Lessons in this course (8)

8. OpenTelemetry, Application Insights and querying logs in production

Intermediate★ Must knowLesson 8 of 8
csharp
builder.Logging.AddOpenTelemetry(o => { o.IncludeFormattedMessage = true; o.IncludeScopes = true; });
builder.Services.AddOpenTelemetry()
    .ConfigureResource(r => r.AddService("Shop.Api"))
    .WithTracing(t => t.AddAspNetCoreInstrumentation().AddHttpClientInstrumentation().AddSqlClientInstrumentation())
    .WithMetrics(m => m.AddAspNetCoreInstrumentation().AddRuntimeInstrumentation())
    .UseOtlpExporter();          // to the Aspire dashboard, Jaeger, Grafana, or Azure Monitor (UseAzureMonitor())

Logs written inside a request automatically carry its TraceId/SpanId, so you can jump from an error log to the full distributed trace.

Querying (Application Insights / Azure Monitor KQL):

kusto
traces
| where timestamp > ago(1h) and severityLevel >= 3
| where customDimensions.OrderId == "1001"
| project timestamp, message, operation_Id

exceptions
| where timestamp > ago(24h)
| summarize count() by type, outerMessage
| order by count_ desc

Production practices:

  • Log to stdout as JSON in containers; let the platform ship logs.
  • Central log store with retention policies and access control.
  • Alerts on error rates and critical events, not on every single error.
  • Sampling for high-volume debug/trace data; never sample audit logs.
  • Redact sensitive values (Microsoft.Extensions.Compliance.Redaction, Serilog destructuring policies).
  • Change levels at runtime without redeploy (configuration reload, App Configuration, Serilog LoggingLevelSwitch).