AWS Distro for OpenTelemetry
Manual Instrumentation for Traces and Metrics with the AWS Distro for OpenTelemetry .NET SDK
Manual Instrumentation for Traces and Metrics with the AWS Distro for OpenTelemetry .NET SDK
The AWS Distro for OpenTelemetry .NET SDK contains an extension library for instrumenting the AWS SDK. In this tutorial, we will introduce how to manually instrument your application for traces and metrics step-by-step using AWS Distro for OpenTelemetry .NET SDK.
Requirements
The AWS Distro for OpenTelemetry .NET SDK is compatible for all the officially supported versions of .NET and .NET Framework.
Note: You’ll also need to have the AWS Distro for OpenTelemetry Collector running to export traces and metrics.
Installation
In order to instrument your .NET application for traces and metrics, start by downloading the OpenTelemetry
nuget package to your application.
dotnet add package OpenTelemetry
The OpenTelemetry SDK for .NET deals with concerns such as sampling, a processing pipeline, and exporting telemetry to a particular backend. This generally requires additional packages to be downloaded for specific instrumentation or exporter.
The OpenTelemetry SDK generates traces with W3C random ID which X-Ray backend doesn’t currently support.
You need to install the OpenTelemetry.Contrib.Extensions.AWSXRay
to be able to use the AWSXRayIdGenerator
which generates X-Ray compatible trace IDs.
If you plan to call another application instrumented with AWS X-Ray SDK, you’ll need to configure the AWSXRayPropagator
as well.
dotnet add package OpenTelemetry.Contrib.Extensions.AWSXRay
In order to export traces and metics from your application to ADOT Collector, you need to install OpenTelemetry.Exporter.OpenTelemetryProtocol
.
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
By default the OpenTelemetry exporter sends data to an OpenTelemetry collector at localhost:4317
.
Setting up the Global Tracer and Meter
Sending Traces and Metrics
Configure AWS X-Ray ID generator, propagator and OpenTelemetry Protocol (OTLP) exporter globally in your application as follows. Make sure to call AddXRayTraceId()
in the very beginning when creating TracerProvider
Also configure the meter provider and add a meter of your choice as well as the OpenTelemetry Protocol (OTLP) exporter.
using OpenTelemetry;using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace;using OpenTelemetry.Trace;
var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("ActivitySourceName") .AddXRayTraceId() // for generating AWS X-Ray compliant trace IDs .AddOtlpExporter() // default address localhost:4317 .Build();
var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter("example_meter") .AddOtlpExporter() .Build();
Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); // configure AWS X-Ray propagator
Using the AWS resource Detectors
The ADOT .NET SDK supports automatically recording metadata in EC2, Elastic Beanstalk, ECS, and EKS environments. You can configure the corresponding resource detector to the TracerProvider
following the EC2 example below.
using OpenTelemetry;using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources;using OpenTelemetry.Resources;using OpenTelemetry.Trace;
var tracerProvider = Sdk.CreateTracerProviderBuilder() // other configurations .SetResourceBuilder(ResourceBuilder .CreateDefault() .AddDetector(new AWSEC2ResourceDetector())) .Build();
Instrumenting .NET Applications
Once you have configured all necessary X-Ray components to the TracerProvider
, you can proceed to OpenTelemetry .NET SDK's developer guide to instrument your .NET application.
OpenTelemetry provides a wide range of instrumentations for popular .NET libraries: Asp.Net, Asp.Net Core, Http, Grpc, Redis, Sql and EntityFramework. Instrumenting a library means that every time the library is used to make or handle a request, that library's calls are automatically wrapped within a span. That span is automatically populated with attributes describing the values used by the library call.
AWS SDK Instrumentation
For tracing downstream calls to AWS services from your .NET application, you will need to install the OpenTelemetry.Contrib.Instrumentation.AWS
package.
dotnet add package OpenTelemetry.Contrib.Instrumentation.AWS
Call AddAWSInstrumentation()
to add AWS SDK client instrumentation to TracerProvider
. The below example is for an ASP.NET Core application.
using OpenTelemetry;using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace;using OpenTelemetry.Trace;
public void ConfigureServices(IServiceCollection services){ services.AddControllers(); tracerProvider.AddAWSInstrumentation() // for tracing calls to AWS services via AWS SDK for .NET .AddAspNetCoreInstrumentation() .AddOtlpExporter() .Build();}
Custom Instrumentation
Creating Custom Spans
In .NET, you can use the activity API to create custom spans to monitor the performance of internal activities that are not captured by instrumentation libraries.
using System.Diagnostics;
ActivitySource activitySource = new ActivitySource("ActivitySourceName", "ActivitySourceVersion");var activity = activitySource.StartActivity("ActivityName", ActivityKind.Server); // this will be translated to a X-Ray Segmentvar internalActivity = activitySource.StartActivity("ActivityName", ActivityKind.Internal); // this will be translated to an X-Ray Subsegment
Note that only spans of kind Server
are converted into X-Ray segments, all other kind of spans (Internal
, Client
, etc.) are converted into X-Ray subsegments. For more on segments and subsegments, see the AWS X-Ray developer guide.
Adding Custom Attributes
You can also add custom key-value pairs as attributes onto your spans.
activity.SetTag("http.method", "GET");activity.SetTag("http.url", "http://www.mywebsite.com");
Attributes are converted to metadata by default. If you configure your collector, you can convert some or all of the attributes to annotations. To read more about X-Ray annotations and metadata see the AWS X-Ray developer guide.
For more information about the activity API, see the OpenTelemetry .NET SDK's developer guide.
Creating Metrics
Similarly to Traces, you can create custom metrics in your application using the OpenTelemetry API and SDK.
In the following example application we demonstrate how to use metric instruments to record metrics with a Counter.
using System.Threading.Tasks;
Meter meter = new Meter("example_meter", "1.0");
totalTimeSentObserver = meter.CreateCounter<int>("time_alive", "ms", "Measures the total time the application has been alive");
while (true) { var delayTask = Task.Delay(1000); await Task.Run(() => totalTimeSentObserver.Add(1, new KeyValuePair<string, object>("attribute", "sample"))); await delayTask;}
Sample Application
Take a reference to the sample application that is instrumented by ADOT and OpenTelemetry .NET SDK.