Warning
Version 1.x.x will continue to be supported until end of October 2025 for bug fixes and security updates, but no new features will be added to this version. We recommend you upgrade to the latest version.
The latest version is available at Metrics v2.
Metrics creates custom metrics asynchronously by logging metrics to standard output following Amazon CloudWatch Embedded Metric Format (EMF).
These metrics can be visualized through Amazon CloudWatch Console.
Key features¶Powertools for AWS Lambda (.NET) are available as NuGet packages. You can install the packages from NuGet Gallery or from Visual Studio editor by searching AWS.Lambda.Powertools*
to see various utilities available.
AWS.Lambda.Powertools.Metrics:
dotnet add package AWS.Lambda.Powertools.Metrics -v 1.7.1
If you're new to Amazon CloudWatch, there are two terminologies you must be aware of before using this utility:
ServerlessEcommerce
.ColdStart
metric by Payment service
.Visit the AWS documentation for a complete explanation for Amazon CloudWatch concepts.
Metric terminology, visually explained Getting started¶Metrics
is implemented as a Singleton to keep track of your aggregate metrics in memory and make them accessible anywhere in your code. To guarantee that metrics are flushed properly the MetricsAttribute
must be added on the lambda handler.
Metrics has two global settings that will be used across all metrics emitted. Use your application or main service as the metric namespace to easily group all metrics:
Setting Description Environment variable Constructor parameter Service Optionally, sets service metric dimension across all metrics e.g.payment
POWERTOOLS_SERVICE_NAME
Service
Metric namespace Logical container where all metrics will be placed e.g. MyCompanyEcommerce
POWERTOOLS_METRICS_NAMESPACE
Namespace
Autocomplete Metric Units
All parameters in Metrics Attribute
are optional. Following rules apply:
Empty
string by default. You can either specify it in code or environment variable. If not present before flushing metrics, a SchemaValidationException
will be thrown.service_undefined
by default. You can either specify it in code or environment variable.false
by default.false
by default.template.ymlFunction.cs
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
...
Environment:
Variables:
POWERTOOLS_SERVICE_NAME: ShoppingCartService
POWERTOOLS_METRICS_NAMESPACE: MyCompanyEcommerce
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(Namespace = "MyCompanyEcommerce", Service = "ShoppingCartService", CaptureColdStart = true, RaiseOnEmptyMetrics = true)]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
...
}
}
Full list of environment variables¶ Environment variable Description Default POWERTOOLS_SERVICE_NAME Sets service name used for tracing namespace, metrics dimension and structured logging "service_undefined"
POWERTOOLS_METRICS_NAMESPACE Sets namespace used for metrics None
Creating metrics¶
You can create metrics using AddMetric
, and you can create dimensions for all your aggregate metrics using AddDimension
method.
MetricsMetrics with custom dimensions
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(Namespace = "ExampleApplication", Service = "Booking")]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
Metrics.AddMetric("SuccessfulBooking", 1, MetricUnit.Count);
}
}
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(Namespace = "ExampleApplication", Service = "Booking")]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
Metrics.AddDimension("Environment","Prod");
Metrics.AddMetric("SuccessfulBooking", 1, MetricUnit.Count);
}
}
Autocomplete Metric Units
MetricUnit
enum facilitates finding a supported metric unit by CloudWatch.
Metrics overflow
CloudWatch EMF supports a max of 100 metrics per batch. Metrics utility will flush all metrics when adding the 100th metric. Subsequent metrics, e.g. 101th, will be aggregated into a new EMF object, for your convenience.
Metric value must be a positive number
Metric values must be a positive number otherwise an ArgumentException
will be thrown.
Do not create metrics or dimensions outside the handler
Metrics or dimensions added in the global scope will only be added during cold start. Disregard if that's the intended behavior.
Adding high-resolution metrics¶You can create high-resolution metrics passing MetricResolution
as parameter to AddMetric
.
When is it useful?
High-resolution metrics are data with a granularity of one second and are very useful in several situations such as telemetry, time series, real-time incident management, and others.
Metrics with high resolution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(Namespace = "ExampleApplication", Service = "Booking")]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
// Publish a metric with standard resolution i.e. StorageResolution = 60
Metrics.AddMetric("SuccessfulBooking", 1, MetricUnit.Count, MetricResolution.Standard);
// Publish a metric with high resolution i.e. StorageResolution = 1
Metrics.AddMetric("FailedBooking", 1, MetricUnit.Count, MetricResolution.High);
// The last parameter (storage resolution) is optional
Metrics.AddMetric("SuccessfulUpgrade", 1, MetricUnit.Count);
}
}
Autocomplete Metric Resolutions
Use the MetricResolution
enum to easily find a supported metric resolution by CloudWatch.
You can use SetDefaultDimensions
method to persist dimensions across Lambda invocations.
SetDefaultDimensions method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
using AWS.Lambda.Powertools.Metrics;
public class Function {
private Dictionary<string, string> _defaultDimensions = new Dictionary<string, string>{
{"Environment", "Prod"},
{"Another", "One"}
};
[Metrics(Namespace = "ExampleApplication", Service = "Booking")]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
Metrics.SetDefaultDimensions(_defaultDimensions);
Metrics.AddMetric("SuccessfulBooking", 1, MetricUnit.Count);
}
}
Flushing metrics¶
With MetricsAttribute
all your metrics are validated, serialized and flushed to standard output when lambda handler completes execution or when you had the 100th metric to memory.
During metrics validation, if no metrics are provided then a warning will be logged, but no exception will be raised.
Function.csExample CloudWatch Logs excerpt
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(Namespace = "ExampleApplication", Service = "Booking")]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
Metrics.AddMetric("SuccessfulBooking", 1, MetricUnit.Count);
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
{
"BookingConfirmation": 1.0,
"_aws": {
"Timestamp": 1592234975665,
"CloudWatchMetrics": [
{
"Namespace": "ExampleApplication",
"Dimensions": [
[
"service"
]
],
"Metrics": [
{
"Name": "BookingConfirmation",
"Unit": "Count"
}
]
}
]
},
"service": "ExampleService"
}
Metric validation
If metrics are provided, and any of the following criteria are not met, SchemaValidationException
will be raised:
We do not emit 0 as a value for ColdStart metric for cost reasons. Let us know if you'd prefer a flag to override it
Raising SchemaValidationException on empty metrics¶If you want to ensure that at least one metric is emitted, you can pass RaiseOnEmptyMetrics
to the Metrics attribute:
Function.cs
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(RaiseOnEmptyMetrics = true)]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
...
Capturing cold start metric¶
You can optionally capture cold start metrics by setting CaptureColdStart
parameter to true
.
Function.cs
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(CaptureColdStart = true)]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
...
If it's a cold start invocation, this feature will:
ColdStart
function_name
and service
dimensionsThis has the advantage of keeping cold start metric separate from your application metrics, where you might have unrelated dimensions.
Advanced¶ Adding metadata¶You can add high-cardinality data as part of your Metrics log with AddMetadata
method. This is useful when you want to search highly contextual information along with your metrics in your logs.
Info
This will not be available during metrics visualization - Use dimensions for this purpose
Info
Adding metadata with a key that is the same as an existing metric will be ignored
Function.csExample CloudWatch Logs excerpt
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(Namespace = ExampleApplication, Service = "Booking")]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
Metrics.AddMetric("SuccessfulBooking", 1, MetricUnit.Count);
Metrics.AddMetadata("BookingId", "683EEB2D-B2F3-4075-96EE-788E6E2EED45");
...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
{
"SuccessfulBooking": 1.0,
"_aws": {
"Timestamp": 1592234975665,
"CloudWatchMetrics": [
{
"Namespace": "ExampleApplication",
"Dimensions": [
[
"service"
]
],
"Metrics": [
{
"Name": "SuccessfulBooking",
"Unit": "Count"
}
]
}
]
},
"Service": "Booking",
"BookingId": "683EEB2D-B2F3-4075-96EE-788E6E2EED45"
}
Single metric with a different dimension¶
CloudWatch EMF uses the same dimensions across all your metrics. Use PushSingleMetric
if you have a metric that should have different dimensions.
Info
Generally, this would be an edge case since you pay for unique metric. Keep the following formula in mind:
unique metric = (metric_name + dimension_name + dimension_value)
Function.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
using AWS.Lambda.Powertools.Metrics;
public class Function {
[Metrics(Namespace = ExampleApplication, Service = "Booking")]
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
Metrics.PushSingleMetric(
metricName: "ColdStart",
value: 1,
unit: MetricUnit.Count,
nameSpace: "ExampleApplication",
service: "Booking",
defaultDimensions: new Dictionary<string, string>
{
{"FunctionContext", "$LATEST"}
});
...
Testing your code¶ Environment variables¶ Tip
Ignore this section, if:
namespace
and service
parametersMetrics
in the global namespaceFor example, Metrics(namespace="ExampleApplication", service="booking")
Make sure to set POWERTOOLS_METRICS_NAMESPACE
and POWERTOOLS_SERVICE_NAME
before running your tests to prevent failing on SchemaValidation
exception. You can set it before you run tests by adding the environment variable.
1
Environment.SetEnvironmentVariable("POWERTOOLS_METRICS_NAMESPACE","AWSLambdaPowertools");
2025-05-06
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4