Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AzureMonitor] add Log Scopes example to Readme #44749

Merged
merged 14 commits into from
Jul 17, 2024
31 changes: 31 additions & 0 deletions sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,37 @@ The Azure Monitor Distro is a distribution package that facilitates users in sen

Refer to [`Program.cs`](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/tests/Azure.Monitor.OpenTelemetry.AspNetCore.Demo/Program.cs) for a complete demo.

### Log Scopes

Log scopes allow you to add additional properties to the logs generated by your application.
Although the Azure Monitor Exporter does support scopes, this feature is off by default in OpenTelemetry.
TimothyMothra marked this conversation as resolved.
Show resolved Hide resolved
To leverage log scopes, you must explicitly enable them.

To include the scope with your logs, set `OpenTelemetryLoggerOptions.IncludeScopes` to `true` in your application's configuration:
```csharp
builder.Services.Configure<OpenTelemetryLoggerOptions>(options =>
{
options.IncludeScopes = true;
});
```

Once enabled, you can define a scope using a dictionary or any enumerable of KeyValuePair<string, object>.
TimothyMothra marked this conversation as resolved.
Show resolved Hide resolved
All logs written within the context of the scope will include the specified information.
Azure Monitor will add these scope values to the Log's CustomProperties.
TimothyMothra marked this conversation as resolved.
Show resolved Hide resolved
```csharp
List<KeyValuePair<string, object>> scope =
[
new("scopeKey", "scopeValue")
];

using (logger.BeginScope(scope))
{
logger.LogInformation("Example message.");
}
```

Note that if you define nested scopes with the same key or multiple keyvaluepairs with the same key, only the first value will be set.
TimothyMothra marked this conversation as resolved.
Show resolved Hide resolved

## Troubleshooting

The Azure Monitor Distro uses EventSource for its own internal logging. The logs are available to any EventListener by opting into the source named "OpenTelemetry-AzureMonitor-Exporter".
Expand Down
36 changes: 34 additions & 2 deletions sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Azure Monitor Exporter client library for .NET



The [OpenTelemetry .NET](https://github.com/open-telemetry/opentelemetry-dotnet) exporters which send [telemetry data](https://docs.microsoft.com/azure/azure-monitor/app/data-model) to [Azure Monitor](https://docs.microsoft.com/azure/azure-monitor/app/app-insights-overview) following the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification).

## Getting started
Expand Down Expand Up @@ -135,6 +133,40 @@ For more information on the OpenTelemetry project, please review the [OpenTeleme

Refer to [`Program.cs`](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Demo/Program.cs) for a complete demo.

### Log Scopes

Log scopes allow you to add additional properties to the logs generated by your application.
Although the Azure Monitor Exporter does support scopes, this feature is off by default in OpenTelemetry.
To leverage log scopes, you must explicitly enable them.

To include the scope with your logs, set `OpenTelemetryLoggerOptions.IncludeScopes` to `true` in your application's configuration:
```csharp
var loggerFactory = LoggerFactory.Create(builder =>
TimothyMothra marked this conversation as resolved.
Show resolved Hide resolved
{
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
});
});
```

Once enabled, you can define a scope using a dictionary or any enumerable of KeyValuePair<string, object>.
All logs written within the context of the scope will include the specified information.
Azure Monitor will add these scope values to the Log's CustomProperties.
```csharp
List<KeyValuePair<string, object>> scope =
[
new("scopeKey", "scopeValue")
];

using (logger.BeginScope(scope))
{
logger.LogInformation("Example message.");
}
```

Note that if you define nested scopes with the same key or multiple keyvaluepairs with the same key, only the first value will be set.

## Troubleshooting

The Azure Monitor exporter uses EventSource for its own internal logging. The exporter logs are available to any EventListener by opting into the source named "OpenTelemetry-AzureMonitor-Exporter".
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,36 @@ public void VerifyLog(LogLevel logLevel, string expectedSeverityLevel)
.AddFilter<OpenTelemetryLoggerProvider>(logCategoryName, logLevel)
.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddAttributes(testResourceAttributes));
options.AddAzureMonitorLogExporterForTest(out telemetryItems);
});
});

// ACT
var logger = loggerFactory.CreateLogger(logCategoryName);
logger.Log(
logLevel: logLevel,
eventId: 0,
exception: null,
message: "Hello {name}.",
args: new object[] { "World" });

List<KeyValuePair<string, object>> scope1 = new()
{
new("scopeKey1", "scopeValue1"),
new("scopeKey1", "scopeValue2")
};

List<KeyValuePair<string, object>> scope2 = new()
{
new("scopeKey1", "scopeValue3")
};

using (logger.BeginScope(scope1))
using (logger.BeginScope(scope2))
{
logger.Log(
logLevel: logLevel,
eventId: 0,
TimothyMothra marked this conversation as resolved.
Show resolved Hide resolved
exception: null,
message: "Hello {name}.",
args: new object[] { "World" });
}

// CLEANUP
loggerFactory.Dispose();
Expand All @@ -83,7 +100,7 @@ public void VerifyLog(LogLevel logLevel, string expectedSeverityLevel)
telemetryItem: telemetryItem!,
expectedSeverityLevel: expectedSeverityLevel,
expectedMessage: "Hello {name}.",
expectedMessageProperties: new Dictionary<string, string> { { "name", "World" }},
expectedMessageProperties: new Dictionary<string, string> { { "name", "World" }, { "scopeKey1", "scopeValue1" } },
expectedSpanId: null,
expectedTraceId: null);
}
Expand Down
Loading