You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature request: Reuse namespace in Metrics.flushSingleMetric and other limitations #2153
As a user of Powertools v1, and considering moving to v2, I found the withMetricsLogger now replaced with flushSingleMetric. I see 2 issues
The current overloads, requires setting namespace, even though previously I've been relying on the namespace being whatever was already set (e.g. via powertools environment variables). I find this a degradation in UX if - which I think is a typical use case - I wanna use the same namespace
I also had use cases for withMetricsLogger where I add multiple metrics, which share an overriden dimensionset. Now this needs to be replaced with multiple calls to flushSingleMetric
I think the refactor/abstractions led to some degradations when it comes to withMetricsLogger. Moreover, LambdaMetricsAspect do set a few other properties/metadata that no longer seem to be available in instances emitted by flushSingleMetric such as trace and function id.
Solution/User Experience
For 1, one solution would be to add flushSingleMetric overloads that don't take a namespace, and to update EmfMetricsLogger to treat the namespace parameter as nullable and a potential override to its this.namespace
For 2, maybe Metrics should get a new method flushMetrics with takes a Consumer<Metrics>, then one is more free about using default dimensions/namespace, or overriding them and adding multiple metrics.
Hey @humanzz thanks for opening this issue and explaining more about the Developer Experience you expect from Powertools.
Use case
As a user of Powertools v1, and considering moving to v2, I found the withMetricsLogger now replaced with flushSingleMetric. I see 2 issues
The current overloads, requires setting namespace, even though previously I've been relying on the namespace being whatever was already set (e.g. via powertools environment variables). I find this a degradation in UX if - which I think is a typical use case - I wanna use the same namespace
Actually I think Java V2 aligns with the API for SingleMetrics in other runtimes, like Python and TypeScript. The mental model for a single metric is to have everything specific to that metric, like dimensions, values, and namespace. I'm open to discussing this and seeing if we can adapt this behavior or if we need to improve our documentation. Can you explain a bit more about using SingleMetrics with the same namespace? Shouldn't this be a use case for regular metric instances?
I also had use cases for withMetricsLogger where I add multiple metrics, which share an overriden dimensionset. Now this needs to be replaced with multiple calls to flushSingleMetric>
I think the refactor/abstractions led to some degradations when it comes to withMetricsLogger. Moreover, LambdaMetricsAspect do set a few other properties/metadata that no longer seem to be available in instances emitted by flushSingleMetric such as trace and function id.
For 1, one solution would be to add flushSingleMetric overloads that don't take a namespace, and to update EmfMetricsLogger to treat the namespace parameter as nullable and a potential override to its this.namespace
For 2, maybe Metrics should get a new method flushMetrics with takes a Consumer<Metrics>, then one is more free about using default dimensions/namespace, or overriding them and adding multiple metrics.
Thanks for suggesting a better experience, but I think we have something to discuss before we decide which way to go.
Can you explain a bit more about using SingleMetrics with the same namespace? Shouldn't this be a use case for regular metric instances?
I would love to learn about such a use-case and how you solve it in v1 at the moment.
I also had use cases for withMetricsLogger where I add multiple metrics, which share an overriden dimensionset. Now this needs to be replaced with multiple calls to flushSingleMetric
This is a good call and indeed not possible anymore in v2. I see Python has
When I implementing flushSingleMetric I was following the fact that emission of such single metrics should be single indeed – but I recognize there is a use-case for flushing multiple metrics with a different configuration in one go instead of calling flush every single time (e.g. in a for-loop). Inline with Java v2 naming conventions using the flush* syntax, I can image to introduce a new method such as this to support the use-case of flushing multiple custom metrics with a single call to flush:
/** * Execute custom metrics collection with a fresh metrics instance. * The provided function receives a new Metrics instance that can be configured * independently (namespace, dimensions, etc.) and used to collect multiple metrics. * All metrics are automatically flushed after the function execution. * * @param metricsFunction function that receives a fresh Metrics instance for custom metric collection */voidflushCustomMetrics(java.util.function.Consumer<Metrics> metricsFunction);
The user-experience will look similar to this where metrics is the regular Metrics Singleton returned from the MetricsFactory:
metrics.flushCustomMetrics(customMetrics -> {
customMetrics.setNamespace("MyCustomNamespace");
customMetrics.addDimension("Environment", "Production");
customMetrics.addMetric("CustomMetric1", 42.0, MetricUnit.COUNT);
customMetrics.addMetric("CustomMetric2", 3.14, MetricUnit.SECONDS);
// No need to call flush() - it's done automatically
});
set a few other properties/metadata that no longer seem to be available in instances emitted by flushSingleMetric such as trace and function id
In Python, we don't define anything related to Tracerid, FunctionID, or any other Lambda function metadata when using metrics. In Metrics, we only add namespace, name, value, and dimensions that customer explicitly set it. I think PT Java v1 at some point had metrics published with function metadata, but I could be wrong.
Yes, I believe it was published with function metadata in v1 due to exposing the interface of the Java EMF library directly. However, we still set the trace id for example in LambdaMetricsAspect for all regular metrics and the function name for the cold start metric.
Thanks for sending this PR @humanzz, I left some feedback there. I think we should add the flushMetrics function that you suggested and also incorporating the metrics metadata again (trace id) like you suggested.
The key decision that we need to make in this issue before finalizing the implementation is:
Do we want to inherit the namespace, default dimensions, metadata from the existing metrics logger if flushMetrics() or flushSingleMetric is used?
In v1 of the metrics utility we indeed copied over the existing metrics logger's configuration (see this code).
@aws-powertools/lambda-dotnet-core, @aws-powertools/lambda-python-core, @aws-powertools/lambda-typescript-core Any opinions? I think Java was a special case here in v1.
So, over time, in many of lambda function handlers I work on, I came into the pattern of (as a user of v1 powertools)
in the handler, set some properties/metadata into both logging context/metrics metadata to ensure these are present across all log lines/metrics
in non-handler code, when emitting custom metrics, using MetricsUtils.withMetricsLogger, it's always intended to be within the same namespace - that I set via the environment variable - but the main difference that tends to happen is that I want to emit those metrics under different dimensions
This way, I'm emitting all metrics within the same namespace, and using the same metadata (already configured in the handler), and my business logic does not need to concern itself with figuring out namespace/metadata
The utility of shared metadata, is that like function request id, trace id, these metadata help with correlating different metrics/log lines if I want to inspect metrics/log lines for similar metadata
From a product standpoint, we should prioritize feature parity & have similar behaviors across runtimes, except for when there's a language specific or more idiomatic pattern that warrants diverging from it.
With that said, if we think a certain pattern we had in v1 of this version is prevalent enough and valid, then we should consider adding it to all runtimes.
Personally, I like the proposal by @humanzz and this is how it was in v1 of Java Metrics as well. In our documentation we advertise the usage of single metrics as a way of emitting metrics with different dimensions:
Use single_metric if you have a metric that should have different dimensions
(Python)
Use singleMetric if you have a metric that should have different dimensions.
(TypeScript)
Therefore, I think we should copy all configuration from the existing metrics logger to the single metrics logger except for the dimensions. If the user wants to change more than just dimensions they can still do so by using the set methods on the metrics logger.
Right now, I see some inconsistent implementation and interface across the runtimes. This means, no matter what we decide, a breaking change is needed in at least one runtime to be consistent with the others.
Activity
leandrodamascena commentedon Sep 29, 2025
Hey @humanzz thanks for opening this issue and explaining more about the Developer Experience you expect from Powertools.
Actually I think Java V2 aligns with the API for SingleMetrics in other runtimes, like Python and TypeScript. The mental model for a single metric is to have everything specific to that metric, like dimensions, values, and namespace. I'm open to discussing this and seeing if we can adapt this behavior or if we need to improve our documentation. Can you explain a bit more about using SingleMetrics with the same namespace? Shouldn't this be a use case for regular metric instances?
Can you give us your opinion here, @phipag?
Thanks for suggesting a better experience, but I think we have something to discuss before we decide which way to go.
phipag commentedon Sep 29, 2025
I would love to learn about such a use-case and how you solve it in v1 at the moment.
This is a good call and indeed not possible anymore in v2. I see Python has
When I implementing
flushSingleMetricI was following the fact that emission of such single metrics should be single indeed – but I recognize there is a use-case for flushing multiple metrics with a different configuration in one go instead of calling flush every single time (e.g. in a for-loop). Inline with Java v2 naming conventions using theflush*syntax, I can image to introduce a new method such as this to support the use-case of flushing multiple custom metrics with a single call to flush:The user-experience will look similar to this where
metricsis the regularMetricsSingleton returned from theMetricsFactory:Was this available in Java v1 (@humanzz?). How do you solve this in Python (@leandrodamascena?).
leandrodamascena commentedon Sep 29, 2025
In Python, we don't define anything related to Tracerid, FunctionID, or any other Lambda function metadata when using metrics. In Metrics, we only add namespace, name, value, and dimensions that customer explicitly set it. I think PT Java v1 at some point had metrics published with function metadata, but I could be wrong.
phipag commentedon Sep 29, 2025
Yes, I believe it was published with function metadata in v1 due to exposing the interface of the Java EMF library directly. However, we still set the trace id for example in
LambdaMetricsAspectfor all regular metrics and the function name for the cold start metric.1 remaining item
phipag commentedon Sep 30, 2025
Thanks for sending this PR @humanzz, I left some feedback there. I think we should add the
flushMetricsfunction that you suggested and also incorporating the metrics metadata again (trace id) like you suggested.The key decision that we need to make in this issue before finalizing the implementation is:
flushMetrics()orflushSingleMetricis used?In v1 of the metrics utility we indeed copied over the existing metrics logger's configuration (see this code).
@aws-powertools/lambda-dotnet-core, @aws-powertools/lambda-python-core, @aws-powertools/lambda-typescript-core Any opinions? I think Java was a special case here in v1.
humanzz commentedon Sep 30, 2025
So, over time, in many of lambda function handlers I work on, I came into the pattern of (as a user of v1 powertools)
MetricsUtils.withMetricsLogger, it's always intended to be within the same namespace - that I set via the environment variable - but the main difference that tends to happen is that I want to emit those metrics under different dimensionsdreamorosi commentedon Sep 30, 2025
From a product standpoint, we should prioritize feature parity & have similar behaviors across runtimes, except for when there's a language specific or more idiomatic pattern that warrants diverging from it.
With that said, if we think a certain pattern we had in v1 of this version is prevalent enough and valid, then we should consider adding it to all runtimes.
phipag commentedon Sep 30, 2025
Personally, I like the proposal by @humanzz and this is how it was in v1 of Java Metrics as well. In our documentation we advertise the usage of single metrics as a way of emitting metrics with different dimensions:
(Python)
(TypeScript)
Therefore, I think we should copy all configuration from the existing metrics logger to the single metrics logger except for the dimensions. If the user wants to change more than just dimensions they can still do so by using the set methods on the metrics logger.
Right now, I see some inconsistent implementation and interface across the runtimes. This means, no matter what we decide, a breaking change is needed in at least one runtime to be consistent with the others.
TypeScript
Python
Suggestion for Java
dreamorosi commentedon Oct 1, 2025
Ok, if you think it makes sense no objections from my side.
phipag commentedon Oct 2, 2025
Merged PR #2154