Skip to content

Commit bd9f55a

Browse files
Adding process log enricher documentation (#49070)
* doc updates * toc update * fixes * updates * fixing reference * fix * fixing * added overview and custom enricher * fix * fixes * fix * fixing * fix again * adding nuget package reference * custom enricher * comments * rename * fix * Update custom-enricher.md * updates * fixing code blocks * fixing highlights * fix * Update process-log-enricher.md * fix * suggestions * suggestions * adding why in overview * fixes * fix --------- Co-authored-by: David Pine <[email protected]>
1 parent b3e1e8f commit bd9f55a

File tree

8 files changed

+316
-0
lines changed

8 files changed

+316
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
title: Custom log enricher
3+
description: Learn how to use the custom log enricher in .NET.
4+
ms.date: 10/13/2025
5+
---
6+
7+
# Custom log enricher
8+
9+
You can easily create a custom enricher by creating a class that implements the <xref:Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher> interface.
10+
After the class is created, you register it with <xref:Microsoft.Extensions.DependencyInjection.EnrichmentServiceCollectionExtensions.AddLogEnricher(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher)>.
11+
Once registered, the logging infrastructure automatically calls the `Enrich()` method exactly once on every registered enricher for each log message produced.
12+
13+
## Install the package
14+
15+
To get started, install the [📦 Microsoft.Extensions.Telemetry.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions) NuGet package:
16+
17+
### [.NET CLI](#tab/dotnet-cli)
18+
19+
```dotnetcli
20+
dotnet add package Microsoft.Extensions.Telemetry.Abstractions
21+
```
22+
23+
Or, if you're using .NET 10+ SDK:
24+
25+
```dotnetcli
26+
dotnet package add Microsoft.Extensions.Telemetry.Abstractions
27+
```
28+
29+
### [PackageReference](#tab/package-reference)
30+
31+
```xml
32+
<PackageReference Include="Microsoft.Extensions.Telemetry.Abstractions"
33+
Version="*" /> <!-- Adjust version -->
34+
```
35+
36+
---
37+
38+
## Implementation
39+
40+
Your custom enricher only needs to implement a single <xref:Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher.Enrich(Microsoft.Extensions.Diagnostics.Enrichment.IEnrichmentTagCollector)> method.
41+
During enrichment, this method is called and given an <xref:Microsoft.Extensions.Diagnostics.Enrichment.IEnrichmentTagCollector> instance. The enricher then calls one of the overloads of
42+
the <xref:Microsoft.Extensions.Diagnostics.Enrichment.IEnrichmentTagCollector.Add(System.String,System.Object)> method to record any properties it wants.
43+
44+
> [!NOTE]
45+
> If your custom log enricher calls <xref:Microsoft.Extensions.Diagnostics.Enrichment.IEnrichmentTagCollector.Add(System.String,System.Object)>,
46+
> it is acceptable to send any type of argument to the `value` parameter as is, because it is parsed into the actual type and serialized internally
47+
> to be sent further down the logging pipeline.
48+
49+
```csharp
50+
public class CustomEnricher : ILogEnricher
51+
{
52+
public void Enrich(IEnrichmentTagCollector collector)
53+
{
54+
collector.Add("customKey", "customValue");
55+
}
56+
}
57+
58+
```
59+
60+
And you register it as shown in the following code using <xref:Microsoft.Extensions.DependencyInjection.EnrichmentServiceCollectionExtensions.AddLogEnricher``1(Microsoft.Extensions.DependencyInjection.IServiceCollection)>:
61+
62+
```csharp
63+
var builder = Host.CreateApplicationBuilder(args);
64+
builder.Logging.EnableEnrichment();
65+
builder.Services.AddLogEnricher<CustomEnricher>();
66+
```
67+
68+
It's also possible to configure manual instantiation of custom enrichers:
69+
70+
```csharp
71+
public class AnotherEnricher : ILogEnricher
72+
{
73+
private readonly string _key;
74+
private readonly object _value;
75+
public CustomEnricher(string key, object value)
76+
{
77+
_key = key;
78+
_value = value;
79+
}
80+
public void Enrich(IEnrichmentTagCollector collector)
81+
{
82+
collector.Add(_key, _value);
83+
}
84+
}
85+
```
86+
87+
And you register it as shown in the following code <xref:Microsoft.Extensions.DependencyInjection.EnrichmentServiceCollectionExtensions.AddLogEnricher(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher)>:
88+
89+
```csharp
90+
var builder = Host.CreateApplicationBuilder();
91+
builder.Logging.EnableEnrichment();
92+
builder.Services.AddLogEnricher(new AnotherEnricher("anotherKey", "anotherValue"));
93+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"EventId": 0,
3+
"LogLevel": "Information",
4+
"Category": "Enrichment.Program",
5+
"Message": "This is a sample log message",
6+
"State": {
7+
"Message": "This is a sample log message",
8+
"process.pid": "12924",
9+
"thread.id": "2",
10+
"{OriginalFormat}": "This is a sample log message"
11+
}
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"EventId": 0,
3+
"LogLevel": "Information",
4+
"Category": "Enrichment.Program",
5+
"Message": "This is a sample log message",
6+
"State": {
7+
"Message": "This is a sample log message",
8+
"process.pid": "10696",
9+
"{OriginalFormat}": "This is a sample log message"
10+
}
11+
}

docs/core/enrichment/overview.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
title: Log enrichment overview
3+
description: Learn about log enrichment in .NET and how to enhance your logs with contextual information.
4+
ms.date: 10/13/2025
5+
---
6+
7+
# Overview
8+
9+
Log enrichment is a powerful feature that automatically attaches contextual information to your application's logs. Instead of manually adding metadata to each log, enrichment provides a systematic way to inject relevant context automatically across your entire application.
10+
11+
## What is enrichment?
12+
13+
Enrichment augments telemetry objects with additional information that provides valuable context about the environment, application state, and execution context when the telemetry was generated. This contextual data helps with debugging, monitoring, performance analysis, and understanding application behavior in production environments.
14+
15+
## Why is enrichment important?
16+
17+
Enrichment plays a critical role in enhancing observability and diagnostics by adding standardized contextual information—such as process details, environment tags, or user identifiers—to telemetry data. This additional metadata transforms raw logs into structured, meaningful insights, making it easier to trace issues, correlate events, and improve application reliability. By enabling enrichment and configuring specific enrichers, teams can streamline troubleshooting, optimize performance monitoring, and ensure compliance with operational standards. Ultimately, enrichment is not just a technical add-on; it’s a foundational practice for building resilient, transparent systems that support informed decision-making and faster incident resolution.
18+
19+
## How enrichment works
20+
21+
The enrichment framework operates through a collection of enrichers that are registered with the dependency injection container. When telemetry is generated, all registered enrichers automatically contribute their contextual information to the telemetry payload. You just register the specific set of enrichers you want into an <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection> instance. The enrichers run automatically without requiring changes to your application code. You simply configure which enrichers you want to use during application startup.
22+
23+
## Dimension names and tags
24+
25+
Enrichers add information to telemetry using standardized dimension names (also called tags or keys).
26+
27+
## Setting up enrichment
28+
29+
To use log enrichment in your application, you need to:
30+
31+
1. **Enable enrichment** for logging.
32+
2. **Register specific enrichers** you want to use.
33+
3. **Configure options** for each enricher (optional).
34+
35+
### Basic setup example
36+
37+
Here's a simple example showing how to set up log enrichment with process information:
38+
39+
:::code language="csharp" source="snippets/enrichment/Program.cs" highlight="8,9":::
40+
41+
This configuration:
42+
43+
- Enables enrichment for logging via `EnableEnrichment()`.
44+
- Registers the process log enricher via `AddProcessLogEnricher()`.
45+
- Configures JSON console output to display the enriched data.
46+
47+
### Output example
48+
49+
With enrichment enabled, your log output will automatically include additional contextual information:
50+
51+
:::code language="json" source="json-output.json" highlight="8":::
52+
53+
## Available enrichers
54+
55+
The .NET enrichment framework provides some built-in enrichers, like:
56+
57+
- **[Process enricher](process-log-enricher.md)**: Process and thread information
58+
59+
## Custom enrichers
60+
61+
If the built-in enrichers don't meet your specific needs, you can create custom enrichers to add application-specific context. For more information, check [custom enrichment](custom-enricher.md).
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
title: Process log enricher
3+
description: Learn how to use the process log enricher in .NET.
4+
ms.date: 10/10/2025
5+
---
6+
7+
# Process log enricher
8+
9+
The process enricher augments telemetry logs with process-specific information.
10+
11+
You can register the enrichers in an IoC container. Then, all registered enrichers are picked up automatically by the respective telemetry instances, such as logs or metrics, where they enrich the telemetry information.
12+
13+
## Install the package
14+
15+
To get started, install the [📦 Microsoft.Extensions.Telemetry](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry) NuGet package:
16+
17+
### [.NET CLI](#tab/dotnet-cli)
18+
19+
```dotnetcli
20+
dotnet add package Microsoft.Extensions.Telemetry
21+
```
22+
23+
Or, if you're using .NET 10+ SDK:
24+
25+
```dotnetcli
26+
dotnet package add Microsoft.Extensions.Telemetry
27+
```
28+
29+
### [PackageReference](#tab/package-reference)
30+
31+
```xml
32+
<PackageReference Include="Microsoft.Extensions.Telemetry"
33+
Version="*" /> <!-- Adjust version -->
34+
```
35+
36+
---
37+
38+
## Usage
39+
40+
To use the process log enricher, first you enable enrichment. Then you can add the <xref:Microsoft.Extensions.DependencyInjection.ProcessEnricherServiceCollectionExtensions.AddProcessLogEnricher*> with default properties, as shown in the following code:
41+
42+
:::code language="csharp" source="snippets/enrichment/Program.cs" highlight="8,9":::
43+
44+
Given this code sample, the output should be similar to the following JSON:
45+
46+
:::code language="json" source="json-output.json" highlight="8":::
47+
48+
## `ProcessLogEnricherOptions`
49+
50+
The <xref:Microsoft.Extensions.Diagnostics.Enrichment.ProcessLogEnricherOptions> class provides fine-grained control over which process-related properties are included in your log enrichment. This options class allows you to selectively enable or disable specific enrichment features such as process ID and thread ID information. Although default properties are supplied by the process enricher, you can customize them by initializing an instance of <xref:Microsoft.Extensions.Diagnostics.Enrichment.ProcessLogEnricherOptions> and providing it when registering the enricher.
51+
52+
You can enable or disable individual options of the enricher using <xref:Microsoft.Extensions.DependencyInjection.ProcessEnricherServiceCollectionExtensions.AddProcessLogEnricher(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{Microsoft.Extensions.Diagnostics.Enrichment.ProcessLogEnricherOptions})>:
53+
54+
```csharp
55+
serviceCollection.AddProcessLogEnricher(options =>
56+
{
57+
options.ThreadId = true;
58+
options.ProcessId = true;
59+
});
60+
```
61+
62+
You may also disable or enable individual options using _appsettings.json_ file configuration, for example:
63+
64+
```json
65+
{
66+
"ProcessLogEnricherOptions": {
67+
"ThreadId": true,
68+
"ProcessId": true
69+
}
70+
}
71+
```
72+
73+
and apply it accordingly using <xref:Microsoft.Extensions.DependencyInjection.ProcessEnricherServiceCollectionExtensions.AddProcessLogEnricher(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfigurationSection)>:
74+
75+
```csharp
76+
serviceCollection.AddProcessLogEnricher(
77+
hostBuilder.Configuration.GetSection("ProcessLogEnricherOptions"));
78+
```
79+
80+
The console output after enabling both options should look like this:
81+
82+
:::code language="json" source="json-output-all-enabled.json" highlight="8,9":::
83+
84+
## Default configuration
85+
86+
The default configuration for process log enrichment is:
87+
88+
| Property | Default Value | Description |
89+
|-------------|---------------|---------------------------------------------------------|
90+
| `ProcessId` | `true` | If true, logs are enriched with the current process ID. |
91+
| `ThreadId` | `false` | If true, logs are enriched with the current thread ID |
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.9" />
12+
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.9" />
13+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.9" />
14+
<PackageReference Include="Microsoft.Extensions.Telemetry" Version="9.9.0" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Text.Json;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.Hosting;
4+
using Microsoft.Extensions.Logging;
5+
6+
var builder = Host.CreateApplicationBuilder(args);
7+
8+
builder.Logging.EnableEnrichment();
9+
builder.Services.AddProcessLogEnricher();
10+
11+
builder.Logging.AddJsonConsole(op =>
12+
{
13+
op.JsonWriterOptions = new JsonWriterOptions
14+
{
15+
Indented = true
16+
};
17+
});
18+
19+
var host = builder.Build();
20+
var logger = host.Services.GetRequiredService<ILogger<Program>>();
21+
22+
logger.LogInformation("This is a sample log message");
23+
await host.RunAsync();

docs/navigate/tools-diagnostics/toc.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,14 @@ items:
446446
href: ../../core/diagnostics/distributed-tracing-collection-walkthroughs.md
447447
- name: Built-in activities
448448
href: ../../core/diagnostics/distributed-tracing-builtin-activities.md
449+
- name: Enrichment
450+
items:
451+
- name: Overview
452+
href: ../../core/enrichment/overview.md
453+
- name: Process log enricher
454+
href: ../../core/enrichment/process-log-enricher.md
455+
- name: Custom enricher
456+
href: ../../core/enrichment/custom-enricher.md
449457
- name: Specialized diagnostics
450458
items:
451459
- name: Overview

0 commit comments

Comments
 (0)