Introducing AWS Lambda Powertools for .NET

A guide to the newly released AWS Lambda Powertools for .NET. Learn how this suite of utilities can help you implement serverless best practices for structured logging, custom metrics, and distributed tracing.

Building serverless applications with AWS Lambda is incredibly powerful, but implementing production-ready best practices for observability—logging, metrics, and tracing—can involve a lot of boilerplate code. To solve this problem, AWS created Lambda Powertools, a suite of utilities that makes it easy to adopt these best practices with minimal effort.

While Lambda Powertools has been a popular and invaluable tool for Python developers for some time, in mid-2021, AWS announced the general availability of AWS Lambda Powertools for .NET. This is a game-changer for .NET developers building serverless applications.

The Three Pillars of Observability

Lambda Powertools for .NET focuses on three core areas of observability:

  1. Structured Logging: Writing logs as JSON objects with a consistent structure makes them searchable and analyzable in tools like Amazon CloudWatch Logs Insights.
  2. Custom Metrics: Emitting custom business and operational metrics asynchronously to Amazon CloudWatch Metrics.
  3. Distributed Tracing: Capturing metadata and annotations for your AWS X-Ray traces to make them easier to debug.

Let's look at how Powertools simplifies each of these.

1. Structured Logging with Logger

Without Powertools, you might write logs using Console.WriteLine or the built-in ILogger. This often results in unstructured, plain-text logs that are difficult to query.

The Powertools Logger utility makes it trivial to write structured JSON logs.

How to use it:

Add the AWS.Lambda.Powertools.Logging NuGet package.

// Decorate your Lambda function handler
[Logging(LogEvent = true)]
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
{
    // Log a structured message
    Logger.LogInformation("This is a structured log message.");

    // Add custom keys to the log entry
    Logger.AppendKey("userId", "user-123");
    Logger.LogInformation("Another message with extra context.");

    return new APIGatewayProxyResponse { StatusCode = 200 };
}

This will produce a CloudWatch log entry that looks like this:

{
    "level": "INFO",
    "message": "Another message with extra context.",
    "service": "my-service-name",
    "timestamp": "2021-07-19T10:00:00.000Z",
    "xray_trace_id": "...",
    "userId": "user-123"
}

This JSON format is automatically searchable and includes important context like the service name and trace ID.

2. Custom Metrics with Metrics

CloudWatch Metrics are essential for monitoring the health of your application. The Powertools Metrics utility allows you to capture custom metrics without making synchronous calls to the CloudWatch API, which would add latency to your function.

Instead, it aggregates metrics and emits them to CloudWatch asynchronously using the Embedded Metric Format (EMF).

How to use it:

Add the AWS.Lambda.Powertools.Metrics NuGet package.

[Metrics(CaptureColdStart = true)]
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
{
    // Add a custom metric
    Metrics.AddMetric("SuccessfulBooking", 1, MetricUnit.Count);

    return new APIGatewayProxyResponse { StatusCode = 200 };
}

The [Metrics] attribute handles flushing the metrics at the end of the invocation. The CaptureColdStart property automatically creates a ColdStart metric for you, which is incredibly useful for monitoring performance.

3. Distributed Tracing with Tracing

AWS X-Ray is a great tool for tracing requests as they travel through your distributed application. The Powertools Tracing utility makes it easier to enrich your traces with custom annotations and metadata.

  • Annotations: Key-value pairs that are indexed for searching. You can use them to filter traces (e.g., annotation.userId = 'user-123').
  • Metadata: Key-value pairs that are not indexed but can store additional context.

How to use it:

Add the AWS.Lambda.Powertools.Tracing NuGet package.

[Tracing]
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
{
    // Add an annotation to the trace
    Tracing.AddAnnotation("userId", "user-123");

    // Add metadata to the trace
    Tracing.AddMetadata("orderId", "order-456");

    // This method call will be captured as a subsegment in the trace
    ProcessOrder();

    return new APIGatewayProxyResponse { StatusCode = 200 };
}

[Tracing]
private void ProcessOrder()
{
    // ...
}

Conclusion

AWS Lambda Powertools for .NET is an essential library for any developer building serverless applications with .NET on AWS. It takes the guesswork out of implementing observability best practices, allowing you to write cleaner, more maintainable code while gaining deep insights into your application's behavior. By providing simple, attribute-based utilities for structured logging, custom metrics, and distributed tracing, it lets you focus on your business logic, not on instrumentation boilerplate.