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

Feature request: custom function for unserializable values in Logger (JSON replacer)

Open dreamorosi opened this issue 1 year ago • 1 comments

Use case

Logger emits JSON structured logs, to do so it calls JSON.stringify() under the hood. There are several types of objects that cannot natively be serialized or that when serialized using the default behavior loose information. The Logger utility implements a custom replacer function that allows it to apply custom serialization on objects like Error or BigInt (added in #1117).

Over time, we have received requests for adding custom logic for more types like Map or Set (#1649) and in the fullness of time we expect to receive more as our customers log more and more types of objects.

To avoid bloating the library in an effort to serialize all kinds of types, we should instead enable customers to provide their own custom function that will be used internally by Logger when serializing logs.

In this way, customers who have edge cases can adapt the logger to their needs and all others can continue enjoying a lightweight logger.

Solution/User Experience

The Logger utility should have a new constructor option called jsonReplacerFn that accepts a function that once set, supersedes the default replacer and gives full control over the serialization to the customer.

type CustomReplacerFn = (key: string, value: unknown) => void;

const jsonReplacerFn = (): CustomReplacerFn => ((_key, value) => {
  if (typeof value === 'bigint') {
    return value.toString();
  }

  return value;
});

const logger = new Logger({
  jsonReplacerFn
});

To implement the feature, the implementer should start with adding a new field of type CustomReplacerFn to the ConstructorOptions.

This value should be handled in the Logger.setOptions() method, which should call a new private method called setJsonReplacerFn() (to be implemented).

The new Logger.setJsonReplacerFn() should handle the option passed during initialization, or default to the Logger.getReplacer() method, which could also be renamed to getDefaultJsonReplacerFn().

A reference to the replacer function should be stored in a protected class property called jsonReplacerFn (to be added)) so that it can be used by the Logger.printLog() method and passed down to child loggers in the Logger.createChild() method.

The implementer should also create unit tests to account for the changes, and ideally add a new documentation section using the one found in the Python version of Powertools as reference (maintainers will help with this last step).

Alternative solutions

No response

Acknowledgment

Future readers

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

dreamorosi avatar Oct 31 '23 19:10 dreamorosi

With v2 released, the issue is back on the backlog and ready to pick up.

If anyone from the community is interested in contributing please leave a comment below and feel free to ask any question or clarification.

dreamorosi avatar Mar 11 '24 18:03 dreamorosi

I have opened a PR for this.

arnabrahman avatar Jul 07 '24 10:07 arnabrahman

Thank you for stepping up, @arnabrahman - assigning it to you!

dreamorosi avatar Jul 08 '24 07:07 dreamorosi

⚠️ COMMENT VISIBILITY WARNING ⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.

github-actions[bot] avatar Jul 11 '24 14:07 github-actions[bot]