Skip to content

Enrichers

Thiago Vasconcelos edited this page Jan 23, 2026 · 2 revisions

An enricher is a hook that runs every time a log entry is emitted, immediately before the entry is queued and sent to the agent. It receives a mutable LogEntry instance and is expected to add or adjust metadata based on ambient state (request context, environment, async scope, etc.). An enricher is not optional sugar. Once registered, it is part of the logging hot path.

An enricher implements exactly one method:

public interface ILogEnricher
{
    void Enrich(LogEntry entry);
}

Do keep in mind this means that an enricher has to run synchronously and on the caller's thread.

Enrichers run right before sending the log to the agent, after every validation, normalization, filtering, etc. has been executed. Which means anything added by an enricher goes straight into the agent without any extra validation, which, while useful, can have some downsides if misused.

Enriching via Log Context

LogContext is a lightweight context propagation mechanism built on AsyncLocal. It stores arbitrary key/value pairs that are scoped to the current asynchronous execution flow.

Any code running within that scope can emit logs and automatically receive the same contextual metadata.

This is how request IDs, user IDs, correlation values, and similar data end up on every log without being passed through method signatures.

Pushing values into the context

Context is added using LogContext.Push:

using (LogContext.Push("UserId", userId))
{
    // all logs here include UserId
}

Nested Scopes

Scopes can be nested:

using (LogContext.Push("RequestId", requestId))
{
    using (LogContext.Push("UserId", userId))
    {
        // Metadata contains both RequestId and UserId
    }
}

Caution

Passing the same context key inside an inner scope will cause the original value to be overriden while inside that scope. The original value is restored when leaving scope.

Enriching via ILogEnricher implementations

Use the LogPortConfigClient.UseEnricher extension method. It takes any ILogEnricher and registers it into the client when it is constructed. Do keep in mind there is no protection on duplicate enrichers to allow for reusability.

var config = new LogPortClientConfig
{
    AgentUrl = "ws://localhost:8080",
    ServiceName = "MyService"
};

config.UseEnricher(new MyEnricher());

Clone this wiki locally