Skip to content

Commit 210bc8a

Browse files
CopilotIEvangelist
andcommitted
Add conceptual articles for new .NET Extensions packages
Co-authored-by: IEvangelist <[email protected]>
1 parent da8dc81 commit 210bc8a

File tree

6 files changed

+1559
-0
lines changed

6 files changed

+1559
-0
lines changed
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
---
2+
title: Application ambient metadata
3+
description: Learn how to capture and flow application metadata for telemetry enrichment using Microsoft.Extensions.AmbientMetadata.Application in .NET.
4+
author: IEvangelist
5+
ms.author: dapine
6+
ms.date: 10/20/2025
7+
ms.topic: concept-article
8+
ai-usage: ai-assisted
9+
---
10+
11+
# Application ambient metadata
12+
13+
The [`Microsoft.Extensions.AmbientMetadata.Application`](https://www.nuget.org/packages/Microsoft.Extensions.AmbientMetadata.Application) NuGet package provides functionality to capture and flow application-level ambient metadata throughout your application. This metadata includes information such as the application name, version, deployment environment, and deployment ring, which is valuable for enriching telemetry, troubleshooting, and analysis.
14+
15+
## Why use application metadata
16+
17+
Application metadata provides essential context about your running application that can enhance observability:
18+
19+
- **Telemetry enrichment**: Automatically add application details to logs, metrics, and traces.
20+
- **Troubleshooting**: Quickly identify which version of your application is experiencing issues.
21+
- **Environment identification**: Distinguish between Development, Staging, and Production environments in your telemetry.
22+
- **Deployment tracking**: Track issues across different deployment rings or regions.
23+
- **Consistent metadata**: Ensure all components in your application use the same metadata values.
24+
25+
## Get started
26+
27+
To get started with application metadata, install the [`Microsoft.Extensions.AmbientMetadata.Application`](https://www.nuget.org/packages/Microsoft.Extensions.AmbientMetadata.Application) NuGet package.
28+
29+
### [.NET CLI](#tab/dotnet-cli)
30+
31+
```dotnetcli
32+
dotnet add package Microsoft.Extensions.AmbientMetadata.Application
33+
```
34+
35+
### [PackageReference](#tab/package-reference)
36+
37+
```xml
38+
<PackageReference Include="Microsoft.Extensions.AmbientMetadata.Application" Version="9.10.0" />
39+
```
40+
41+
---
42+
43+
For more information, see [dotnet add package](../tools/dotnet-add-package.md) or [Manage package dependencies in .NET applications](../tools/dependencies.md).
44+
45+
## Configure application metadata
46+
47+
Application metadata can be configured through your application's configuration system. The package looks for metadata under the `ambientmetadata:application` configuration section by default.
48+
49+
### Configure with appsettings.json
50+
51+
Add the application metadata to your `appsettings.json` file:
52+
53+
```json
54+
{
55+
"ambientmetadata": {
56+
"application": {
57+
"ApplicationName": "MyWebApi",
58+
"BuildVersion": "1.0.0",
59+
"DeploymentRing": "Production",
60+
"EnvironmentName": "Production"
61+
}
62+
}
63+
}
64+
```
65+
66+
### Configure with IHostBuilder
67+
68+
Use the <xref:Microsoft.Extensions.Hosting.ApplicationMetadataHostBuilderExtensions.UseApplicationMetadata%2A> extension method to register application metadata:
69+
70+
```csharp
71+
using Microsoft.Extensions.Hosting;
72+
73+
var builder = Host.CreateApplicationBuilder(args);
74+
75+
builder.UseApplicationMetadata();
76+
77+
var host = builder.Build();
78+
79+
await host.RunAsync();
80+
```
81+
82+
### Configure with IHostApplicationBuilder
83+
84+
For applications using <xref:Microsoft.Extensions.Hosting.IHostApplicationBuilder>, such as ASP.NET Core applications:
85+
86+
```csharp
87+
using Microsoft.AspNetCore.Builder;
88+
using Microsoft.Extensions.Hosting;
89+
90+
var builder = WebApplication.CreateBuilder(args);
91+
92+
builder.UseApplicationMetadata();
93+
94+
var app = builder.Build();
95+
96+
app.MapGet("/", () => "Hello World!");
97+
98+
app.Run();
99+
```
100+
101+
## Access application metadata
102+
103+
Once configured, you can inject and use the <xref:Microsoft.Extensions.AmbientMetadata.ApplicationMetadata> type:
104+
105+
```csharp
106+
using Microsoft.Extensions.AmbientMetadata;
107+
using Microsoft.Extensions.DependencyInjection;
108+
using Microsoft.Extensions.Hosting;
109+
110+
var builder = Host.CreateApplicationBuilder(args);
111+
112+
builder.UseApplicationMetadata();
113+
builder.Services.AddSingleton<MetadataService>();
114+
115+
var host = builder.Build();
116+
117+
var metadataService = host.Services.GetRequiredService<MetadataService>();
118+
metadataService.DisplayMetadata();
119+
120+
public class MetadataService
121+
{
122+
private readonly ApplicationMetadata _metadata;
123+
124+
public MetadataService(ApplicationMetadata metadata)
125+
{
126+
_metadata = metadata;
127+
}
128+
129+
public void DisplayMetadata()
130+
{
131+
Console.WriteLine($"Application: {_metadata.ApplicationName}");
132+
Console.WriteLine($"Version: {_metadata.BuildVersion}");
133+
Console.WriteLine($"Environment: {_metadata.EnvironmentName}");
134+
Console.WriteLine($"Deployment Ring: {_metadata.DeploymentRing}");
135+
}
136+
}
137+
```
138+
139+
## ApplicationMetadata properties
140+
141+
The <xref:Microsoft.Extensions.AmbientMetadata.ApplicationMetadata> class includes the following properties:
142+
143+
| Property | Description |
144+
|----------|-------------|
145+
| `ApplicationName` | The name of the application. |
146+
| `BuildVersion` | The version of the application build. |
147+
| `DeploymentRing` | The deployment ring or stage (for example, Canary, Production). |
148+
| `EnvironmentName` | The environment where the application is running (for example, Development, Staging, Production). |
149+
150+
## Use with logging
151+
152+
Application metadata is particularly useful for enriching log messages:
153+
154+
```csharp
155+
using Microsoft.Extensions.AmbientMetadata;
156+
using Microsoft.Extensions.DependencyInjection;
157+
using Microsoft.Extensions.Hosting;
158+
using Microsoft.Extensions.Logging;
159+
160+
var builder = Host.CreateApplicationBuilder(args);
161+
162+
builder.UseApplicationMetadata();
163+
builder.Services.AddSingleton<LoggingService>();
164+
165+
var host = builder.Build();
166+
167+
var loggingService = host.Services.GetRequiredService<LoggingService>();
168+
loggingService.LogWithMetadata();
169+
170+
public class LoggingService
171+
{
172+
private readonly ILogger<LoggingService> _logger;
173+
private readonly ApplicationMetadata _metadata;
174+
175+
public LoggingService(ILogger<LoggingService> logger, ApplicationMetadata metadata)
176+
{
177+
_logger = logger;
178+
_metadata = metadata;
179+
}
180+
181+
public void LogWithMetadata()
182+
{
183+
_logger.LogInformation(
184+
"Processing request in {ApplicationName} v{Version} ({Environment})",
185+
_metadata.ApplicationName,
186+
_metadata.BuildVersion,
187+
_metadata.EnvironmentName);
188+
}
189+
}
190+
```
191+
192+
## Custom configuration section
193+
194+
If you prefer to use a different configuration section name, specify it when calling `UseApplicationMetadata`:
195+
196+
```csharp
197+
using Microsoft.Extensions.Hosting;
198+
199+
var builder = Host.CreateApplicationBuilder(args);
200+
201+
// Use custom configuration section
202+
builder.UseApplicationMetadata("myapp:metadata");
203+
204+
var host = builder.Build();
205+
206+
await host.RunAsync();
207+
```
208+
209+
With this configuration, your settings would look like:
210+
211+
```json
212+
{
213+
"myapp": {
214+
"metadata": {
215+
"ApplicationName": "MyWebApi",
216+
"BuildVersion": "1.0.0",
217+
"DeploymentRing": "Production",
218+
"EnvironmentName": "Production"
219+
}
220+
}
221+
}
222+
```
223+
224+
## Environment-specific configuration
225+
226+
You can provide different metadata for different environments using environment-specific configuration files:
227+
228+
**appsettings.Development.json**:
229+
230+
```json
231+
{
232+
"ambientmetadata": {
233+
"application": {
234+
"ApplicationName": "MyWebApi",
235+
"BuildVersion": "1.0.0-dev",
236+
"DeploymentRing": "Development",
237+
"EnvironmentName": "Development"
238+
}
239+
}
240+
}
241+
```
242+
243+
**appsettings.Production.json**:
244+
245+
```json
246+
{
247+
"ambientmetadata": {
248+
"application": {
249+
"ApplicationName": "MyWebApi",
250+
"BuildVersion": "1.0.0",
251+
"DeploymentRing": "Production",
252+
"EnvironmentName": "Production"
253+
}
254+
}
255+
}
256+
```
257+
258+
## Practical example: Telemetry enrichment
259+
260+
Here's a complete example showing how to use application metadata to enrich telemetry in an ASP.NET Core application:
261+
262+
```csharp
263+
using Microsoft.AspNetCore.Builder;
264+
using Microsoft.Extensions.AmbientMetadata;
265+
using Microsoft.Extensions.DependencyInjection;
266+
using Microsoft.Extensions.Hosting;
267+
using Microsoft.Extensions.Logging;
268+
269+
var builder = WebApplication.CreateBuilder(args);
270+
271+
builder.UseApplicationMetadata();
272+
builder.Services.AddSingleton<TelemetryEnricher>();
273+
274+
var app = builder.Build();
275+
276+
app.Use(async (context, next) =>
277+
{
278+
var enricher = context.RequestServices.GetRequiredService<TelemetryEnricher>();
279+
enricher.EnrichRequest(context);
280+
await next();
281+
});
282+
283+
app.MapGet("/api/health", (ApplicationMetadata metadata) =>
284+
{
285+
return Results.Ok(new
286+
{
287+
Status = "Healthy",
288+
Application = metadata.ApplicationName,
289+
Version = metadata.BuildVersion,
290+
Environment = metadata.EnvironmentName
291+
});
292+
});
293+
294+
app.Run();
295+
296+
public class TelemetryEnricher
297+
{
298+
private readonly ILogger<TelemetryEnricher> _logger;
299+
private readonly ApplicationMetadata _metadata;
300+
301+
public TelemetryEnricher(
302+
ILogger<TelemetryEnricher> logger,
303+
ApplicationMetadata metadata)
304+
{
305+
_logger = logger;
306+
_metadata = metadata;
307+
}
308+
309+
public void EnrichRequest(HttpContext context)
310+
{
311+
using var scope = _logger.BeginScope(new Dictionary<string, object>
312+
{
313+
["ApplicationName"] = _metadata.ApplicationName ?? "Unknown",
314+
["BuildVersion"] = _metadata.BuildVersion ?? "Unknown",
315+
["Environment"] = _metadata.EnvironmentName ?? "Unknown",
316+
["DeploymentRing"] = _metadata.DeploymentRing ?? "Unknown",
317+
["RequestPath"] = context.Request.Path.Value ?? "Unknown"
318+
});
319+
320+
_logger.LogInformation("Request received");
321+
}
322+
}
323+
```
324+
325+
## Best practices
326+
327+
When using application metadata, consider the following best practices:
328+
329+
- **Automate version setting**: Use your CI/CD pipeline to automatically set the `BuildVersion` from your version control system or build number.
330+
- **Environment consistency**: Ensure environment names are consistent across all your applications for easier querying and filtering in telemetry systems.
331+
- **Configuration management**: Use environment-specific configuration files or environment variables to manage different metadata values across environments.
332+
- **Validate metadata**: Ensure required metadata fields are present during application startup to catch configuration issues early.
333+
- **Telemetry integration**: Integrate application metadata with your telemetry system (such as Application Insights or OpenTelemetry) for comprehensive observability.
334+
335+
## See also
336+
337+
- [Configuration in .NET](configuration.md)
338+
- [Configuration providers in .NET](configuration-providers.md)
339+
- [Logging in .NET](logging.md)
340+
- [Options pattern in .NET](options.md)

0 commit comments

Comments
 (0)