-
Notifications
You must be signed in to change notification settings - Fork 176
feat(metrics): use async local storage for metrics #4663
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
base: main
Are you sure you want to change the base?
Conversation
b387413
to
bd08c00
Compare
2a9645b
to
bc27232
Compare
62d0f60
to
1c3040a
Compare
1c3040a
to
b73b723
Compare
fdf5b61
to
a0a78f4
Compare
a0a78f4
to
f5cae92
Compare
2214107
to
d3d0801
Compare
0c2cbd2
to
d03a774
Compare
d03a774
to
a3340db
Compare
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.
Very nice work here, I haven't tested it and I won't be able to for a while's but the implementation makes a lot of sense - please if possible run some tests on your machine with the correct setup as we discussed.
Other than that, do you have any idea of whether there's a significant performance impact for this new implementation when used on a Lambda on demand?
"dependencies": { | ||
"@aws-lambda-powertools/commons": "2.27.0" | ||
"@aws-lambda-powertools/commons": "2.27.0", | ||
"@aws/lambda-invoke-store": "0.1.0" |
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.
Since we added this as dependency of the commons
pkg, do we need to declare it here again?
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 that's a good point, we may not. Let me play around with it.
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.
Maybe showing my ignorance of npm workspaces but if it's used in multiple packages across the workspace, should it not be in the root package.json
file rather than commons
or metrics
or whatever?
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.
The main package.json
doesn't get published to npm, only the package ones do. This means it won't be installed when the package gets installed.
In this case, it should be either in both or just in commons
, since metrics
depends on it.
When present in both, if the dependency version is aligned, it gets deduplicated, so only one copy gets installed.
In this case I was suggesting to bypass this risk entirely and just keep it as dependency for commons
, but I don't feel too strongly about it since I don't expect this package to change very often.
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.
Ah yes, I knew I was missing something. Honestly, I'd rather be explicit so you can see what dependencies a package uses when you look at the dependency file so I'd be in favour of keeping it here.
} | ||
|
||
getDimensions(): Dimensions { | ||
return { ...this.#getDimensions() }; |
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.
Why are we spreading and creating a new object here?
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.
Because I don't want it to be possible to get a reference to the underlying object and be able to mutate it without going through the store interface.
Yes, I plan to do some perf testing (vs the original version) in a real lambda function on Monday. |
|
Summary
This PR adds support for using an async context (specifically from the
InvokeStore
package) in the Metrics utility. This allows users to emit metrics that are isolated specifically to the current lambda invocation, isolated from any other executions.Changes
MetricsStore
MetadataStore
DimensionStore
Metrics
class only accesses the data in these stores through this interface and never touches the stored objects directly.InvokeStore
context: if they are then the metrics are stored in the current async context, otherwise we fallback to a plain instance wide object as per the current implementation.Metrics
class, e.g.,setMetric
will check if the metric already exists and handle converting values into an array if the metric is already there. Likewise with setting timestamps.Metrics
class as a whole.Issue number: closes #4662
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.