I have a problem with OpenTelemetry configuration in my .NET 8 web app.
Logs are visible in the Grafana/Loki application, but I see only one label service_name
with value unknown_service:dotnet
.
When I configure Serilog to write logs directly to Loki (.WriteTo.GrafanaLoki(...)
), everything works fine.
How to properly configure the entire application to be able to define my own labels in Loki?
My configuration:
Application (.NET):
OpenTelemetryBuilder builder
= webAppBuilder.Services.AddOpenTelemetry().ConfigureResource(
resBuilder => resBuilder.AddService(
serviceName: resource.Name,
serviceVersion: resource.Version,
autoGenerateServiceInstanceId: false,
serviceInstanceId: Environment.MachineName
));
builder.WithTracing(tracing => {
tracing.AddSource("MyApp")
.AddAspNetCoreInstrumentation(o =>
{
o.RecordException = true;
})
.AddHttpClientInstrumentation(h => h.RecordException = true)
.SetSampler(new AlwaysOnSampler())
.SetErrorStatusOnException()
.AddOtlpExporter(); // GRPC: http://localhost:4317
builder.WithMetrics(metrics => {
metrics.AddMeter("MyApp")
.AddMeter(DiagnosticHeaders.DefaultListenerName)
.SetExemplarFilter(ExemplarFilterType.TraceBased)
.AddRuntimeInstrumentation()
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation()
.AddProcessInstrumentation()
.AddOtlpExporter(); // GRPC: http://localhost:4317
webAppBuilder.Services.AddSerilog(
(serviceProvider, configuration) =>
{
configuration.Enrich.WithProcessId()
.Enrich.WithThreadId()
.Enrich.FromLogContext()
.MinimumLevel.Verbose()
.WriteTo.AddConsoleSink()
.WriteTo.OpenTelemetry() // GRPC: http://localhost:4317
}
);
otel-collector.yaml (on Docker from image otel/opentelemetry-collector:latest
):
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 3s # Batch data for up to 3 seconds
send_batch_size: 1000 # Number of spans or metrics per batch
exporters:
prometheus:
endpoint: ":9201" # Prometheus remote write endpoint
send_timestamps: true
metric_expiration: 180m
enable_open_metrics: true
otlp/tempo:
endpoint: tempo:4317 # Endpoint for Tempo to send traces
tls:
insecure: true
otlphttp/loki:
endpoint: http://loki:3100/otlp # Endpoint for Loki to send logs
tls:
insecure: true
extensions:
health_check:
service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/tempo]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/loki]
Loki-config.yaml (on Docker from image grafana/loki:3.1.0
)
limits_config:
allow_structured_metadata: true