In this lesson, you will learn how to build custom diagnostic log enrichers to automatically inject context into every log entry, ensuring your logs are actionable without cluttering your business logic.
The Problem with Manual Logging
When debugging high-throughput systems, logs are useless if they lack context. You might manually add userId or correlationId to every _logger.LogInformation call, but this is error-prone and violates the DRY (Don't Repeat Yourself) principle. A Log Enricher solves this by acting as a global interceptor that attaches metadata to the LogEvent before it is written to the sink.
Implementing a Custom Enricher
In the Serilog ecosystem, for example, you implement the ILogEventEnricher interface. The goal is to "enrich" the log event with properties derived from the current execution context, such as the machine name, a specific header, or a custom user state.
Here is how you define a simple enricher that adds the current thread's ID to every log:
public class ThreadIdEnricher : ILogEventEnricher
{
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var threadId = Environment.CurrentManagedThreadId;
logEvent.AddPropertyIfAbsent(
propertyFactory.CreateProperty("ThreadId", threadId));
}
}
Once defined, you register it during your host startup:
Log.Logger = new LoggerConfiguration()
.Enrich.With(new ThreadIdEnricher())
.WriteTo.Console()
.CreateLogger();
Why This Matters for Performance
Because this happens inside the logging pipeline, it avoids modifying the code paths that handle your actual business logic. By automating the injection of diagnostic metadata, you ensure that even when developers forget to include critical state information, your structured logs maintain a consistent schema. This consistency is vital when you later perform log aggregation or feed these events into machine analytics platforms, as your queries will rely on these stable, pre-defined property keys rather than parsing unstructured message strings.
Key Takeaway: Custom log enrichers abstract the injection of contextual metadata, ensuring your logs remain rich, searchable, and consistent without requiring repetitive boilerplate code in your application layer.