OpenTelemetry is an open-source, vendor-neutral observability framework for generating, collecting, and exporting telemetry data (metrics, traces, and logs). It provides a standardised way to instrument applications, making it possible to monitor and troubleshoot distributed systems without being locked in to a particular observability vendor.
Open.IdentityServer provides built-in OpenTelemetry support through its ITelemetryService interface and DefaultTelemetryService implementation. Telemetry data is emitted automatically for key operations such as token issuance, client authentication, and request handling — with no additional configuration required to start collecting signals.
Overview¶
OpenTelemetry defines three primary signal types:
Metrics — Numerical measurements that describe the behaviour of your system over time (e.g. request counts, error rates, active connections).
Traces — Records of the path a request takes through your system, broken into spans that represent individual units of work.
Logs — Timestamped text records, enriched with structured data, that capture discrete events.
Open.IdentityServer emits metrics and traces natively using the .NET System.Diagnostics APIs (Meter, Counter, ActivitySource). Logging is handled through the standard ASP.NET Core ILogger infrastructure, which can be exported via OpenTelemetry’s logging bridge.
Getting Started¶
OpenTelemetry signals are emitted by Open.IdentityServer automatically. To collect and export them, you need to configure the OpenTelemetry SDK in your host application.
Install the required NuGet packages:
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
Then configure the OpenTelemetry SDK in your Program.cs or Startup.cs:
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
using OpenTelemetry.Logs;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddIdentityServer()
// ... your IdentityServer configuration
;
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource =>
{
resource.AddService("<Your IdentityServer application name>");
})
.WithMetrics(metrics =>
{
metrics
.AddMeter(TelemetryConstants.MetricsConstants.MeterName)
.AddOtlpExporter();
})
.WithTracing(tracing =>
{
tracing
.AddAspNetCoreInstrumentation()
.AddSource(TelemetryConstants.TraceCategories.Basic)
.AddSource(TelemetryConstants.TraceCategories.Cache)
.AddSource(TelemetryConstants.TraceCategories.Services)
.AddSource(TelemetryConstants.TraceCategories.Stores)
.AddSource(TelemetryConstants.TraceCategories.Validation)
.AddOtlpExporter();
});
builder.Logging.AddOpenTelemetry(logging =>
{
logging.AddOtlpExporter();
});
Note
The DefaultTelemetryService is registered as a singleton automatically when you call AddIdentityServer(). No additional registration is needed to enable telemetry.
Metrics¶
Open.IdentityServer exposes metrics through a .NET Meter named Open.IdentityServer. All metric instruments are counters that track the volume and outcome of protocol operations.
Meter Name¶
Open.IdentityServer
Available Instruments¶
Instrument Name |
Type |
Description |
|---|---|---|
|
Counter |
Counts all operations, tagged with |
|
UpDownCounter |
Tracks the number of currently active IdentityServer protocol requests. Tagged with |
|
Counter |
Counts API secret validation attempts. Tagged with |
|
Counter |
Counts client secret validation attempts. Tagged with |
|
Counter |
Counts client configuration validation attempts. Tagged with |
|
Counter |
Counts tokens issued. Tagged with |
|
Counter |
Counts token introspection requests. Tagged with |
|
Counter |
Counts token revocation requests. Tagged with |
|
Counter |
Counts device authentication requests. Tagged with |
|
Counter |
Counts resource owner password authentication attempts. Tagged with |
|
Counter |
Counts backchannel (CIBA) authentication requests. Tagged with |
|
Counter |
Counts pushed authorization requests (PAR). Tagged with |
Subscribing to Metrics¶
To collect Open.IdentityServer metrics, subscribe to the Open.IdentityServer meter in your OpenTelemetry configuration:
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics.AddMeter(TelemetryConstants.MetricsConstants.MeterName);
});
Traces¶
Open.IdentityServer uses .NET ActivitySource instances to create distributed trace spans. Traces provide visibility into the internal processing of each request, helping you identify performance bottlenecks and understand the flow of operations.
Activity Sources¶
Open.IdentityServer defines several activity sources, each representing a category of operations:
Activity Source Name |
Description |
|---|---|
|
Top-level protocol request processing (e.g. the overall handling of a token or authorize request). |
|
Caching operations (cache reads, writes, and invalidations). |
|
Internal service operations (token creation, consent, key material, etc.). |
|
Data store operations (reading/writing grants, clients, resources). |
|
Validation operations (token validation, request validation, secret validation). |
Subscribing to Traces¶
To collect traces, add the relevant activity sources to your OpenTelemetry tracing configuration:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
// Subscribe to all Open.IdentityServer activity sources
tracing
.AddAspNetCoreInstrumentation()
.AddSource(TelemetryConstants.TraceCategories.Basic)
.AddSource(TelemetryConstants.TraceCategories.Cache)
.AddSource(TelemetryConstants.TraceCategories.Services)
.AddSource(TelemetryConstants.TraceCategories.Stores)
.AddSource(TelemetryConstants.TraceCategories.Validation);
});
You can subscribe to a subset of sources if you only need visibility into specific categories. For example, to trace only store operations:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing
.AddAspNetCoreInstrumentation()
.AddSource(TelemetryConstants.TraceCategories.Stores);
});
Trace Granularity¶
Each trace activity is named after the class and method performing the operation, providing fine-grained visibility. For example, a token request might produce a trace hierarchy such as:
Open.IdentityServer: IdentityServerProtocolRequest
└─ Open.IdentityServer: TokenEndpoint.ProcessAsync
└─ Open.IdentityServer.Validation: ClientSecretValidator.ValidateAsync
└─ Open.IdentityServer.Validation: TokenRequestValidator.ValidateRequestAsync
└─ Open.IdentityServer.Stores: DefaultRefreshTokenStore.GetRefreshTokenAsync
└─ Open.IdentityServer.Services: DefaultTokenService.CreateAccessTokenAsync
Tracing in ASP.NET Core¶
Additional trace data is automatically captured by the OpenTelemetry ASP.NET Core instrumentation package (OpenTelemetry.Instrumentation.AspNetCore).
The AddAspNetCoreInstrumentation() method automatically creates traces for HTTP requests, including:
Request duration
HTTP method, route, and status code
Network information
User agent
These traces are collected without requiring any additional code in your controllers or middleware. For more details on the ASP.NET Core instrumentation, see the OpenTelemetry ASP.NET Core Instrumentation documentation.
Logging¶
Open.IdentityServer uses the standard ASP.NET Core ILogger infrastructure for structured logging. Log messages are emitted at various levels throughout the processing pipeline, providing detailed diagnostic information.
To export logs via OpenTelemetry, configure the logging bridge:
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
logging.AddOtlpExporter();
});
For more details on log levels and filtering, see the Logging documentation page.
Note
If using Serilog, you will need to use the OpenTelemetry Serilog Sink to forward logs to OpenTelemetry. The built-in logging bridge does not support Serilog directly.
Exporters¶
OpenTelemetry supports a wide variety of exporters for sending telemetry data to your chosen backend. Common choices include:
OTLP (OpenTelemetry Protocol) — The standard protocol, supported by most observability platforms (e.g. Jaeger, Grafana, Datadog, Azure Monitor, AWS X-Ray).
Prometheus — For metrics scraping (use
OpenTelemetry.Exporter.Prometheus.AspNetCore).Console — Useful during development (use
OpenTelemetry.Exporter.Console).
Example using the Console exporter for development:
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics
.AddMeter("Open.IdentityServer")
.AddConsoleExporter();
})
.WithTracing(tracing =>
{
tracing
.AddAspNetCoreInstrumentation()
.AddSource("Open.IdentityServer")
.AddSource("Open.IdentityServer.Cache")
.AddSource("Open.IdentityServer.Services")
.AddSource("Open.IdentityServer.Stores")
.AddSource("Open.IdentityServer.Validation")
.AddConsoleExporter();
});
Customisation¶
The ITelemetryService interface can be replaced with a custom implementation if you need to modify or extend the telemetry behaviour. The default implementation is registered with TryAddSingleton, so you can override it by registering your own implementation before or after calling AddIdentityServer().
Note
In most cases, the default implementation combined with OpenTelemetry SDK configuration provides sufficient flexibility without needing a custom ITelemetryService.