Roadmap › 1. .NET › Step 23
Log
Logging & Custom Logging in .NET — ILogger, Serilog, NLog, log4net and Your Own Logger
Why and what to log, log levels, structured vs plain-text logging, Microsoft.Extensions.Logging (ILogger, providers, categories, filtering, scopes, high-performance LoggerMessage source generators), Serilog (sinks, enrichers, request logging), NLog and log4net (including .NET Framework apps), Trace and Windows Event Log, writing a custom logger provider (file and database), audit logging, correlation ids and distributed tracing with OpenTelemetry and Application Insights, log storage and querying (Seq, ELK, Azure Monitor/KQL), security (PII, secrets) and performance.
What it is & where it is used
Logging records what an application does so you can understand behaviour, diagnose problems and audit actions — especially in production where you can't attach a debugger.
| Signal | Answers | Example tools |
|---|---|---|
| Logs | What happened, in detail? | ILogger, Serilog, NLog, log4net |
| Metrics | How many / how fast / how often? | System.Diagnostics.Metrics, Prometheus, App Insights |
| Traces | Where did time go across services for one request? | Activity, OpenTelemetry, Jaeger, App Insights |
| Audit trail | Who did what to which data, when? | Dedicated audit tables/log store |
Together logs, metrics and traces are called observability.
Versions & history
| Year | Milestone |
|---|---|
| 2001–2004 | log4net (Apache port of log4j); System.Diagnostics.Trace/EventLog in .NET Framework |
| 2006 | NLog 1.0 |
| 2009 | ELMAH (error logging for ASP.NET Web Forms/MVC) |
| 2013 | Serilog — structured logging for .NET |
| 2016 | Microsoft.Extensions.Logging (ILogger<T>) with ASP.NET Core 1.0 |
| 2019–2021 | LoggerMessage.Define; .NET 6 logging source generator ([LoggerMessage]) |
| 2021–2023 | OpenTelemetry .NET 1.0 (tracing 2021, metrics 2022, logs 2023) |
| 2024–2025 | .NET 8/9 log redaction/enrichment (Microsoft.Extensions.Telemetry), .NET Aspire dashboard with OpenTelemetry logs |
Lifecycle
Life of a log event:
- Code calls
logger.LogWarning("Payment {PaymentId} retry {Attempt}", id, attempt). - The logger checks if the level is enabled for this category (cheap check — nothing else happens if not).
- A log entry is created: timestamp, level, category, message template, named properties (PaymentId, Attempt), exception, scope data (RequestId, TraceId, user).
- Each registered provider/sink receives it: console, file, Seq, Application Insights, database…
- Sinks often buffer and batch asynchronously, then write/send.
- Logs are stored with a retention period, queried (search by property, KQL), turned into alerts and dashboards.
Tools used to develop
- Frameworks: Microsoft.Extensions.Logging, Serilog (+ Serilog.AspNetCore, sinks), NLog (+ NLog.Web.AspNetCore), log4net, ELMAH (.NET Framework).
- Stores/viewers: Seq, Elasticsearch + Kibana (ELK/Elastic Stack), Grafana Loki, Azure Monitor / Application Insights (KQL), Datadog, Splunk, Windows Event Viewer.
- Tracing: OpenTelemetry SDK + exporters (OTLP), .NET Aspire dashboard, Jaeger, Zipkin.
- CLI:
dotnet-trace,dotnet-counters,dotnet-monitor.