-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[AzureMonitorExporter] Add support new HTTP semantics - Dependency Te…
…lemetry (#37464) * Add support new HTTP semantics - Dependency Telemetry * Merge two conditions. * PR feedback
- Loading branch information
1 parent
a919c48
commit 0a0ba46
Showing
15 changed files
with
452 additions
and
166 deletions.
There are no files selected for viewing
71 changes: 71 additions & 0 deletions
71
...nitor.OpenTelemetry.Exporter/src/Customizations/Models/RemoteDependencyData.Schema.New.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System.Diagnostics; | ||
using System.Globalization; | ||
using Azure.Core; | ||
using Azure.Monitor.OpenTelemetry.Exporter.Internals; | ||
|
||
namespace Azure.Monitor.OpenTelemetry.Exporter.Models; | ||
|
||
internal partial class RemoteDependencyData | ||
{ | ||
public RemoteDependencyData(int version, Activity activity, ref ActivityTagsProcessor activityTagsProcessor, string schemaVersion) : base(version) | ||
{ | ||
Properties = new ChangeTrackingDictionary<string, string>(); | ||
Measurements = new ChangeTrackingDictionary<string, double>(); | ||
|
||
string? httpUrl = null; | ||
string dependencyName; | ||
|
||
if (activityTagsProcessor.activityType.HasFlag(OperationType.Http)) | ||
{ | ||
httpUrl = AzMonList.GetTagValue(ref activityTagsProcessor.MappedTags, SemanticConventions.AttributeUrlFull)?.ToString(); | ||
dependencyName = activityTagsProcessor.MappedTags.GetNewSchemaHttpDependencyName(httpUrl) ?? activity.DisplayName; | ||
Data = httpUrl.Truncate(SchemaConstants.RemoteDependencyData_Data_MaxLength); | ||
Target = activityTagsProcessor.MappedTags.GetNewSchemaHttpDependencyTarget().Truncate(SchemaConstants.RemoteDependencyData_Target_MaxLength); | ||
Type = "Http"; | ||
ResultCode = AzMonList.GetTagValue(ref activityTagsProcessor.MappedTags, SemanticConventions.AttributeHttpResponseStatusCode) | ||
?.ToString().Truncate(SchemaConstants.RemoteDependencyData_ResultCode_MaxLength) | ||
?? "0"; | ||
} | ||
else | ||
{ | ||
dependencyName = activity.DisplayName; | ||
} | ||
|
||
Name = dependencyName.Truncate(SchemaConstants.RemoteDependencyData_Name_MaxLength); | ||
Id = activity.Context.SpanId.ToHexString(); | ||
Duration = activity.Duration < SchemaConstants.RemoteDependencyData_Duration_LessThanDays | ||
? activity.Duration.ToString("c", CultureInfo.InvariantCulture) | ||
: SchemaConstants.Duration_MaxValue; | ||
Success = activity.Status != ActivityStatusCode.Error; | ||
|
||
// TODO: Other operation types. | ||
|
||
if (activityTagsProcessor.AzureNamespace != null) | ||
{ | ||
if (activity.Kind == ActivityKind.Internal) | ||
{ | ||
Type = $"InProc | {activityTagsProcessor.AzureNamespace}"; | ||
} | ||
else if (activity.Kind == ActivityKind.Producer) | ||
{ | ||
Type = $"Queue Message | {activityTagsProcessor.AzureNamespace}"; | ||
} | ||
else | ||
{ | ||
// The Azure SDK sets az.namespace with its resource provider information. | ||
// When ActivityKind is not internal and az.namespace is present, set the value of Type to az.namespace. | ||
Type = activityTagsProcessor.AzureNamespace ?? Type; | ||
} | ||
} | ||
else if (activity.Kind == ActivityKind.Internal) | ||
{ | ||
Type = "InProc"; | ||
} | ||
|
||
TraceHelper.AddActivityLinksToProperties(activity, ref activityTagsProcessor.UnMappedTags); | ||
TraceHelper.AddPropertiesToTelemetry(Properties, ref activityTagsProcessor.UnMappedTags); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
.../Azure.Monitor.OpenTelemetry.Exporter/src/Customizations/Models/RequestData.Schema.New.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System.Diagnostics; | ||
using System.Globalization; | ||
using Azure.Core; | ||
using Azure.Monitor.OpenTelemetry.Exporter.Internals; | ||
|
||
namespace Azure.Monitor.OpenTelemetry.Exporter.Models; | ||
|
||
internal partial class RequestData | ||
{ | ||
public RequestData(int version, Activity activity, ref ActivityTagsProcessor activityTagsProcessor, string schemaVersion) : base(version) | ||
{ | ||
string? url = null; | ||
|
||
if (activityTagsProcessor.activityType.HasFlag(OperationType.Http)) | ||
{ | ||
url = activityTagsProcessor.MappedTags.GetNewSchemaRequestUrl(); | ||
} | ||
|
||
Id = activity.Context.SpanId.ToHexString(); | ||
Name = TraceHelper.GetNewSchemaOperationName(activity, url, ref activityTagsProcessor.MappedTags).Truncate(SchemaConstants.RequestData_Name_MaxLength); | ||
Duration = activity.Duration < SchemaConstants.RequestData_Duration_LessThanDays | ||
? activity.Duration.ToString("c", CultureInfo.InvariantCulture) | ||
: SchemaConstants.Duration_MaxValue; | ||
ResponseCode = AzMonList.GetTagValue(ref activityTagsProcessor.MappedTags, SemanticConventions.AttributeHttpResponseStatusCode) | ||
?.ToString().Truncate(SchemaConstants.RequestData_ResponseCode_MaxLength) | ||
?? "0"; | ||
|
||
Success = IsSuccess(activity, ResponseCode, activityTagsProcessor.activityType); | ||
|
||
Url = url.Truncate(SchemaConstants.RequestData_Url_MaxLength); | ||
Properties = new ChangeTrackingDictionary<string, string>(); | ||
Measurements = new ChangeTrackingDictionary<string, double>(); | ||
|
||
if (activity.Kind == ActivityKind.Consumer) | ||
{ | ||
TraceHelper.AddEnqueuedTimeToMeasurementsAndLinksToProperties(activity, Measurements, ref activityTagsProcessor.UnMappedTags); | ||
} | ||
else | ||
{ | ||
TraceHelper.AddActivityLinksToProperties(activity, ref activityTagsProcessor.UnMappedTags); | ||
} | ||
|
||
TraceHelper.AddPropertiesToTelemetry(Properties, ref activityTagsProcessor.UnMappedTags); | ||
} | ||
} |
49 changes: 0 additions & 49 deletions
49
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Customizations/Models/RequestDataV2.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 0 additions & 44 deletions
44
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/AzMonListExtensionsV2.cs
This file was deleted.
Oops, something went wrong.
91 changes: 91 additions & 0 deletions
91
sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/AzMonNewListExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Runtime.CompilerServices; | ||
|
||
namespace Azure.Monitor.OpenTelemetry.Exporter.Internals; | ||
|
||
internal static class AzMonNewListExtensions | ||
{ | ||
///<summary> | ||
/// Gets http request url from activity tag objects. | ||
///</summary> | ||
internal static string? GetNewSchemaRequestUrl(this AzMonList tagObjects) | ||
{ | ||
try | ||
{ | ||
var serverAddress = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeServerAddress)?.ToString(); | ||
if (serverAddress != null) | ||
{ | ||
UriBuilder uriBuilder = new() | ||
{ | ||
Scheme = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeUrlScheme)?.ToString(), | ||
Host = serverAddress, | ||
Path = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeUrlPath)?.ToString(), | ||
Query = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeUrlQuery)?.ToString() | ||
}; | ||
|
||
if (int.TryParse(AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeServerPort)?.ToString(), out int port)) | ||
{ | ||
uriBuilder.Port = port; | ||
} | ||
|
||
return uriBuilder.Uri.AbsoluteUri; | ||
} | ||
} | ||
catch | ||
{ | ||
// If URI building fails, there is no need to throw an exception. Instead, we can simply return null. | ||
} | ||
|
||
return null; | ||
} | ||
|
||
///<summary> | ||
/// Gets Http dependency target from activity tag objects. | ||
///</summary> | ||
internal static string? GetNewSchemaHttpDependencyTarget(this AzMonList tagObjects) | ||
{ | ||
var tagValues = AzMonList.GetTagValues(ref tagObjects, SemanticConventions.AttributeServerAddress, SemanticConventions.AttributeServerPort); | ||
var serverAddress = tagValues[0]?.ToString(); // tagValues[0] => SemanticConventions.AttributeServerAddress. | ||
var serverPort = tagValues[1]?.ToString(); // tagValues[1] => SemanticConventions.AttributeServerPort. | ||
|
||
if (string.IsNullOrWhiteSpace(serverAddress)) | ||
{ | ||
return null; | ||
} | ||
|
||
if (int.TryParse(serverPort, out int port) && !IsDefaultPort(port)) | ||
{ | ||
return $"{serverAddress}:{serverPort}"; | ||
} | ||
|
||
return serverAddress; | ||
} | ||
|
||
internal static string? GetNewSchemaHttpDependencyName(this AzMonList tagObjects, string? httpUrl) | ||
{ | ||
if (string.IsNullOrWhiteSpace(httpUrl)) | ||
{ | ||
return null; | ||
} | ||
|
||
var httpMethod = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeHttpRequestMethod)?.ToString(); | ||
if (!string.IsNullOrWhiteSpace(httpMethod)) | ||
{ | ||
if (Uri.TryCreate(httpUrl!.ToString(), UriKind.Absolute, out var uri) && uri.IsAbsoluteUri) | ||
{ | ||
return $"{httpMethod} {uri.AbsolutePath}"; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static bool IsDefaultPort(int port) | ||
{ | ||
return port == 0 || port == 80 || port == 443; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 0 additions & 38 deletions
38
...y.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Tests/AzMonListExtensionsV2Tests.cs
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.