Skip to content

Commit

Permalink
[AzureMonitorExporter] minor test improvements. add additional loggin…
Browse files Browse the repository at this point in the history
…g to `TelemetryItems` tests (Azure#31557)

* investigating test failures

* additional logs

* fix

* add spanId missing from Trace tests

* change LogExporterForTest to use SimpleLogRecordExportProcessor

* mitigate test by using .First()
  • Loading branch information
TimothyMothra authored and sofiar-msft committed Dec 7, 2022
1 parent 7468fd2 commit 9887ea0
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal static OpenTelemetryLoggerOptions AddAzureMonitorLogExporterForTest(thi

telemetryItems = new ConcurrentBag<TelemetryItem>();

return loggerOptions.AddProcessor(new BatchLogRecordExportProcessor(new AzureMonitorLogExporter(new MockTransmitter(telemetryItems))));
return loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(new AzureMonitorLogExporter(new MockTransmitter(telemetryItems))));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;
using Azure.Monitor.OpenTelemetry.Exporter.Models;
using Xunit.Abstractions;

namespace Azure.Monitor.OpenTelemetry.Exporter.Tests.CommonTestFramework
{
internal class TelemetryItemOutputHelper
{
private readonly ITestOutputHelper output;

public TelemetryItemOutputHelper(ITestOutputHelper output)
{
this.output = output;
}

public void Write(IEnumerable<TelemetryItem> telemetryItems)
{
if (telemetryItems == null)
{
return;
}

foreach (var telemetryItem in telemetryItems)
{
this.Write(telemetryItem);
}
}

public void Write(TelemetryItem telemetryItem)
{
output.WriteLine(new string('-', 32));

output.WriteLine($"Name: {telemetryItem.Name}");
output.WriteLine($"Tags: {telemetryItem.Tags.Count}");
foreach (var tag in telemetryItem.Tags)
{
output.WriteLine($"\t{tag.Key}: {tag.Value}");
}

WriteBaseData(telemetryItem);
}

private void WriteBaseData(TelemetryItem telemetryItem)
{
var baseType = telemetryItem.Data.BaseType;
var baseData = telemetryItem.Data.BaseData;
output.WriteLine($"\nBaseData: {baseType}");

switch (baseType)
{
case nameof(RequestData):
WriteRequestData((RequestData)baseData);
break;
case nameof(RemoteDependencyData):
WriteRemoteDependencyData((RemoteDependencyData)baseData);
break;
case nameof(MessageData):
WriteMessageData((MessageData)baseData);
break;
case "MetricData":
WriteMetricsData((MetricsData)baseData);
break;
case "ExceptionData":
WriteExceptionData((TelemetryExceptionData)baseData);
break;
default:
output.WriteLine($"***WriteBaseData not implemented for '{baseType}'***");
break;
}
}

private void WriteExceptionData(TelemetryExceptionData exceptionData)
{
output.WriteLine($"SeverityLevel: {exceptionData.SeverityLevel}");

output.WriteLine($"Exceptions: {exceptionData.Exceptions.Count}");
foreach (var exceptionDetails in exceptionData.Exceptions)
{
output.WriteLine($"\tTypeName: {exceptionDetails.TypeName}");
output.WriteLine($"\tMessage: {exceptionDetails.Message}");
}
}

private void WriteMetricsData(MetricsData metricsData)
{
foreach (var metric in metricsData.Metrics)
{
output.WriteLine($"Name: {metric.Name}");
output.WriteLine($"Namespace: {metric.Namespace}");
output.WriteLine($"\tCount: {metric.Count}");
output.WriteLine($"\tValue: {metric.Value}");
output.WriteLine($"\tMin: {metric.Min}");
output.WriteLine($"\tMax: {metric.Max}");
}
}

private void WriteMessageData(MessageData messageData)
{
output.WriteLine($"Name: {messageData.Message}");
output.WriteLine($"SeverityLevel: {messageData.SeverityLevel}");

output.WriteLine($"Properties: {messageData.Properties.Count}");
foreach (var prop in messageData.Properties)
{
output.WriteLine($"\t{prop.Key}: {prop.Value}");
}
}

private void WriteRemoteDependencyData(RemoteDependencyData remoteDependencyData)
{
output.WriteLine($"Name: {remoteDependencyData.Name}");
output.WriteLine($"Id: {remoteDependencyData.Id}");

output.WriteLine($"Properties: {remoteDependencyData.Properties.Count}");
foreach (var prop in remoteDependencyData.Properties)
{
output.WriteLine($"\t{prop.Key}: {prop.Value}");
}
}

private void WriteRequestData(RequestData requestData)
{
output.WriteLine($"Name: {requestData.Name}");
output.WriteLine($"Id: {requestData.Id}");
output.WriteLine($"Url: {requestData.Url}");
output.WriteLine($"ResponseCode: {requestData.ResponseCode}");

output.WriteLine($"Properties: {requestData.Properties.Count}");
foreach (var prop in requestData.Properties)
{
output.WriteLine($"\t{prop.Key}: {prop.Value}");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ public static void AssertActivity_As_DependencyTelemetry(
TelemetryItem telemetryItem,
string expectedName,
string expectedTraceId,
string expectedSpanId,
IDictionary<string, string> expectedProperties)
{
Assert.Equal("RemoteDependency", telemetryItem.Name); // telemetry type
Expand All @@ -152,6 +153,7 @@ public static void AssertActivity_As_DependencyTelemetry(
Assert.Contains("ai.internal.sdkVersion", telemetryItem.Tags.Keys);

var remoteDependencyData = (RemoteDependencyData)telemetryItem.Data.BaseData;
Assert.Equal(expectedSpanId, remoteDependencyData.Id);
Assert.Equal(expectedName, remoteDependencyData.Name);

if (expectedProperties == null)
Expand All @@ -172,7 +174,8 @@ public static void AssertActivity_As_RequestTelemetry(
ActivityKind activityKind,
string expectedName,
string expectedTraceId,
IDictionary<string, string> expectedProperties)
IDictionary<string, string> expectedProperties,
string expectedSpanId)
{
Assert.Equal("Request", telemetryItem.Name); // telemetry type
Assert.Equal("RequestData", telemetryItem.Data.BaseType); // telemetry data type
Expand All @@ -197,6 +200,7 @@ public static void AssertActivity_As_RequestTelemetry(

var requestData = (RequestData)telemetryItem.Data.BaseData;
Assert.Equal(expectedName, requestData.Name);
Assert.Equal(expectedSpanId, requestData.Id);

if (expectedProperties == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.Extensions.Logging;
using OpenTelemetry.Logs;
using Xunit;
using Xunit.Abstractions;

namespace Azure.Monitor.OpenTelemetry.Exporter.Tests.E2ETelemetryItemValidation
{
Expand All @@ -19,6 +20,13 @@ namespace Azure.Monitor.OpenTelemetry.Exporter.Tests.E2ETelemetryItemValidation
/// </summary>
public class LogsTests
{
internal readonly TelemetryItemOutputHelper telemetryOutput;

public LogsTests(ITestOutputHelper output)
{
this.telemetryOutput = new TelemetryItemOutputHelper(output);
}

[Theory]
[InlineData(LogLevel.Information, "Information")]
[InlineData(LogLevel.Warning, "Warning")]
Expand Down Expand Up @@ -59,6 +67,7 @@ public void VerifyLog(LogLevel logLevel, string expectedSeverityLevel)

// ASSERT
Assert.True(telemetryItems.Any(), "Unit test failed to collect telemetry.");
this.telemetryOutput.Write(telemetryItems);
var telemetryItem = telemetryItems.Single();

TelemetryItemValidationHelper.AssertLog_As_MessageTelemetry(
Expand Down Expand Up @@ -118,6 +127,7 @@ public void VerifyException(LogLevel logLevel, string expectedSeverityLevel)

// ASSERT
Assert.True(telemetryItems.Any(), "Unit test failed to collect telemetry.");
this.telemetryOutput.Write(telemetryItems);
var telemetryItem = telemetryItems.Single();

TelemetryItemValidationHelper.AssertLog_As_ExceptionTelemetry(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
using Xunit;
using Xunit.Abstractions;

namespace Azure.Monitor.OpenTelemetry.Exporter.Tests.E2ETelemetryItemValidation
{
Expand All @@ -21,6 +22,13 @@ namespace Azure.Monitor.OpenTelemetry.Exporter.Tests.E2ETelemetryItemValidation
/// </summary>
public class MetricsTests
{
internal readonly TelemetryItemOutputHelper telemetryOutput;

public MetricsTests(ITestOutputHelper output)
{
this.telemetryOutput = new TelemetryItemOutputHelper(output);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
Expand Down Expand Up @@ -57,6 +65,7 @@ public void VerifyCounter(bool asView)

// ASSERT
Assert.True(telemetryItems.Any(), "Unit test failed to collect telemetry.");
this.telemetryOutput.Write(telemetryItems);
var telemetryItem = telemetryItems.Single();

TelemetryItemValidationHelper.AssertCounter_As_MetricTelemetry(
Expand Down Expand Up @@ -107,6 +116,7 @@ public void VerifyHistogram(bool asView)

// ASSERT
Assert.True(telemetryItems.Any(), "Unit test failed to collect telemetry.");
this.telemetryOutput.Write(telemetryItems);
var telemetryItem = telemetryItems.Single();

TelemetryItemValidationHelper.AssertHistogram_As_MetricTelemetry(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using OpenTelemetry.Logs;
using OpenTelemetry.Trace;
using Xunit;
using Xunit.Abstractions;

namespace Azure.Monitor.OpenTelemetry.Exporter.Tests.E2ETelemetryItemValidation
{
Expand All @@ -22,6 +23,13 @@ namespace Azure.Monitor.OpenTelemetry.Exporter.Tests.E2ETelemetryItemValidation
/// </summary>
public class TracesTests
{
internal readonly TelemetryItemOutputHelper telemetryOutput;

public TracesTests(ITestOutputHelper output)
{
this.telemetryOutput = new TelemetryItemOutputHelper(output);
}

[Theory]
[InlineData(ActivityKind.Client)]
[InlineData(ActivityKind.Producer)]
Expand All @@ -40,10 +48,11 @@ public void VerifyTrace_CreatesDependency(ActivityKind activityKind)
.Build();

// ACT
string traceId;
string spanId, traceId;
using (var activity = activitySource.StartActivity(name: "SayHello", kind: activityKind ))
{
traceId = activity.TraceId.ToHexString();
spanId = activity.SpanId.ToHexString();

activity.SetTag("integer", 1);
activity.SetTag("message", "Hello World!");
Expand All @@ -56,12 +65,14 @@ public void VerifyTrace_CreatesDependency(ActivityKind activityKind)

// ASSERT
Assert.True(telemetryItems.Any(), "Unit test failed to collect telemetry.");
var telemetryItem = telemetryItems.Single();
this.telemetryOutput.Write(telemetryItems);
var telemetryItem = telemetryItems.First(); // TODO: Change to Single(). Still investigating random duplicate export which only repros on build server.

TelemetryItemValidationHelper.AssertActivity_As_DependencyTelemetry(
telemetryItem: telemetryItem,
expectedName: "SayHello",
expectedTraceId: traceId,
expectedSpanId: spanId,
expectedProperties: new Dictionary<string, string> { { "integer", "1" }, { "message", "Hello World!" }, { "intArray", "1,2,3" } });
}

Expand All @@ -82,10 +93,11 @@ public void VerifyTrace_CreatesRequest(ActivityKind activityKind)
.Build();

// ACT
string traceId;
string spanId, traceId;
using (var activity = activitySource.StartActivity(name: "SayHello", kind: activityKind))
{
traceId = activity.TraceId.ToHexString();
spanId = activity.SpanId.ToHexString();

activity.SetTag("integer", 1);
activity.SetTag("message", "Hello World!");
Expand All @@ -98,13 +110,15 @@ public void VerifyTrace_CreatesRequest(ActivityKind activityKind)

// ASSERT
Assert.True(telemetryItems.Any(), "Unit test failed to collect telemetry.");
var telemetryItem = telemetryItems.Single();
this.telemetryOutput.Write(telemetryItems);
var telemetryItem = telemetryItems.First(); // TODO: Change to Single(). Still investigating random duplicate export which only repros on build server.

TelemetryItemValidationHelper.AssertActivity_As_RequestTelemetry(
telemetryItem: telemetryItem,
activityKind: activityKind,
expectedName: "SayHello",
expectedTraceId: traceId,
expectedSpanId: spanId,
expectedProperties: new Dictionary<string, string> { { "integer", "1" }, { "message", "Hello World!" }, { "intArray", "1,2,3" } });
}

Expand Down Expand Up @@ -144,8 +158,9 @@ public void VerifyLogWithinActivity(LogLevel logLevel, string expectedSeverityLe

// ACT
string spanId, traceId;
string activityName = $"TestActivity {nameof(VerifyLogWithinActivity)} {logLevel}";

using (var activity = activitySource.StartActivity(name: "SayHello"))
using (var activity = activitySource.StartActivity(name: activityName))
{
spanId = activity.SpanId.ToHexString();
traceId = activity.TraceId.ToHexString();
Expand All @@ -165,16 +180,19 @@ public void VerifyLogWithinActivity(LogLevel logLevel, string expectedSeverityLe
loggerFactory.Dispose();

// ASSERT
Assert.True(activityTelemetryItems.Any(), "test project did not capture telemetry");
var activityTelemetryItem = activityTelemetryItems.Single();
Assert.True(activityTelemetryItems.Any(), "Unit test failed to collect telemetry.");
this.telemetryOutput.Write(activityTelemetryItems);
var activityTelemetryItem = activityTelemetryItems.First(); // TODO: Change to Single(). Still investigating random duplicate export which only repros on build server.

TelemetryItemValidationHelper.AssertActivity_As_DependencyTelemetry(
telemetryItem: activityTelemetryItem,
expectedName: "SayHello",
expectedName: activityName,
expectedTraceId: traceId,
expectedSpanId: spanId,
expectedProperties: null);

Assert.True(logTelemetryItems.Any(), "Unit test failed to collect telemetry.");
this.telemetryOutput.Write(logTelemetryItems);
var logTelemetryItem = logTelemetryItems.Single();

TelemetryItemValidationHelper.AssertLog_As_MessageTelemetry(
Expand Down
Loading

0 comments on commit 9887ea0

Please sign in to comment.