Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
What's New in Logging from .NET 8 to .NET 11: Enrichment, Redaction, FakeLogger, Buffering and Generic LoggerMessage
Logging in .NET moves on two trains: ILogger and the source generator ship with the runtime, while enrichment, redaction, FakeLogger, sampling and buffering come with the monthly Microsoft.Extensions.Telemetry packages. With real output we show which feature arrived when, CA1873 and the obsolete AddServiceLogEnricher in .NET 10, generic LoggerMessage in .NET 11, and how to read old Serilog Startup code.
Log Levels and Cost: Sampling, Buffering and Changing Log Levels Live in Production
Log volume is set by your level configuration: the same 1000 requests produced 6.3 MB of logs at Debug and 246 KB at Information with Microsoft.AspNetCore=Warning. With real output we show random and trace-based sampling in Microsoft.Extensions.Telemetry, per-request buffering that writes Debug logs on failure, changing levels without a restart, and how sampling can drop Errors and buffers lose scopes and TraceId.
HTTP Logging in ASP.NET Core: AddHttpLogging, the W3C Logger and the Cost of Request/Response Bodies
Use HTTP logging in production with one event per request, bodies off, and an interceptor that logs the body only on errors. The real defaults of AddHttpLogging, the header allow list, CombineLogs, [HttpLogging] and WithHttpLogging, an IHttpLoggingInterceptor that logs bodies on 4xx/5xx, the W3C logger file and the measured cost of body logging: 85 KB of allocations per request instead of 8 KB.
Sensitive Data in Logs: Redaction, Data Classification and Privacy-Compliant Logging
The way to keep sensitive data out of logs is to classify it and mask it automatically in the logging pipeline. Taxonomy and attributes with Microsoft.Extensions.Compliance.Redaction, [LogProperties], ErasingRedactor, your own redactor and the HMAC redactor that keeps correlation; masking with destructuring in Serilog, personal data in exception messages and a FakeLogger test that catches it, with real output.
Correlation IDs and Trace Context: Linking Every Log of a Request from the API to the Queue
The way to link every log of a request is to write the TraceId from the W3C traceparent on every log line. ASP.NET Core and HttpClient do it on their own; across a queue and a BackgroundService the chain breaks and must be carried manually with DistributedContextPropagator. ActivityTrackingOptions, Serilog, baggage, X-Correlation-ID, a support code on the error screen and one Seq query, with real output.
Reading Structured Logs with Seq: Docker Setup, Queries, Signals and Alerts
We run Seq in Docker with a password and a separate ingestion port, and send logs through Serilog and OTLP with an Ingest-only API key. Filters, group by and percentile queries, logs and spans on the same TraceId, signals, alerts and signal-based retention, all with real results, including why 8 failures became 16 events and the ERROR level trap with OTLP.
Serilog Sinks: Console, File, Seq and OpenTelemetry — Async, Batching and Lost Logs
In a container, logs go to stdout as compact JSON; if you need files, set rolling and retention explicitly. Serilog 4's core batching and the async wrapper either drop events or hold the app when a sink is slow: 101 of 2,000 events arrived, or the loop took 2.4 seconds. SelfLog, going out to OTLP and per-sink levels.
Serilog in Depth: Bootstrap Logger, appsettings Configuration, Enrichers and Request Logging
A production-ready Serilog setup has two stages: a bootstrap logger that catches startup failures, then the real logger fed by appsettings and DI. ReadFrom.Configuration, a custom enricher, PushProperty versus BeginScope, UseSerilogRequestLogging writing one summary event per request, and the logs lost when CloseAndFlush is forgotten.
High-Performance Logging: the LoggerMessage Source Generator, IsEnabled and Allocation Cost
Even a disabled LogDebug line allocates 128 bytes per call because of params object[] and boxing; the [LoggerMessage] source generator brings that to zero with typed parameters and an IsEnabled check. BenchmarkDotNet measurements, an event catalog, primary constructors, [LogProperties] and the cost of the Telemetry package swapping the generator.
What to Log and What Not To: A Logging Strategy for .NET and the Anatomy of a Good Log Event
A good log event is a single occurrence that answers its reader's question: it has a constant message template, meaningful property names and an EventId. We turn five bad log lines in the Bookstore order flow into three events and show level choice, double-logged exceptions and the cost of interpolation caught by CA2254 with real output.
OWASP A09: Security Logging and Alerting Failures — What to Log, What Never to Log
We start with a login endpoint that writes wrong passwords to the log, lets a line break forge a record and never records 403s. We move to structured logging with LoggerMessage and the JSON console, make authorization denials visible, protect the email with HMAC redaction, tie the response to the log through traceId and look at which events deserve an alert.
EF Core Interceptors and Events: Audit Fields and Slow Query Logging
We fill CreatedAt and UpdatedAt automatically with a SaveChangesInterceptor, log queries over a threshold with a DbCommandInterceptor, and watch the change tracker live through SavingChanges and StateChanged events. We also see why nothing runs when you forget the async override.