Skip to content

Feature request: Change ordering of default log formatter #1568

Closed
@bilalq

Description

@bilalq

Use case

I know that users can provide their own LogFormatter instance, but the I believe the default should still be reasonably well-suited for most people.

The problem today is that the output frontloads a bunch of noise that isn't useful and makes the CloudWatch console log stream view useless without expanding and hard to read/skim even when you do.

At a glance, all you see is whether or not an invocation was a cold start and the ARN. Actually interesting information like log level and message are buried.

Screenshot 2023-06-29 at 6 58 58 AM

Solution/User Experience

Technically, V8 and every other JS engine I'm aware of don't guarantee ordering of JS object literals when serializing/deserializing. In practice, when the object key counts are not high, the order as written does get preserved.

If we look here:

https://github.com/aws-powertools/powertools-lambda-typescript/blob/main/packages/logger/src/formatter/PowertoolLogFormatter.ts#L19-L33

Changing:

    return {
      cold_start: attributes.lambdaContext?.coldStart,
      function_arn: attributes.lambdaContext?.invokedFunctionArn,
      function_memory_size: attributes.lambdaContext?.memoryLimitInMB,
      function_name: attributes.lambdaContext?.functionName,
      function_request_id: attributes.lambdaContext?.awsRequestId,
      level: attributes.logLevel,
      message: attributes.message,
      sampling_rate: attributes.sampleRateValue,
      service: attributes.serviceName,
      timestamp: this.formatTimestamp(attributes.timestamp),
      xray_trace_id: attributes.xRayTraceId,
    };

To something like this:

    return {
      level: attributes.logLevel,
      message: attributes.message,
      function_request_id: attributes.lambdaContext?.awsRequestId,
      xray_trace_id: attributes.xRayTraceId,
      service: attributes.serviceName,
      function_arn: attributes.lambdaContext?.invokedFunctionArn,
      function_memory_size: attributes.lambdaContext?.memoryLimitInMB,
      function_name: attributes.lambdaContext?.functionName,
      sampling_rate: attributes.sampleRateValue,
      timestamp: this.formatTimestamp(attributes.timestamp),
      cold_start: attributes.lambdaContext?.coldStart,
    };

Would likely be a lot more usable. This brings the log level, message, and execution ids to the forefront.

With regards to backwards compatibility: No promised API or contractual behavior changes. Technically, if a user had regex based parsing of log lines, that may break. However, I'd argue that given the JS engine already doesn't guarantee order preservation, such a dependency never had guarantees to begin with and should not be considered breakage of backwards compatibility.

Alternative solutions

No response

Acknowledgment

Future readers

Please react with 👍 and your use case to help us understand customer demand.

Metadata

Metadata

Assignees

Labels

completedThis item is complete and has been merged/shippedfeature-requestThis item refers to a feature request for an existing or new utilityloggerThis item relates to the Logger Utility

Type

No type

Projects

Status

Shipped

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions