powertools-lambda-typescript
powertools-lambda-typescript copied to clipboard
Feature request: custom function for unserializable values in Logger (JSON replacer)
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
- [X] This feature request meets Powertools for AWS Lambda (TypeScript) Tenets
- [ ] Should this be considered in other Powertools for AWS Lambda languages? i.e. Python, Java, and .NET
Future readers
Please react with 👍 and your use case to help us understand customer demand.
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.
I have opened a PR for this.
Thank you for stepping up, @arnabrahman - assigning it to you!
⚠️ 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.