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
| Attribute | Source | Description |
|---|---|---|
service.name | Assembly name or OTEL_SERVICE_NAME | ”BitzOrcas.Api” or “BitzOrcas.JobHost” |
service.version | Assembly version | ”1.0.0” |
deployment.environment | OTEL_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
ICorrelationContextinjection
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:
export OTEL_TRACES_SAMPLER=traceidratioexport OTEL_TRACES_SAMPLER_ARG=0.1 # 10% samplingSee also
- Health checks — Health probe configuration
- Mediator pipeline — ActivityAudit in pipeline