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.
If you're new to Amazon CloudWatch, there are two terminologies you must be aware of before using this utility:
Namespace. It's the highest level container that will group multiple metrics from multiple services for a given application, for example ServerlessEcommerce.
Dimensions. Metrics metadata in key-value format. They help you slice and dice metrics visualization, for example ColdStart metric by Payment service.
Metric. It's the name of the metric, for example: SuccessfulBooking or UpdatedBooking.
Unit. It's a value representing the unit of measure for the corresponding metric, for example: Count or Seconds.
Resolution. It's a value representing the storage resolution for the corresponding metric. Metrics can be either Standard or High resolution. Read more here.
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 three 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
Decorator parameter
Metric namespace
Logical container where all metrics will be placed e.g. MyCompanyEcommerce
POWERTOOLS_METRICS_NAMESPACE
Namespace
Service
Optionally, sets Service metric dimension across all metrics e.g. payment
POWERTOOLS_SERVICE_NAME
Service
Disable Powertools Metrics
Optionally, disables all Powertools metrics
POWERTOOLS_METRICS_DISABLED
N/A
Info
POWERTOOLS_METRICS_DISABLED will not disable default metrics created by AWS services.
Autocomplete Metric Units
All parameters in Metrics Attribute are optional. Following rules apply:
Namespace: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:service_undefined by default. You can either specify it in code or environment variable.
You can create metrics using AddMetric, and you can create dimensions for all your aggregate metrics using AddDimension method.
1 2 3 4 5 6 7 8 910
usingAWS.Lambda.Powertools.Metrics;publicclassFunction{[Metrics(Namespace = "ExampleApplication", Service = "Booking")]publicasyncTask<APIGatewayProxyResponse>FunctionHandler(APIGatewayProxyRequestapigProxyEvent,ILambdaContextcontext){Metrics.AddMetric("SuccessfulBooking",1,MetricUnit.Count);}}
1 2 3 4 5 6 7 8 91011
usingAWS.Lambda.Powertools.Metrics;publicclassFunction{[Metrics(Namespace = "ExampleApplication", Service = "Booking")]publicasyncTask<APIGatewayProxyResponse>FunctionHandler(APIGatewayProxyRequestapigProxyEvent,ILambdaContextcontext){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.
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.
1 2 3 4 5 6 7 8 91011121314151617
usingAWS.Lambda.Powertools.Metrics;publicclassFunction{[Metrics(Namespace = "ExampleApplication", Service = "Booking")]publicasyncTask<APIGatewayProxyResponse>FunctionHandler(APIGatewayProxyRequestapigProxyEvent,ILambdaContextcontext){// Publish a metric with standard resolution i.e. StorageResolution = 60Metrics.AddMetric("SuccessfulBooking",1,MetricUnit.Count,MetricResolution.Standard);// Publish a metric with high resolution i.e. StorageResolution = 1Metrics.AddMetric("FailedBooking",1,MetricUnit.Count,MetricResolution.High);// The last parameter (storage resolution) is optionalMetrics.AddMetric("SuccessfulUpgrade",1,MetricUnit.Count);}}
Autocomplete Metric Resolutions
Use the MetricResolution enum to easily find a supported metric resolution by CloudWatch.
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.
You can also flush metrics manually by calling Flush method.
During metrics validation, if no metrics are provided then a warning will be logged, but no exception will be raised.
1 2 3 4 5 6 7 8 91011
usingAWS.Lambda.Powertools.Metrics;publicclassFunction{[Metrics(Namespace = "ExampleApplication", Service = "Booking")]publicasyncTask<APIGatewayProxyResponse>FunctionHandler(APIGatewayProxyRequestapigProxyEvent,ILambdaContextcontext){Metrics.AddMetric("SuccessfulBooking",1,MetricUnit.Count);Metrics.Flush();}}
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
1 2 3 4 5 6 7 8 910
usingAWS.Lambda.Powertools.Metrics;publicclassFunction{[Metrics(Namespace = ExampleApplication, Service = "Booking")]publicasyncTask<APIGatewayProxyResponse>FunctionHandler(APIGatewayProxyRequestapigProxyEvent,ILambdaContextcontext){Metrics.AddMetric("SuccessfulBooking",1,MetricUnit.Count);Metrics.AddMetadata("BookingId","683EEB2D-B2F3-4075-96EE-788E6E2EED45");...
usingAWS.Lambda.Powertools.Metrics;publicclassFunction{[Metrics(Namespace = ExampleApplication, Service = "Booking")]publicasyncTask<APIGatewayProxyResponse>FunctionHandler(APIGatewayProxyRequestapigProxyEvent,ILambdaContextcontext){Metrics.PushSingleMetric(name:"ColdStart",value:1,unit:MetricUnit.Count,nameSpace:"ExampleApplication",service:"Booking");...
By default it will skip all previously defined dimensions including default dimensions. Use dimensions argument if you want to reuse default dimensions or specify custom dimensions from a dictionary.
Metrics.DefaultDimensions: Reuse default dimensions when using static Metrics
Options.DefaultDimensions: Reuse default dimensions when using Builder or Configure patterns
1 2 3 4 5 6 7 8 9101112131415161718
usingAWS.Lambda.Powertools.Metrics;publicclassFunction{[Metrics(Namespace = ExampleApplication, Service = "Booking")]publicasyncTask<APIGatewayProxyResponse>FunctionHandler(APIGatewayProxyRequestapigProxyEvent,ILambdaContextcontext){Metrics.PushSingleMetric(name:"ColdStart",value:1,unit:MetricUnit.Count,nameSpace:"ExampleApplication",service:"Booking",dimensions:newDictionary<string,string>{{"FunctionContext","$LATEST"}});...
1 2 3 4 5 6 7 8 910111213
usingAWS.Lambda.Powertools.Metrics;publicclassFunction{[Metrics(Namespace = ExampleApplication, Service = "Booking")]publicasyncTask<APIGatewayProxyResponse>FunctionHandler(APIGatewayProxyRequestapigProxyEvent,ILambdaContextcontext){Metrics.SetDefaultDimensions(newDictionary<string,string>{{"Default","SingleMetric"}});Metrics.PushSingleMetric("SingleMetric",1,MetricUnit.Count,dimensions:Metrics.DefaultDimensions);...
The UseMetrics middleware is an extension method for the IApplicationBuilder interface.
It adds a metrics middleware to the specified application builder, which captures cold start metrics (if enabled) and flushes metrics on function exit.
usingAWS.Lambda.Powertools.Metrics.AspNetCore.Http;varbuilder=WebApplication.CreateBuilder(args);// Configure metricsbuilder.Services.AddSingleton<IMetrics>(_=>newMetricsBuilder().WithNamespace("MyApi")// Namespace for the metrics.WithService("WeatherService")// Service name for the metrics.WithCaptureColdStart(true)// Capture cold start metrics.WithDefaultDimensions(newDictionary<string,string>// Default dimensions for the metrics{{"Environment","Prod"},{"Another","One"}}).Build());// Build the metricsbuilder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);varapp=builder.Build();app.UseMetrics();// Add the metrics middlewareapp.MapGet("/powertools",(IMetricsmetrics)=>{// add custom metricsmetrics.AddMetric("MyCustomMetric",1,MetricUnit.Count);// flush metrics - this is required to ensure metrics are sent to CloudWatchmetrics.Flush();});app.Run();
Here is the highlighted UseMetrics method:
1 2 3 4 5 6 7 8 91011
/// <summary>/// Adds a metrics middleware to the specified application builder./// This will capture cold start (if CaptureColdStart is enabled) metrics and flush metrics on function exit./// </summary>/// <param name="app">The application builder to add the metrics middleware to.</param>/// <returns>The application builder with the metrics middleware added.</returns>publicstaticIApplicationBuilderUseMetrics(thisIApplicationBuilderapp){app.UseMiddleware<MetricsMiddleware>();returnapp;}
Explanation:
The method is defined as an extension method for the IApplicationBuilder interface.
It adds a MetricsMiddleware to the application builder using the UseMiddleware method.
The MetricsMiddleware captures and records metrics for HTTP requests, including cold start metrics if the CaptureColdStart option is enabled.
usingAWS.Lambda.Powertools.Metrics;usingAWS.Lambda.Powertools.Metrics.AspNetCore.Http;varbuilder=WebApplication.CreateBuilder(args);// Configure metricsbuilder.Services.AddSingleton<IMetrics>(_=>newMetricsBuilder().WithNamespace("MyApi")// Namespace for the metrics.WithService("WeatherService")// Service name for the metrics.WithCaptureColdStart(true)// Capture cold start metrics.WithDefaultDimensions(newDictionary<string,string>// Default dimensions for the metrics{{"Environment","Prod"},{"Another","One"}}).Build());// Build the metrics// Add AWS Lambda support. When the application is run in Lambda, Kestrel is swapped out as the web server with Amazon.Lambda.AspNetCoreServer. This// package will act as the web server translating requests and responses between the Lambda event source and ASP.NET Core.builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);varapp=builder.Build();app.MapGet("/powertools",(IMetricsmetrics)=>{// add custom metricsmetrics.AddMetric("MyCustomMetric",1,MetricUnit.Count);// flush metrics - this is required to ensure metrics are sent to CloudWatchmetrics.Flush();}).WithMetrics();app.Run();
Here is the highlighted WithMetrics method:
1 2 3 4 5 6 7 8 91011
/// <summary>/// Adds a metrics filter to the specified route handler builder./// This will capture cold start (if CaptureColdStart is enabled) metrics and flush metrics on function exit./// </summary>/// <param name="builder">The route handler builder to add the metrics filter to.</param>/// <returns>The route handler builder with the metrics filter added.</returns>publicstaticRouteHandlerBuilderWithMetrics(thisRouteHandlerBuilderbuilder){builder.AddEndpointFilter<MetricsFilter>();returnbuilder;}
Explanation:
The method is defined as an extension method for the RouteHandlerBuilder class.
It adds a MetricsFilter to the route handler builder using the AddEndpointFilter method.
The MetricsFilter captures and records metrics for HTTP endpoints, including cold start metrics if the CaptureColdStart option is enabled.
The method returns the modified RouteHandlerBuilder instance with the metrics filter added.
usingSystem.Collections.Generic;usingAmazon.Lambda.Core;publicclassMetricsnBuilderHandler{privatereadonlyIMetrics_metrics;// Allow injection of IMetrics for testingpublicMetricsnBuilderHandler(IMetricsmetrics=null){_metrics=metrics??newMetricsBuilder().WithCaptureColdStart(true).WithService("testService").WithNamespace("dotnet-powertools-test").WithDefaultDimensions(newDictionary<string,string>{{"Environment","Prod1"},{"Another","One"}}).Build();}[Metrics]publicvoidHandler(ILambdaContextcontext){_metrics.AddMetric("SuccessfulBooking",1,MetricUnit.Count);}}
You are explicitly setting namespace/default dimension via namespace and service parameters
You're not instantiating Metrics in the global namespace
For 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.