Lesson 28: Logging Architecture (ILogger, Providers, Serilog)
Build production-grade logging with .NET's ILogger, understand log levels, and master structured logging for observability.
What You'll Learn
- • ILogger<T> and the .NET logging abstraction
- • Log levels and when to use each one
- • Structured logging vs string interpolation
- • Setting up logging providers and filtering
🧠 Real-World Analogy
Logging is like a flight recorder (black box) for your application. In development, you review it after a crash. In production, it runs continuously so you can diagnose issues without reproducing them. Structured logging is like filing papers in labelled folders instead of throwing them in a pile.
ILogger<T> — The .NET Way
.NET provides ILogger<T> as the standard logging interface. You inject it via DI, and it automatically tags logs with the class name. The key is using message templates (not string interpolation) so log aggregators can parse and query your logs.
ILogger<T> with DI
Set up structured logging with ILogger, console provider, and exception handling.
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
class OrderProcessor
{
private readonly ILogger<OrderProcessor> _logger;
public OrderProcessor(ILogger<OrderProcessor> logger)
{
_logger = logger;
}
public void ProcessOrder(string orderId, decimal amount)
{
// Structured logging — values are captured as properties
_logger.LogInformation("Processing order {OrderId} for {Amount:C}",
...Log Levels
Each log level serves a specific purpose. In production, you typically filter to Warning and above. In development, you drop to Debug. During incident investigation, you might temporarily enable Trace.
Log Levels Explained
See all 6 .NET log levels with real-world examples and filtering rules.
using System;
using Microsoft.Extensions.Logging;
// Log levels control what gets written and what gets filtered
class Program
{
static void Main()
{
// Simulate different log levels
Console.WriteLine("=== .NET Log Levels (lowest to highest) ===\n");
var levels = new (LogLevel level, string use, string example)[]
{
(LogLevel.Trace, "Most detailed",
"Entering method Calculate with x=5, y=3"),
(LogLevel
...Structured Logging
The difference between $"User {email} logged in" and "User {Email} logged in", email is enormous. The first produces a flat string. The second creates structured data that tools like Seq, Elastic, or Datadog can filter, aggregate, and alert on.
Structured vs Unstructured Logging
Compare searchable structured logs with flat string logs.
using System;
using System.Collections.Generic;
// Structured logging — why it matters
class StructuredLogger
{
public void Log(string template, params (string Key, object Value)[] properties)
{
// In real Serilog/ILogger, properties are stored as structured data
var timestamp = DateTime.UtcNow.ToString("HH:mm:ss.fff");
Console.Write($"[{timestamp}] ");
string message = template;
var propDict = new Dictionary<string, object>();
...Pro Tip
Use LoggerMessage.Define or the [LoggerMessage] source generator attribute for high-performance logging in hot paths. It avoids boxing and string allocation entirely.
Common Mistakes
- • Using
$"..."instead of message templates — loses structure - • Logging sensitive data (passwords, tokens) — security risk
- • Setting minimum level too low in production — performance and noise
Lesson Complete!
You've mastered .NET logging from basics to structured observability. Next, learn high-performance file I/O with Streams, Buffers, and Pipelines.
Sign up for free to track which lessons you've completed and get learning reminders.