.NET SDK
Full observability for .NET services — HTTP, databases, gRPC, and logging captured automatically via OpenTelemetry
Installation
Targets .NET 6+ and .NET Standard 2.1.
Minimum Setup
Two fields are required: ApiKey and ServiceName. Everything else has defaults.
Built on OpenTelemetry
The .NET SDK uses OpenTelemetry.Instrumentation.Http and OpenTelemetry.Instrumentation.AspNetCore under the hood. The AddObtrace() extension method configures everything via the standard .NET dependency injection system, including OTel exporters, resource attributes, and all available instrumentations.
What's Captured Automatically
After creating an ObtraceClient, the SDK configures OpenTelemetry and instruments your application. You don't need to write any extra code for this:
| What | How | Needs code? |
|---|---|---|
| Console.WriteLine() | Console.Out writes are intercepted and sent as info logs | No |
| Console.Error.WriteLine() | Console.Error writes are intercepted and sent as error logs | No |
| Outbound HttpClient calls | HttpClient instrumented via OpenTelemetry.Instrumentation.Http with spans and traceparent injection | No |
| Inbound ASP.NET Core requests | Instrumented via OpenTelemetry.Instrumentation.AspNetCore when using AddObtrace() | No |
| SQL Server / EF Core | SqlClient and Entity Framework instrumented via OTel when packages are installed | No |
| gRPC | Grpc.Net.Client instrumented via OpenTelemetry.Instrumentation.GrpcNetClient | No |
| Redis | StackExchange.Redis instrumented via OTel when the instrumentation package is installed | No |
| Shutdown flush | IAsyncDisposable flushes remaining data on dispose | No |
Console auto-capture is enabled by default (AutoCaptureConsole = true). Set AutoCaptureConsole = false to disable it.
Opting Out of Auto HTTP Instrumentation
ASP.NET Core Integration with AddObtrace()
For ASP.NET Core apps, use the AddObtrace() extension method to register the client in DI, add the HTTP request middleware, and wire up shutdown:
AddObtrace() configures OpenTelemetry via the .NET DI system: it registers the OTLP exporter, adds OpenTelemetry.Instrumentation.AspNetCore for inbound request spans, adds OpenTelemetry.Instrumentation.Http for outbound HttpClient spans, registers ObtraceClient as a singleton, and hooks into ApplicationStopping to flush on shutdown. If you have OpenTelemetry.Instrumentation.SqlClient, OpenTelemetry.Instrumentation.EntityFrameworkCore, OpenTelemetry.Instrumentation.GrpcNetClient, or OpenTelemetry.Instrumentation.StackExchangeRedis packages installed, they are also configured automatically.
Optional: Custom Telemetry
The automatic console and HTTP capture covers basic observability. For business-specific events, use the SDK methods directly.
Logging
Use client.Log() for structured events that represent something that happened. Logs are best for state transitions, errors, and audit trails.
Levels: trace, debug, info, warn, error, fatal.
Metrics
Use client.Metric() for numerical measurements you want to track over time. Metrics are best for gauges, counters, and percentiles.
The unit parameter follows OTLP conventions: "ms" for milliseconds, "By" for bytes, "1" for dimensionless values.
Tracing / Spans
Use client.Span() for operations with duration that you want to visualize in a trace waterfall. Spans are best for database queries, HTTP calls, queue processing, and any work that takes measurable time.
Framework Integration
ASP.NET Core (Manual)
If you prefer manual setup over AddObtrace():
Worker Service / Background Jobs
Configuration Reference
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
ApiKey | string | Yes | Obtrace API key | |
ServiceName | string | Yes | Stable name for this service | |
TenantId | string? | No | from key | Tenant identifier |
ProjectId | string? | No | from key | Project identifier |
AppId | string? | No | Application identifier within the project | |
Env | string | No | "production" | Deployment environment |
ServiceVersion | string? | No | Version string for this deployment | |
AutoCaptureConsole | bool | No | true | Intercept Console.Out and Console.Error as logs |
AutoInstrumentHttp | bool | No | true | Instrument outbound HttpClient calls with spans and trace propagation |
ValidateSemanticMetrics | bool | No | false | Warn on non-standard metric names |
Debug | bool | No | false | Enable verbose logging to stdout |
MaxQueueSize | int | No | 2048 | Maximum buffered items before dropping |
FlushIntervalMs | int | No | 5000 | Auto-flush interval in milliseconds |
Validation Checklist
After deploying, verify:
ServiceName,Env, andServiceVersionare stable across restarts and match what you see in the Obtrace UI- At least one real request path emits both a log and a span
- No
401or403errors appear in stdout whenDebug = true FlushAsyncorShutdownAsyncis called before process exit (useawait using,AddObtrace(), or register withApplicationStopping)- Outbound HttpClient calls show auto-generated spans
- Metrics use OTLP-standard units (
ms,By,1) not custom strings