Skip to content

Commit

Permalink
ILogger provider populates structured logging key/values irrespective… (
Browse files Browse the repository at this point in the history
#2078)

* ILogger provider populates structured logging key/values irrespective of whether Scopes are enabled or not

* comment
  • Loading branch information
cijothomas authored Oct 4, 2020
1 parent 507a2d7 commit 81288f2
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## VNext
- [ILogger LogError and LogWarning variants write exception `ExceptionStackTrace` when `TrackExceptionsAsExceptionTelemetry` flag is set to `false`](https://github.com/microsoft/ApplicationInsights-dotnet/pull/2065)
- [The `{OriginalFormat}` field in ILogger will be emitted as `OriginalFormat` with the braces removed](https://github.com/microsoft/ApplicationInsights-dotnet/pull/2071)
- ApplicationInsightsLoggerProvider populates structured logging key/values irrespective of whether Scopes are enabled or not.

## Version 2.15.0
- EventCounterCollector module does not add AggregationInterval as a dimension to the metric.
Expand Down
24 changes: 12 additions & 12 deletions LOGGING/src/ILogger/ApplicationInsightsLogger.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// -----------------------------------------------------------------------
// <copyright file="ApplicationInsightsLogger.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// All rights reserved. 2013
// </copyright>
// -----------------------------------------------------------------------
Expand Down Expand Up @@ -168,23 +168,23 @@ private void PopulateTelemetry<TState>(ISupportProperties telemetryItem, TState
dict["EventName"] = eventId.Name;
}

if (this.applicationInsightsLoggerOptions.IncludeScopes)
if (state is IReadOnlyCollection<KeyValuePair<string, object>> stateDictionary)
{
if (state is IReadOnlyCollection<KeyValuePair<string, object>> stateDictionary)
foreach (KeyValuePair<string, object> item in stateDictionary)
{
foreach (KeyValuePair<string, object> item in stateDictionary)
if (item.Key == "{OriginalFormat}")
{
if (item.Key == "{OriginalFormat}")
{
dict["OriginalFormat"] = Convert.ToString(item.Value, CultureInfo.InvariantCulture);
}
else
{
dict[item.Key] = Convert.ToString(item.Value, CultureInfo.InvariantCulture);
}
dict["OriginalFormat"] = Convert.ToString(item.Value, CultureInfo.InvariantCulture);
}
else
{
dict[item.Key] = Convert.ToString(item.Value, CultureInfo.InvariantCulture);
}
}
}

if (this.applicationInsightsLoggerOptions.IncludeScopes)
{
if (this.ExternalScopeProvider != null)
{
StringBuilder stringBuilder = new StringBuilder();
Expand Down
52 changes: 50 additions & 2 deletions LOGGING/test/ILogger.Tests/ILoggerIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,54 @@ namespace Microsoft.ApplicationInsights
[TestClass]
public class ILoggerIntegrationTests
{
/// <summary>
/// Ensures that <see cref="ApplicationInsightsLogger"/> populates params for structured logging into custom properties <see cref="ILogger"/>.
/// </summary>
[TestMethod]
[TestCategory("ILogger")]
public void ApplicationInsightsLoggerPopulateStructureLoggingParamsIntoCustomProperties()
{
List<ITelemetry> itemsReceived = new List<ITelemetry>();

// Scopes are enabled.
IServiceProvider serviceProvider = ILoggerIntegrationTests.SetupApplicationInsightsLoggerIntegration(
(telemetryItem, telemetryProcessor) => itemsReceived.Add(telemetryItem),
configureTelemetryConfiguration: null,
configureApplicationInsightsOptions: (appInsightsLoggerOptions) => appInsightsLoggerOptions.IncludeScopes = true);

ILogger<ILoggerIntegrationTests> testLogger = serviceProvider.GetRequiredService<ILogger<ILoggerIntegrationTests>>();
testLogger.LogInformation("Testing structured with {CustomerName} {Age}", "TestCustomerName", 20);

Assert.AreEqual("Testing structured with TestCustomerName 20", (itemsReceived[0] as TraceTelemetry).Message);
var customProperties = (itemsReceived[0] as TraceTelemetry).Properties;
Assert.IsTrue(customProperties["CustomerName"].Equals("TestCustomerName"));
Assert.IsTrue(customProperties["Age"].Equals("20"));
}

/// <summary>
/// Ensures that <see cref="ApplicationInsightsLogger"/> populates params for structured logging into custom properties <see cref="ILogger"/>.
/// </summary>
[TestMethod]
[TestCategory("ILogger")]
public void ApplicationInsightsLoggerPopulateStructureLoggingParamsIntoCustomPropertiesWhenScopeDisabled()
{
List<ITelemetry> itemsReceived = new List<ITelemetry>();

// Disable scope
IServiceProvider serviceProvider = ILoggerIntegrationTests.SetupApplicationInsightsLoggerIntegration(
(telemetryItem, telemetryProcessor) => itemsReceived.Add(telemetryItem),
configureTelemetryConfiguration: null,
configureApplicationInsightsOptions: (appInsightsLoggerOptions) => appInsightsLoggerOptions.IncludeScopes = false);

ILogger<ILoggerIntegrationTests> testLogger = serviceProvider.GetRequiredService<ILogger<ILoggerIntegrationTests>>();
testLogger.LogInformation("Testing structured with {CustomerName} {Age}", "TestCustomerName", 20);

Assert.AreEqual("Testing structured with TestCustomerName 20", (itemsReceived[0] as TraceTelemetry).Message);
var customProperties = (itemsReceived[0] as TraceTelemetry).Properties;
Assert.IsTrue(customProperties["CustomerName"].Equals("TestCustomerName"));
Assert.IsTrue(customProperties["Age"].Equals("20"));
}

/// <summary>
/// Ensures that <see cref="ApplicationInsightsLogger"/> is invoked when user logs using <see cref="ILogger"/>.
/// </summary>
Expand Down Expand Up @@ -142,7 +190,7 @@ public void ApplicationInsightsLoggerLogsExceptionAsTraceWhenSwitchIsFalse()

Assert.AreEqual(SeverityLevel.Error, (itemsReceived[1] as TraceTelemetry).SeverityLevel);
Assert.AreEqual("LoggerMessage", (itemsReceived[1] as TraceTelemetry).Message);

Assert.IsTrue((itemsReceived[1] as TraceTelemetry).Properties["ExceptionMessage"].Contains("StackTraceEnabled"));

Assert.IsTrue((itemsReceived[1] as TraceTelemetry).Properties.ContainsKey("ExceptionStackTrace"));
Expand Down Expand Up @@ -263,7 +311,7 @@ public void DefaultLoggerOptionsAreCorrectlyRegistered()
IServiceProvider serviceProvider = ILoggerIntegrationTests.SetupApplicationInsightsLoggerIntegration(
(telemetryItem, telemetryProcessor) => { });

IOptions<ApplicationInsightsLoggerOptions> registeredOptions =
IOptions<ApplicationInsightsLoggerOptions> registeredOptions =
serviceProvider.GetRequiredService<IOptions<ApplicationInsightsLoggerOptions>>();

Assert.IsTrue(registeredOptions.Value.TrackExceptionsAsExceptionTelemetry);
Expand Down

0 comments on commit 81288f2

Please sign in to comment.