Skip to content

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

Closed
@dreamorosi

Description

@dreamorosi

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.

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