.NET API Project Guide
Complete instrumentation and rollout for ASP.NET APIs
Use this guide for ASP.NET APIs where reliability depends on visibility into controllers, services, and outbound dependencies.
- HTTP middleware and endpoint pipeline.
- Service/repository layers.
- Outbound HTTP, DB, and message clients.
Register the Obtrace client and add request instrumentation middleware:
using Obtrace.Sdk;
var builder = WebApplication.CreateBuilder(args);
var cfg = new ObtraceConfig
{
ApiKey = Environment.GetEnvironmentVariable("OBTRACE_API_KEY")!,
ServiceName = "order-api",
Env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "production",
ServiceVersion = Environment.GetEnvironmentVariable("OBTRACE_SERVICE_VERSION") ?? "1.0.0"
};
var client = new ObtraceClient(cfg);
builder.Services.AddSingleton(client);
var app = builder.Build();
app.Use(async (context, next) =>
{
var sw = System.Diagnostics.Stopwatch.StartNew();
await next();
sw.Stop();
var route = context.GetEndpoint()?.DisplayName ?? context.Request.Path.Value ?? "unknown";
var method = context.Request.Method;
client.Span($"http.server {method} {route}", attrs: new Dictionary<string, object?>
{
["http.method"] = method,
["http.route"] = route,
["http.status_code"] = context.Response.StatusCode
});
client.Metric("http.server.request.duration", sw.Elapsed.TotalMilliseconds, "ms", new Dictionary<string, object?>
{
["http.method"] = method,
["http.route"] = route,
["http.status_code"] = context.Response.StatusCode
});
});
app.MapGet("/api/orders/{id}", (string id) =>
{
client.Log("info", "order.fetched", new Dictionary<string, object?>
{
["order.id"] = id
});
return Results.Ok(new { id, status = "shipped" });
});
app.Run();
The await using pattern on ObtraceClient calls ShutdownAsync at end of scope. Console output is captured automatically.
OBTRACE_API_KEY=obt_...
ASPNETCORE_ENVIRONMENT=Production
OBTRACE_SERVICE_VERSION=1.0.0
- Flush on
IHostApplicationLifetime stop token.
- Keep retry bounded and monitored.
- Validate after runtime/package upgrades.
- Missing telemetry after startup changes: confirm middleware is registered before
app.Run().
- Missing outbound spans: wrap HttpClient/DB calls with
client.Span().
- Volume spikes: review emission points and sampling.