Structured Logging vs. Plain Text Logs
Serilog replaces ASP.NET Core's default text-based logging with structured logging, where you write templates like Log.Information("Order {OrderId} shipped to {City}", orderId, city) and Serilog captures OrderId and City as first-class properties rather than baking them into a flat string. This means a log sink like Seq or Elasticsearch can later query 'show me all logs where OrderId = 12345' directly, instead of grep-ing through unstructured text.
Cricket analogy: Structured logging is like a scorer entering each ball into CricViz's ball-by-ball database with fields for bowler, batsman, and runs, instead of writing a flat prose match report — later you can query 'every six Rohit Sharma hit off spin' instantly.
Configuring Sinks and Enrichers
Serilog is configured with a fluent API — new LoggerConfiguration().WriteTo.Console().WriteTo.Seq("http://localhost:5341").Enrich.FromLogContext().Enrich.WithMachineName().CreateLogger() — where sinks define where logs go (console, file, Seq, Application Insights) and enrichers automatically attach contextual properties like MachineName, RequestId, or a custom CorrelationId to every log event without repeating that code at every call site.
Cricket analogy: Configuring sinks and enrichers is like a broadcaster routing the same live match feed to multiple outputs — TV, radio commentary, and a stats overlay — while automatically stamping every feed with the venue name and match date without redoing that for each channel.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.WriteTo.Console()
.WriteTo.Seq("http://localhost:5341")
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
var app = builder.Build();
app.UseSerilogRequestLogging();
app.MapGet("/orders/{id}", (int id, ILogger<Program> logger) =>
{
logger.LogInformation("Fetching order {OrderId}", id);
return Results.Ok(new { id, status = "Shipped" });
});
app.Run();Correlating Logs Across a Request
Using LogContext.PushProperty or Serilog's built-in request logging middleware (UseSerilogRequestLogging()), every log emitted while handling a single HTTP request can be tagged with the same TraceId, so when a request touches a controller, a service, and a database call, all three log lines can be correlated in Seq or Application Insights by filtering on that one identifier — critical for debugging a single failing request in a high-traffic production system.
Cricket analogy: Correlating logs by a shared TraceId is like DRS technology tracking a single delivery across multiple camera angles and Hawk-Eye data feeds, tagged with the same ball number, so the third umpire can pull every piece of evidence for that one delivery instantly.
UseSerilogRequestLogging() replaces the noisy, multi-line default ASP.NET Core request logs with a single structured log line per request that includes the elapsed time, status code, and route template — dramatically reducing log volume while keeping the useful fields queryable.
Observability Beyond Logs: Metrics and Tracing
Full observability pairs Serilog's structured logs with metrics (request duration, error rate counters, often exposed via OpenTelemetry) and distributed tracing (spans that follow a request across microservice boundaries). ASP.NET Core's built-in support for the OpenTelemetry SDK lets you export traces and metrics to backends like Azure Monitor or Jaeger, so logs answer 'what happened,' metrics answer 'how often,' and traces answer 'where did the time go across services.'
Cricket analogy: Pairing logs with metrics and tracing is like a cricket analytics team combining ball-by-ball logs, aggregate strike-rate metrics, and a full wagon-wheel trace of shot placement — logs tell you what happened on one ball, metrics tell you a batsman's overall form, and the trace shows where every run came from.
Avoid logging sensitive data like passwords, full credit card numbers, or personal identifiers directly into structured properties — sinks like Seq or Application Insights retain logs for extended periods, and a structured property is just as much a compliance risk as plain text, arguably easier to query and exfiltrate.
- Structured logging captures values as queryable properties, not flat strings
- Sinks define where logs go; enrichers attach contextual properties automatically
- UseSerilogRequestLogging() condenses each request into one structured summary line
- A shared correlation ID like TraceId ties together every log line for one request
- Metrics show aggregate trends; traces show per-request cross-service detail
- OpenTelemetry provides vendor-neutral export of traces and metrics
- Never log sensitive data as structured properties
Practice what you learned
1. What is the main benefit of structured logging over plain text logging?
2. In Serilog, what is the role of an 'enricher'?
3. What does UseSerilogRequestLogging() provide?
4. Which of the following best distinguishes metrics from traces in observability?
Was this page helpful?
You May Also Like
Deploying to Azure App Service and Docker
Containerize an ASP.NET Core app with a multi-stage Dockerfile and deploy it to Azure App Service using Key Vault-backed configuration and deployment slots.
Unit Testing Controllers and Services
Learn how to isolate ASP.NET Core controllers and services with xUnit and Moq to verify business logic without running the full HTTP pipeline.
ASP.NET Core Interview Questions
A focused review of the ASP.NET Core fundamentals, common pitfalls, and system-design questions that come up most often in technical interviews.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics