How to setup OpenTelemetry instrumentation in ASP.NET core
In this post I’ll show how to setup OpenTelemetry tracing, metrics and logging for AspNetCore on dotnet 6
New project
Start by creating a new project. I’ll be using the webapi template.
dotnet new webapi --output opentelemetry-example
Add required packages
Then we need to add the OpenTelemetry packages.
dotnet add package --prerelease OpenTelemetry.Exporter.Console
dotnet add package --prerelease OpenTelemetry.Extensions.Hosting
dotnet add package --prerelease OpenTelemetry.Instrumentation.AspNetCore
The first package is the console exporter which is for outputing telemetry data on to your local developer console. For a real project you would probably use something like the jaeger or the otlp exporter.
The Extension.Hosting package includes the extension methods AddOpenTelemetryTracing
and AddOpenTelemetryMetrics
which is used on IServiceCollection
to setup OpenTelemetry. It also adds the LoggingBuilder
extension method AddOpenTelemetry
.
The Instrumentation.AspNetCore package collects telemetry data about incoming web requests. It provides the AddAspNetCoreInstrumentation
extension method for TraceProviderBuilder
and MeterProviderBuilder
Add tracing
builder.Services
.AddOpenTelemetryTracing((builder) => builder
// Configure the resource attribute `service.name` to MyServiceName
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"))
// Add tracing of the AspNetCore instrumentation library
.AddAspNetCoreInstrumentation()
.AddConsoleExporter()
);
Add metrics
builder.Services
.AddOpenTelemetryMetrics(builder => builder
// Configure the resource attribute `service.name` to MyServiceName
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"))
// Add metrics from the AspNetCore instrumentation library
.AddAspNetCoreInstrumentation()
.AddConsoleExporter(options =>
{
options.MetricReaderType = MetricReaderType.Periodic;
options.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 5000;
}));
Add logging
builder.Host
.ConfigureLogging(logging => logging
.ClearProviders()
.AddOpenTelemetry(options =>
{
// Export the body of the message
options.IncludeFormattedMessage = true;
// Configure the resource attribute `service.name` to MyServiceName
options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"));
options.AddConsoleExporter(options =>
{
options.MetricReaderType = MetricReaderType.Periodic;
options.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 5000;
});
}));
Complete example
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services
.AddOpenTelemetryTracing((builder) => builder
// Configure the resource attribute `service.name` to MyServiceName
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"))
// Add tracing of the AspNetCore instrumentation library
.AddAspNetCoreInstrumentation()
.AddConsoleExporter()
);
builder.Services
.AddOpenTelemetryMetrics(builder => builder
// Configure the resource attribute `service.name` to MyServiceName
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"))
// Add metrics from the AspNetCore instrumentation library
.AddAspNetCoreInstrumentation()
.AddConsoleExporter(options =>
{
options.MetricReaderType = MetricReaderType.Periodic;
options.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 5000;
}));
builder.Host
.ConfigureLogging(logging => logging
.ClearProviders()
.AddOpenTelemetry(options =>
{
// Export the body of the message
options.IncludeFormattedMessage = true;
// Configure the resource attribute `service.name` to MyServiceName
options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"));
options.AddConsoleExporter(options =>
{
options.MetricReaderType = MetricReaderType.Periodic;
options.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 5000;
});
}));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();