-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(logger): logger throws TypeError when log item has BigInt value #1201
fix(logger): logger throws TypeError when log item has BigInt value #1201
Conversation
public removeEmptyKeys(attributes: LogAttributes): LogAttributes { | ||
return pickBy(attributes, (value) => value !== undefined && value !== '' && value !== null); | ||
const newAttributes: LogAttributes = {}; | ||
for (const key in attributes) { | ||
if (attributes[key] !== undefined && attributes[key] !== '' && attributes[key] !== null) { | ||
newAttributes[key] = attributes[key]; | ||
} | ||
} | ||
|
||
return newAttributes; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Firstly, I wrote a declarative one-liner:
public removeEmptyKeys(attributes: LogAttributes): LogAttributes {
return Object.fromEntries(Object.entries(attributes).filter(([, value]) => value !== undefined && value !== '' && value !== null));
}
But for the sake of readability, I stick to the verbose version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if nested objects could be in the logItem
, but it wasn't and isn't supported by this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you give an example of what do you mean by nested objects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logger.info("my message", { value: 42, nested: { value: "nested value", emptyValue: '', undefinedValue: undefined, nullValue: null } });
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to support nested objects though.
Here's an example of logs emitted by Logger v1.5.0
(latest):
from this code:
import { Logger, injectLambdaContext } from "@aws-lambda-powertools/logger";
import middy from "@middy/core";
const logger = new Logger({});
export const handler = middy(async () => {
logger.info("my message", {
value: 42,
nested: {
value: "nested value",
emptyValue: "",
undefinedValue: undefined,
nullValue: null,
},
});
}).use(injectLambdaContext(logger, { logEvent: true }));
this was the event payload passed:
{
"key1": "value1",
"key2": "value2",
"key3": "value3",
"nested": {
"some": "key",
"other": 1
}
}
We need to support nested objects both for the logEvent
functionality (also present in the unit tests) and arbitrary objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh after re-reading I realize I might have misunderstood your comment.
Were you referring to supporting the removal of
undefined
,null
, etc. from nested objects?
yes, it's just go through the first level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, apologies for the misunderstanding!
I think that at the moment we should strive for maintaining the same exact functionality level as the current version without breaking changes. Which based on the test I did above, seems to at least remove undefined
values.
Then later on, if there's demand we can explore extending the behavior to empty strings and/or null
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
undefined
values are filtered somewhere else 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great then!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I definitely support/agree with the choice of using a more verbose version for the sake of readability.
I see that there's no This should make the necessary updates to the lock file as well as removing it from the Could you please also remove |
Also, I see that the branch you're working on is behind Normally this would be fine, but in this case I would strongly advise to rebase/bring it in line with The reason why I say this is that as part of the migration to Node 18 we have updated all the dependencies and added the runtime to the unit & integration tests. For the integration tests to pass we need the CDK version that is currently present on |
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#exceptions | ||
* @private | ||
*/ | ||
private getReplacer(): (key: string, value: LogAttributes | Error | bigint) => void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the new name, thanks for making the change
Thank you for syncing the branch & updating the dependencies & lock file. I can confirm that the integration tests are passing: https://github.com/awslabs/aws-lambda-powertools-typescript/actions/runs/3794471678 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @shdq for picking this up and for the quick PR.
I appreciate the choices made throughout.
public removeEmptyKeys(attributes: LogAttributes): LogAttributes { | ||
return pickBy(attributes, (value) => value !== undefined && value !== '' && value !== null); | ||
const newAttributes: LogAttributes = {}; | ||
for (const key in attributes) { | ||
if (attributes[key] !== undefined && attributes[key] !== '' && attributes[key] !== null) { | ||
newAttributes[key] = attributes[key]; | ||
} | ||
} | ||
|
||
return newAttributes; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I definitely support/agree with the choice of using a more verbose version for the sake of readability.
I'm happy to help! Thanks for the fast feedback loop @dreamorosi! |
📊 Package size report 0.2%↑
🤖 This report was automatically generated by pkg-size-action |
Description of your changes
The replacer function used for
JSON.stringify
convertsBigInt
values to strings.Added tests and removed external dependency for
removeEmptyKeys()
function.How to verify this change
Related issues, RFCs
Issue number: #1117
PR status
Is this ready for review?: YES
Is it a breaking change?: NO
Checklist
Breaking change checklist
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.