powertools-lambda-typescript icon indicating copy to clipboard operation
powertools-lambda-typescript copied to clipboard

feat(logger): time zone aware timestamp in Logger

Open arnabrahman opened this issue 1 year ago • 1 comments

Summary

This PR introduces a new feature allowing customers to emit timestamps with a timezone-aware format in the Logger. By default, Logger emits logs with timestamps formatted using the UTC timezone, which is the default behavior in AWS Lambda.

Changes

  • When a timezone other than UTC is set, timestamps will be formatted to include the relevant timezone offset. Example: If the emitted timestamp format in UTC is 2016-06-20T12:08:10.000Z and the timezone is set to America/New_York, the timestamp will be formatted as 2016-06-20T08:08:10.000-04:00.

  • The timezone offset is formatted according to the ISO_8601 specification, where the offset can be positive (+) or negative (-) and is followed by HH:MM - see ISO_8601 spec

  • Unit tests have been written for two different timezones to cover both GMT (+) and GMT (-) timezones.

  • While writing the unit tests, I thought if I changed the system timezone by setting the TZ variable, it would work in that timezone. But this is not the case. There are some limitations to jest (https://github.com/jestjs/jest/issues/9856, https://github.com/jestjs/jest/issues/9264). I had to mock the getTimezoneOffset function to make it work. There are some workarounds mentioned about custom environment but I couldn't make those work properly.

  • Updated the docs for the new feature, followed the python powertools docs for inspiration.

  • But now comes the most surprising and confusing part. All the tests were running fine locally, I wanted to try it inside a Lambda function, so I deployed one with my solution. However, during testing, I got some unexpected results. The solution works fine when I set the TZ environment variable for different timezones. But when I don't set the TZ environment variable, things just don't work. My implementation was something like this:

    const defaultTimezone = 'UTC';
     if(configuredTimezone && configuredTimezone !== defaultTimezone)
        // Timezone aware implementation
     else
       // UTC timezone format
    

    In cases where there is no TZ set, the if block was getting executed unexpectedly. I spent some time to figure it out what's wrong with my code but I couldn't.

    Then i found that the actual TZ value that AWS Lambda sets is not UTC, it's actually :UTC. I tried with different runtimes like python/node/ruby but got the same result. This is the most confusing part, I don't know if I am missing something in the doc or not.

    After the revelation, I changed the implementation & it worked fine in the lambda.

    const defaultTimezone = 'UTC';
    if (configuredTimezone && !configuredTimezone.includes(defaultTimezone))
      // Timezone aware implementation
    else
      // UTC timezone format
    

Issue number: #1774


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

arnabrahman avatar Jun 29 '24 13:06 arnabrahman

Hi @arnabrahman, nice to see you again 😃

Thank you so much for opening this PR! I should be able to provide a first review by Monday EOD at the latest.

I want to set aside some time to build the package and test it in a real Lambda function to see how it behaves.

dreamorosi avatar Jun 29 '24 13:06 dreamorosi

I see the doc has been updated.

arnabrahman avatar Jul 02 '24 13:07 arnabrahman