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

Azure Monitor Exporter - Minor tweaks and test coverage #16036

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal static class AzureMonitorConverter
[TelemetryType.Event] = "Event",
};

public static List<TelemetryItem> Convert(Batch<Activity> batchActivity, string instrumentationKey)
internal static List<TelemetryItem> Convert(Batch<Activity> batchActivity, string instrumentationKey)
{
List<TelemetryItem> telemetryItems = new List<TelemetryItem>();
TelemetryItem telemetryItem;
Expand All @@ -52,7 +52,7 @@ public static List<TelemetryItem> Convert(Batch<Activity> batchActivity, string
return telemetryItems;
}

private static TelemetryItem GeneratePartAEnvelope(Activity activity)
internal static TelemetryItem GeneratePartAEnvelope(Activity activity)
{
TelemetryItem telemetryItem = new TelemetryItem(PartA_Name_Mapping[activity.GetTelemetryType()], activity.StartTimeUtc.ToString(CultureInfo.InvariantCulture));
ExtractRoleInfo(activity.GetResource(), out var roleName, out var roleInstance);
Expand Down Expand Up @@ -119,9 +119,9 @@ private static MonitorBase GenerateTelemetryData(Activity activity)

if (telemetryType == TelemetryType.Request)
{
var url = activity.Kind == ActivityKind.Server ? UrlHelper.GetUrl(partBTags) : GetMessagingUrl(partBTags);
var statusCode = GetHttpStatusCode(partBTags);
var success = GetSuccessFromHttpStatusCode(statusCode);
var url = activity.Kind == ActivityKind.Server ? HttpHelper.GetUrl(partBTags) : GetMessagingUrl(partBTags);
var statusCode = HttpHelper.GetHttpStatusCode(partBTags);
var success = HttpHelper.GetSuccessFromHttpStatusCode(statusCode);
var request = new RequestData(2, activity.Context.SpanId.ToHexString(), activity.Duration.ToString("c", CultureInfo.InvariantCulture), success, statusCode)
{
Name = activity.DisplayName,
Expand All @@ -130,8 +130,7 @@ private static MonitorBase GenerateTelemetryData(Activity activity)
};

// TODO: Handle activity.TagObjects, extract well-known tags
// ExtractPropertiesFromTags(request.Properties, activity.Tags);

AddPropertiesToTelemetry(request.Properties, PartCTags);
telemetry.BaseData = request;
}
else if (telemetryType == TelemetryType.Dependency)
Expand All @@ -146,48 +145,37 @@ private static MonitorBase GenerateTelemetryData(Activity activity)

if (activityType == PartBType.Http)
{
dependency.Data = UrlHelper.GetUrl(partBTags);
dependency.Data = HttpHelper.GetUrl(partBTags);
dependency.Type = "HTTP"; // TODO: Parse for storage / SB.
var statusCode = GetHttpStatusCode(partBTags);
var statusCode = HttpHelper.GetHttpStatusCode(partBTags);
dependency.ResultCode = statusCode;
dependency.Success = GetSuccessFromHttpStatusCode(statusCode);
dependency.Success = HttpHelper.GetSuccessFromHttpStatusCode(statusCode);
}

// TODO: Handle dependency.target.
AddPropertiesToTelemetry(dependency.Properties, PartCTags);
telemetry.BaseData = dependency;
}

return telemetry;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static string GetHttpStatusCode(Dictionary<string, string> tags)
internal static string GetMessagingUrl(Dictionary<string, string> tags)
{
if (tags.TryGetValue(SemanticConventions.AttributeHttpStatusCode, out var status))
if (tags != null && tags.TryGetValue(SemanticConventions.AttributeMessagingUrl, out var url))
{
return status;
return url;
}

return "0";
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool GetSuccessFromHttpStatusCode(string statusCode)
{
return statusCode == "200" || statusCode == "Ok";
return null;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static string GetMessagingUrl(Dictionary<string, string> tags)
{
tags.TryGetValue(SemanticConventions.AttributeMessagingUrl, out var url);
return url;
}

private static void ExtractPropertiesFromTags(IDictionary<string, string> destination, IEnumerable<KeyValuePair<string, string>> tags)
internal static void AddPropertiesToTelemetry(IDictionary<string, string> destination, IEnumerable<KeyValuePair<string, string>> PartCTags)
{
// TODO: Iterate only interested fields. Ref: https://github.com/Azure/azure-sdk-for-net/pull/14254#discussion_r470907560
foreach (var tag in tags.Where(item => !item.Key.StartsWith("http.", StringComparison.InvariantCulture)))
foreach (var tag in PartCTags)
{
destination.Add(tag);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public AzureMonitorTraceExporter(AzureMonitorExporterOptions options)
/// <inheritdoc/>
public override ExportResult Export(in Batch<Activity> batch)
{
// Prevent Azure Monitor's HTTP operations from being instrumented.
using var scope = SuppressInstrumentationScope.Begin();

try
{
var telemetryItems = AzureMonitorConverter.Convert(batch, this.instrumentationKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ public AzureMonitorTransmitter(AzureMonitorExporterOptions exporterOptions)

public async ValueTask<int> TrackAsync(IEnumerable<TelemetryItem> telemetryItems, bool async, CancellationToken cancellationToken)
{
// Prevent Azure Monitor's HTTP operations from being instrumented.
using var scope = SuppressInstrumentationScope.Begin();

if (cancellationToken.IsCancellationRequested)
{
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace OpenTelemetry.Exporter.AzureMonitor
{
internal class UrlHelper
internal class HttpHelper
{
private const string SchemePostfix = "://";
private const string Colon = ":";
Expand Down Expand Up @@ -68,5 +68,33 @@ internal static string GetUrl(Dictionary<string, string> tags)

return string.IsNullOrWhiteSpace(url) ? null : url;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static string GetHttpStatusCode(Dictionary<string, string> tags)
{
if (tags != null && tags.TryGetValue(SemanticConventions.AttributeHttpStatusCode, out var status))
{
return status;
}

return "0";
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool GetSuccessFromHttpStatusCode(string statusCode)
{
return statusCode == "200" || statusCode == "Ok";
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static string GetHost(Dictionary<string, string> tags)
{
if (tags != null && tags.TryGetValue(SemanticConventions.AttributeHttpHost, out var host))
{
return host;
}

return null;
}
}
}
10 changes: 5 additions & 5 deletions sdk/monitor/OpenTelemetry.Exporter.AzureMonitor/src/PartBType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ namespace OpenTelemetry.Exporter.AzureMonitor
internal enum PartBType
{
Unknown,
Http,
Azure,
Common,
Db,
Messaging,
Rpc,
FaaS,
Net
Http,
Messaging,
Rpc
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,10 @@ internal static class SemanticConventions
public const string AttributeMessagingPayloadSize = "messaging.message_payload_size_bytes";
public const string AttributeMessagingPayloadCompressedSize = "messaging.message_payload_compressed_size_bytes";
public const string AttributeMessagingOperation = "messaging.operation";

public const string AttributeEndpointAddress = "peer.address";
public const string AttributeMessageBusDestination = "message_bus.destination";

public const string AttributeAzureNameSpace = "az.namespace";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ internal static class TagsExtension
[SemanticConventions.AttributeHttpHostPort] = PartBType.Http,
[SemanticConventions.AttributeHttpTarget] = PartBType.Http,

[SemanticConventions.AttributeNetPeerName] = PartBType.Net,
[SemanticConventions.AttributeNetPeerIp] = PartBType.Net,
[SemanticConventions.AttributeNetPeerPort] = PartBType.Net,
[SemanticConventions.AttributeNetTransport] = PartBType.Net,
[SemanticConventions.AttributeNetHostIp] = PartBType.Net,
[SemanticConventions.AttributeNetHostPort] = PartBType.Net,
[SemanticConventions.AttributeNetHostName] = PartBType.Net,
[SemanticConventions.AttributeNetPeerName] = PartBType.Common,
[SemanticConventions.AttributeNetPeerIp] = PartBType.Common,
[SemanticConventions.AttributeNetPeerPort] = PartBType.Common,
[SemanticConventions.AttributeNetTransport] = PartBType.Common,
[SemanticConventions.AttributeNetHostIp] = PartBType.Common,
[SemanticConventions.AttributeNetHostPort] = PartBType.Common,
[SemanticConventions.AttributeNetHostName] = PartBType.Common,
[SemanticConventions.AttributeComponent] = PartBType.Common,

[SemanticConventions.AttributeRpcSystem] = PartBType.Rpc,
[SemanticConventions.AttributeRpcService] = PartBType.Rpc,
Expand All @@ -45,6 +46,10 @@ internal static class TagsExtension
[SemanticConventions.AttributeFaasCron] = PartBType.FaaS,
[SemanticConventions.AttributeFaasTime] = PartBType.FaaS,

[SemanticConventions.AttributeAzureNameSpace] = PartBType.Azure,
[SemanticConventions.AttributeEndpointAddress] = PartBType.Azure,
[SemanticConventions.AttributeMessageBusDestination] = PartBType.Azure,

[SemanticConventions.AttributeMessagingSystem] = PartBType.Messaging,
[SemanticConventions.AttributeMessagingDestination] = PartBType.Messaging,
[SemanticConventions.AttributeMessagingDestinationKind] = PartBType.Messaging,
Expand Down Expand Up @@ -99,12 +104,12 @@ internal static PartBType ToAzureMonitorTags(this IEnumerable<KeyValuePair<strin
continue;
}

if (activityType == PartBType.Unknown || activityType == PartBType.Net)
if (activityType == PartBType.Unknown || activityType == PartBType.Common)
{
activityType = tempActivityType;
}

if (tempActivityType == activityType || tempActivityType == PartBType.Net)
if (tempActivityType == activityType || tempActivityType == PartBType.Common)
{
partBTags.Add(entry.Key, entry.Value.ToString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public static void Main()
var resource = OpenTelemetry.Resources.Resources.CreateServiceResource("my-service", "roleinstance1", "my-namespace");
using var tracerProvider = OpenTelemetry.Sdk.CreateTracerProviderBuilder()
.SetResource(resource)
.AddSource("Samples.SampleServer")
.AddSource("Samples.SampleClient")
.AddSource("Demo.DemoServer")
.AddSource("Demo.DemoClient")
.AddAzureMonitorTraceExporter(o => {
o.ConnectionString = $"InstrumentationKey=Ikey;";
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void Start(string url)

Task.Run(() =>
{
using var source = new ActivitySource("Samples.SampleServer");
using var source = new ActivitySource("Demo.DemoServer");

while (this.listener.IsListening)
{
Expand All @@ -63,19 +63,19 @@ public void Start(string url)
activity?.SetTag($"http.header.{headerKey}", headerValue);
}

activity?.SetTag("http.url", context.Request.Url.AbsolutePath);
activity?.SetTag("http.url", context.Request.Url.ToString());
activity?.SetTag("http.host", context.Request.Url.Host);

string requestContent;
using (var childSpan = source.StartActivity("ReadStream", ActivityKind.Consumer))
using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
{
requestContent = reader.ReadToEnd();
childSpan.AddEvent(new ActivityEvent("StreamReader.ReadToEnd"));
activity.AddEvent(new ActivityEvent("StreamReader.ReadToEnd"));
}

activity?.SetTag("request.content", requestContent);
activity?.SetTag("request.length", requestContent.Length.ToString(CultureInfo.InvariantCulture));
activity?.SetTag("http.status_code", $"{context.Response.StatusCode:D}");

var echo = Encoding.UTF8.GetBytes("echo: " + requestContent);
context.Response.ContentEncoding = Encoding.UTF8;
Expand Down Expand Up @@ -109,7 +109,7 @@ public void Start(string url)

this.requestTask = Task.Run(async () =>
{
using var source = new ActivitySource("Samples.SampleClient");
using var source = new ActivitySource("Demo.DemoClient");
using var client = new HttpClient();

var count = 1;
Expand All @@ -122,9 +122,7 @@ public void Start(string url)
count++;

activity?.AddEvent(new ActivityEvent("PostAsync:Started"));
#pragma warning disable CA2234 // Pass system uri objects instead of strings
using var response = await client.PostAsync(url, content, cancellationToken).ConfigureAwait(false);
#pragma warning restore CA2234 // Pass system uri objects instead of strings
activity?.AddEvent(new ActivityEvent("PostAsync:Ended"));

activity?.SetTag("http.url", url);
Expand Down
Loading