OpenTelemetry is an open-source observability framework for cloud-native software. It provides a vendor-neutral set of APIs and SDKs to collect and export traces, metrics, and logs.
In TaskHub, OTEL is the shared spine that ties together logs (Loki), metrics (Prometheus), and traces (Tempo) into a single observable system.
[PRE]/[HNDLR]/[POST] spans; the Response system tags every Result onto the active activity.| Signal | What it answers | TaskHub backend |
|---|---|---|
| Traces | βWhere did this request spend its time, and who did it call?β | Grafana Tempo |
| Metrics | βHow fast / how many / how big β over time?β | Prometheus |
| Logs | βWhat happened, in human-readable detail?β | Grafana Loki |
All three are stitched together by TraceId and SpanId, so a slow trace in Tempo links directly to its log lines in Loki.
TaskHub.Observability.OpenTelemetry provides:
AddAppOpenTelemetry() β single-call registration that wires up tracing, metrics, and resource attributes.OpenTelemetryOptions β configuration record (endpoint, sampling, instrumentations, ignored paths).See OpenTelemetry usage for setup and OpenTelemetry architecture for internals.
"OpenTelemetry": {
"ServiceVersion": "1.0",
"Protocol": "grpc",
"TracingEndpoint": "http://otel-collector:4317",
"Environment": "Production",
"RecordException": true,
"IsHttpTracesEnabled": true,
"IsAspNetTracesEnabled": true,
"IsEFCoreTracesEnabled": true,
"Ignore": [ "/health", "/metrics", "/swagger" ],
"Sources": [ "ReaderRepository", "WriterRepository" ],
"Sampling": { "IsEnabled": true, "Type": "AlwaysOn" }
}
Sources is the list of custom ActivitySource names your service emits β list every one, or spans wonβt be exported.
| Type | Behavior | When to use |
|---|---|---|
AlwaysOn |
Every trace exported. | Dev, staging, low-traffic services. |
AlwaysOff |
Nothing exported. | Trace-only-on-demand setups. |
TraceIdRatio |
Random fraction (e.g. 0.1 = 10%). | High-traffic production. |
ParentBased |
Inherit decision from upstream service. | Chained microservices. |
/health, /ready, /metrics in Ignore. Otherwise sampler exhaustion drowns useful traces.new ActivitySource("OrderRepository") not new ActivitySource("repo"). Names show up in Tempoβs service map.job.id, user.id, result.code. These become searchable in Tempo. Avoid high-cardinality tags like full URLs or timestamps.activity?.SetStatus(ActivityStatusCode.Error) ensures Tempo flags the span red. The Response system does this automatically when a Result fails.TraceId.