Skip to content
bitzorcas
EN

Concept

Observability

OpenTelemetry observability — traces + metrics via OTLP export, custom SqlSugar ActivitySource, CorrelationId propagation, and structured logging.

Last updated

BitzOrcas uses OpenTelemetry as the unified observability framework with OTLP export for traces and metrics. Both API Host and JobHost share the same ServiceDefaults configuration.

Architecture

API Host / JobHost
OpenTelemetry SDK
├── Traces: ASP.NET Core + HttpClient + SqlSugar ActivitySource
└── Metrics: ASP.NET Core + HttpClient + Runtime (GC/ThreadPool/CPU)
OTLP Exporter → Collector (OTLP endpoint)
Jaeger / Tempo / Datadog / etc.

ServiceDefaults

Both hosts share BitzOrcas.ServiceDefaults.AddServiceDefaults():

builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource
.AddService(serviceName, serviceVersion)
.AddAttributes(new[] { new("deployment.environment", environment) }))
.WithTracing(tracing => tracing
.AddAspNetCoreInstrumentation() // HTTP inbound
.AddHttpClientInstrumentation() // HTTP outbound
.AddSource(BitzOrcasActivitySources.All) // SqlSugar custom
.AddOtlpExporter(o => o.Endpoint = endpoint))
.WithMetrics(metrics => metrics
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation() // GC / ThreadPool / CPU
.AddOtlpExporter(o => o.Endpoint = endpoint));

Resource attributes

AttributeSourceDescription
service.nameAssembly name or OTEL_SERVICE_NAME”BitzOrcas.Api” or “BitzOrcas.JobHost”
service.versionAssembly version”1.0.0”
deployment.environmentOTEL_DEPLOYMENT_ENVIRONMENT”development” / “staging” / “production”

OTLP endpoint configuration

{
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://localhost:4317",
"OTEL_SERVICE_NAME": "bitzorcas-api",
"OTEL_DEPLOYMENT_ENVIRONMENT": "development"
}

Production endpoint injected by orchestration (Aspire/K8s).

Custom ActivitySource

SqlSugar operations emit custom spans via BitzOrcasActivitySources:

public static class BitzOrcasActivitySources
{
public static string[] All => [SqlSugar];
}

This provides query-level tracing for database operations without modifying SqlSugar internals.

CorrelationId propagation

CorrelationIdMiddleware generates/propagates a X-Correlation-Id header through the entire request chain:

  • Missing header: generates new UUID
  • Existing header: propagates unchanged
  • Included in all ProblemDetails error responses
  • Available via ICorrelationContext injection

Structured logging

BitzOrcas uses ASP.NET Core’s built-in ILogger<T> with structured parameters:

logger.LogInformation(
"Note created {NoteId} by {UserId} in tenant {TenantId}",
note.Id, user.UserId, user.TenantId);

Log output is UTF-8 encoded (Console.OutputEncoding = Encoding.UTF8 in Program.cs) for proper Chinese character rendering.

Business context tags (OTel)

Tenant and user context are propagated as OTel business tags for correlation in dashboards:

tenant.id = "100"
user.id = "abc-123"
caller.type = "User" | "Application"

Sampling

Default: ParentBasedSampler(AlwaysOnSampler). Production can switch via:

Terminal window
export OTEL_TRACES_SAMPLER=traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1 # 10% sampling

See also