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

Add ToOtlpLog unit tests for scopes (cont.) #4578

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.
// </copyright>

using System.Collections.ObjectModel;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
Expand Down Expand Up @@ -846,6 +847,244 @@ public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_ContainsScopeAttributeDoubl
Assert.Equal(scopeValue.ToString(), actualScope.Value.DoubleValue.ToString());
}

[Fact]
public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfTypeString_ScopeIsIgnored()
{
// Arrange.
var logRecords = new List<LogRecord>(1);
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.AddInMemoryExporter(logRecords);
});
});
var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests));

const string scopeState = "Some scope state";

// Act.
using (logger.BeginScope(scopeState))
{
logger.LogInformation("Some log information message.");
}

// Assert.
var logRecord = logRecords.Single();
var otlpLogRecord = logRecord.ToOtlpLog(DefaultSdkLimitOptions);
Assert.NotNull(otlpLogRecord);
Assert.Single(otlpLogRecord.Attributes);
}

[Theory]
[InlineData(typeof(int))]
[InlineData(typeof(float))]
[InlineData(typeof(decimal))]
[InlineData(typeof(char))]
[InlineData(typeof(bool))]
public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfPrimitiveTypes_ScopeIsIgnored(Type typeOfScopeState)
{
// Arrange.
var logRecords = new List<LogRecord>(1);
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.AddInMemoryExporter(logRecords);
});
});
var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests));

var scopeState = Activator.CreateInstance(typeOfScopeState);

// Act.
using (logger.BeginScope(scopeState))
{
logger.LogInformation("Some log information message.");
}

// Assert.
var logRecord = logRecords.Single();
var otlpLogRecord = logRecord.ToOtlpLog(DefaultSdkLimitOptions);
Assert.NotNull(otlpLogRecord);
Assert.Single(otlpLogRecord.Attributes);
}

[Fact]
public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfDictionaryType_ScopeIsProcessed()
{
// Arrange.
var logRecords = new List<LogRecord>(1);
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.AddInMemoryExporter(logRecords);
});
});
var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests));

const string scopeKey = "Some scope key";
var scopeState = new Dictionary<string, object>() { { scopeKey, "Some scope value" } };

// Act.
using (logger.BeginScope(scopeState))
{
logger.LogInformation("Some log information message.");
}

// Assert.
var logRecord = logRecords.Single();
var otlpLogRecord = logRecord.ToOtlpLog(DefaultSdkLimitOptions);
var actualScope = TryGetAttribute(otlpLogRecord, scopeKey);
Assert.NotNull(actualScope);
Assert.Equal(scopeKey, actualScope.Key);
mfogliatto marked this conversation as resolved.
Show resolved Hide resolved
mfogliatto marked this conversation as resolved.
Show resolved Hide resolved
}

[Theory]
[InlineData(typeof(List<KeyValuePair<string, object>>))]
[InlineData(typeof(ReadOnlyCollection<KeyValuePair<string, object>>))]
[InlineData(typeof(HashSet<KeyValuePair<string, object>>))]
public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeStateIsOfEnumerableType_ScopeIsProcessed(Type typeOfScopeState)
{
// Arrange.
var logRecords = new List<LogRecord>(1);
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.AddInMemoryExporter(logRecords);
});
});
var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests));

const string scopeKey = "Some scope key";
var scopeValues = new List<KeyValuePair<string, object>> { new KeyValuePair<string, object>(scopeKey, "Some scope value") };
var scopeState = Activator.CreateInstance(typeOfScopeState, scopeValues) as ICollection<KeyValuePair<string, object>>;

// Act.
using (logger.BeginScope(scopeState))
{
logger.LogInformation("Some log information message.");
}

// Assert.
var logRecord = logRecords.Single();
var otlpLogRecord = logRecord.ToOtlpLog(DefaultSdkLimitOptions);
var actualScope = TryGetAttribute(otlpLogRecord, scopeKey);
Assert.NotNull(actualScope);
Assert.Equal(scopeKey, actualScope.Key);
}

[Fact]
public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndMultipleScopesWithSameKeyAreAdded_ContainsAllAddedScopeValues()
{
// Arrange.
var logRecords = new List<LogRecord>(1);
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.AddInMemoryExporter(logRecords);
});
});
var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests));

const string scopeKey = "Some scope key";

// Act.
using (logger.BeginScope(new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>(scopeKey, "Some scope value"),
new KeyValuePair<string, object>(scopeKey, "Some other scope value"),
}))
{
logger.LogInformation("Some log information message.");
}

// Assert.
var logRecord = logRecords.Single();
var otlpLogRecord = logRecord.ToOtlpLog(DefaultSdkLimitOptions);
var scopeAttributesCount = otlpLogRecord.Attributes.Count(_ => _.Key == scopeKey);
mfogliatto marked this conversation as resolved.
Show resolved Hide resolved
Assert.Equal(2, scopeAttributesCount);
}

[Fact]
public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndMultpleScopeLevelsWithSameKeyAreAdded_ContainsAllAddedScopeValues()
mfogliatto marked this conversation as resolved.
Show resolved Hide resolved
{
// Arrange.
var logRecords = new List<LogRecord>(1);
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.AddInMemoryExporter(logRecords);
});
});
var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests));

const string scopeKey = "Some scope key";

// Act.
using (logger.BeginScope(new List<KeyValuePair<string, object>> { new KeyValuePair<string, object>(scopeKey, "Some scope value") }))
utpilla marked this conversation as resolved.
Show resolved Hide resolved
{
using (logger.BeginScope(new List<KeyValuePair<string, object>> { new KeyValuePair<string, object>(scopeKey, "Some scope value") }))
{
logger.LogInformation("Some log information message.");
}
}

// Assert.
var logRecord = logRecords.Single();
var otlpLogRecord = logRecord.ToOtlpLog(DefaultSdkLimitOptions);
var scopeAttributesCount = otlpLogRecord.Attributes.Count(_ => _.Key == scopeKey);
Assert.Equal(2, scopeAttributesCount);
}

[Fact]
public void ToOtlpLog_WhenOptionsIncludeScopesIsTrue_AndScopeWithExistingKeyIsUsedInLogMethod_ContainsAllAddedScopeValues()
{
// Arrange.
var logRecords = new List<LogRecord>(1);
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.IncludeScopes = true;
options.AddInMemoryExporter(logRecords);
});
});
var logger = loggerFactory.CreateLogger(nameof(OtlpLogExporterTests));

const string scopeKey = "Some scope key";

// Act.
using (logger.BeginScope(new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>(scopeKey, "Some scope value"),
}))
{
logger.Log(
LogLevel.Error,
new EventId(1),
new List<KeyValuePair<string, object>> { new KeyValuePair<string, object>(scopeKey, "Some other scope value") },
exception: new Exception("Some exception message"),
formatter: (s, e) => string.Empty);
}

// Assert.
var logRecord = logRecords.Single();
var otlpLogRecord = logRecord.ToOtlpLog(DefaultSdkLimitOptions);
var scopeAttributesCount = otlpLogRecord.Attributes.Count(_ => _.Key == scopeKey);
Assert.Equal(2, scopeAttributesCount);
}

private static OtlpCommon.KeyValue TryGetAttribute(OtlpLogs.LogRecord record, string key)
{
return record.Attributes.FirstOrDefault(att => att.Key == key);
Expand Down