Instrumentation raw objects should be sent as custom properties (#1099)

* Added raw objects available to instrumentation as Activity custom properties.

* Updated CHANGELOGs.

* Added "OTel" prefix to custom properties. Moved to constants.

Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
This commit is contained in:
Mikel Blanchard 2020-08-18 21:28:51 -07:00 committed by GitHub
parent 25d9a4befe
commit 8bd8641e3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 64 additions and 35 deletions

View File

@ -78,8 +78,8 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation
// Both new activity and old one store the other activity
// inside them. This is required in the Stop step to
// correctly stop and restore Activity.Current.
newOne.SetCustomProperty("ActivityByAspNet", activity);
activity.SetCustomProperty("ActivityByHttpInListener", newOne);
newOne.SetCustomProperty("OTel.ActivityByAspNet", activity);
activity.SetCustomProperty("OTel.ActivityByHttpInListener", newOne);
activity = newOne;
}
@ -135,7 +135,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation
// This block is hit if Asp.Net did restore Current to its own activity,
// and we need to retrieve the one created by HttpInListener,
// or an additional activity was never created.
createdActivity = (Activity)activity.GetCustomProperty("ActivityByHttpInListener");
createdActivity = (Activity)activity.GetCustomProperty("OTel.ActivityByHttpInListener");
activityToEnrich = createdActivity ?? activity;
}
}
@ -196,7 +196,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation
activity.Stop();
// Restore the original activity as Current.
var activityByAspNet = (Activity)activity.GetCustomProperty("ActivityByAspNet");
var activityByAspNet = (Activity)activity.GetCustomProperty("OTel.ActivityByAspNet");
Activity.Current = activityByAspNet;
}
else if (createdActivity != null)

View File

@ -2,6 +2,10 @@
## Unreleased
* Grpc instrumentation will now add the raw Request object to the Activity it
creates
([#1099](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1099))
## 0.4.0-beta.2
Released 2020-07-24

View File

@ -22,6 +22,8 @@ namespace OpenTelemetry.Instrumentation.Grpc.Implementation
{
internal class GrpcClientDiagnosticListener : ListenerHandler
{
public const string RequestCustomPropertyName = "OTel.GrpcHandler.Request";
private readonly ActivitySourceAdapter activitySource;
private readonly PropertyFetcher startRequestFetcher = new PropertyFetcher("Request");
@ -48,6 +50,7 @@ namespace OpenTelemetry.Instrumentation.Grpc.Implementation
activity.SetKind(ActivityKind.Client);
activity.DisplayName = grpcMethod?.Trim('/');
activity.SetCustomProperty(RequestCustomPropertyName, request);
this.activitySource.Start(activity);

View File

@ -2,6 +2,9 @@
## Unreleased
* ASP.NET Core instrumentation will now add the raw Request, Response, and/or
Exception objects to the Activity it creates
([#1099](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1099))
* Changed the default propagation to support W3C Baggage
([#1048](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1048))
* The default ITextFormat is now `CompositePropagator(TraceContextFormat,

View File

@ -29,6 +29,10 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
{
internal class HttpHandlerDiagnosticListener : ListenerHandler
{
public const string RequestCustomPropertyName = "OTel.HttpHandler.Request";
public const string ResponseCustomPropertyName = "OTel.HttpHandler.Response";
public const string ExceptionCustomPropertyName = "OTel.HttpHandler.Exception";
private static readonly Func<HttpRequestMessage, string, IEnumerable<string>> HttpRequestMessageHeaderValuesGetter = (request, name) =>
{
if (request.Headers.TryGetValues(name, out var values))
@ -90,6 +94,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
activity.SetKind(ActivityKind.Client);
activity.DisplayName = HttpTagHelper.GetOperationNameForHttpMethod(request.Method);
activity.SetCustomProperty(RequestCustomPropertyName, request);
this.activitySource.Start(activity);
@ -135,7 +140,8 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
if (this.stopResponseFetcher.Fetch(payload) is HttpResponseMessage response)
{
// response could be null for DNS issues, timeouts, etc...
activity.SetCustomProperty(ResponseCustomPropertyName, response);
activity.SetTag(SemanticConventions.AttributeHttpStatusCode, (int)response.StatusCode);
activity.SetStatus(
@ -158,6 +164,8 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
return;
}
activity.SetCustomProperty(ExceptionCustomPropertyName, exc);
if (exc is HttpRequestException)
{
if (exc.InnerException is SocketException exception)

View File

@ -37,8 +37,12 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
/// </remarks>
internal static class HttpWebRequestActivitySource
{
internal const string ActivitySourceName = "OpenTelemetry.HttpWebRequest";
internal const string ActivityName = ActivitySourceName + ".HttpRequestOut";
public const string ActivitySourceName = "OpenTelemetry.HttpWebRequest";
public const string ActivityName = ActivitySourceName + ".HttpRequestOut";
public const string RequestCustomPropertyName = "OTel.HttpWebRequest.Request";
public const string ResponseCustomPropertyName = "OTel.HttpWebRequest.Response";
public const string ExceptionCustomPropertyName = "OTel.HttpWebRequest.Exception";
internal static readonly Func<HttpWebRequest, string, IEnumerable<string>> HttpWebRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name);
internal static readonly Action<HttpWebRequest, string, string> HttpWebRequestHeaderValuesSetter = (request, name, value) => request.Headers.Add(name, value);
@ -97,7 +101,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
InstrumentRequest(request, activity);
activity.SetCustomProperty("HttpWebRequest.Request", request);
activity.SetCustomProperty(RequestCustomPropertyName, request);
if (activity.IsAllDataRequested)
{
@ -114,7 +118,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AddResponseTags(HttpWebResponse response, Activity activity)
{
activity.SetCustomProperty("HttpWebRequest.Response", response);
activity.SetCustomProperty(ResponseCustomPropertyName, response);
if (activity.IsAllDataRequested)
{
@ -130,7 +134,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AddExceptionTags(Exception exception, Activity activity)
{
activity.SetCustomProperty("HttpWebRequest.Exception", exception);
activity.SetCustomProperty(ExceptionCustomPropertyName, exception);
if (!activity.IsAllDataRequested)
{

View File

@ -2,7 +2,11 @@
## Unreleased
* Renamed from `AddSqlClientDependencyInstrumentation` to `AddSqlClientInstrumentation`
* .NET Core SqlClient instrumentation will now add the raw Command object to the
Activity it creates
([#1099](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1099))
* Renamed from `AddSqlClientDependencyInstrumentation` to
`AddSqlClientInstrumentation`
## 0.4.0-beta.2

View File

@ -22,19 +22,21 @@ namespace OpenTelemetry.Instrumentation.SqlClient.Implementation
{
internal class SqlClientDiagnosticListener : ListenerHandler
{
internal const string ActivitySourceName = "OpenTelemetry.SqlClient";
internal const string ActivityName = ActivitySourceName + ".Execute";
public const string ActivitySourceName = "OpenTelemetry.SqlClient";
public const string ActivityName = ActivitySourceName + ".Execute";
internal const string SqlDataBeforeExecuteCommand = "System.Data.SqlClient.WriteCommandBefore";
internal const string SqlMicrosoftBeforeExecuteCommand = "Microsoft.Data.SqlClient.WriteCommandBefore";
public const string CommandCustomPropertyName = "OTel.SqlHandler.Command";
internal const string SqlDataAfterExecuteCommand = "System.Data.SqlClient.WriteCommandAfter";
internal const string SqlMicrosoftAfterExecuteCommand = "Microsoft.Data.SqlClient.WriteCommandAfter";
public const string SqlDataBeforeExecuteCommand = "System.Data.SqlClient.WriteCommandBefore";
public const string SqlMicrosoftBeforeExecuteCommand = "Microsoft.Data.SqlClient.WriteCommandBefore";
internal const string SqlDataWriteCommandError = "System.Data.SqlClient.WriteCommandError";
internal const string SqlMicrosoftWriteCommandError = "Microsoft.Data.SqlClient.WriteCommandError";
public const string SqlDataAfterExecuteCommand = "System.Data.SqlClient.WriteCommandAfter";
public const string SqlMicrosoftAfterExecuteCommand = "Microsoft.Data.SqlClient.WriteCommandAfter";
internal const string MicrosoftSqlServerDatabaseSystemName = "mssql";
public const string SqlDataWriteCommandError = "System.Data.SqlClient.WriteCommandError";
public const string SqlMicrosoftWriteCommandError = "Microsoft.Data.SqlClient.WriteCommandError";
public const string MicrosoftSqlServerDatabaseSystemName = "mssql";
private static readonly Version Version = typeof(SqlClientDiagnosticListener).Assembly.GetName().Version;
#pragma warning disable SA1202 // Elements should be ordered by access <- In this case, Version MUST come before SqlClientActivitySource otherwise null ref exception is thrown.
@ -85,6 +87,7 @@ namespace OpenTelemetry.Instrumentation.SqlClient.Implementation
var database = this.databaseFetcher.Fetch(connection);
activity.DisplayName = (string)database;
activity.SetCustomProperty(CommandCustomPropertyName, command);
if (activity.IsAllDataRequested)
{

View File

@ -23,7 +23,7 @@ namespace OpenTelemetry.Trace
/// </summary>
public static class ActivityExtensions
{
internal const string ResourcePropertyName = "otel.resource";
internal const string ResourcePropertyName = "OTel.Resource";
/// <summary>
/// Gets the Resource associated with the Activity.

View File

@ -185,7 +185,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.True(eventRecords.Records.TryDequeue(out var stopEvent));
Assert.Equal("Stop", stopEvent.Key);
HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty("HttpWebRequest.Response");
HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.ResponseCustomPropertyName);
Assert.NotNull(response);
VerifyActivityStopTags(200, "OK", activity);
@ -237,7 +237,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.True(eventRecords.Records.TryDequeue(out var stopEvent));
Assert.Equal("Stop", stopEvent.Key);
HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty("HttpWebRequest.Response");
HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.ResponseCustomPropertyName);
Assert.NotNull(response);
Assert.Empty(activity.Tags);
@ -401,7 +401,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.True(eventRecords.Records.TryDequeue(out var stopEvent));
Assert.Equal("Stop", stopEvent.Key);
HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty("HttpWebRequest.Response");
HttpWebResponse response = (HttpWebResponse)stopEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.ResponseCustomPropertyName);
Assert.NotNull(response);
VerifyActivityStopTags(200, "OK", activity);
@ -518,9 +518,9 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.True(eventRecords.Records.TryDequeue(out var stopEvent));
Assert.Equal("Stop", stopEvent.Key);
HttpWebRequest stopRequest = (HttpWebRequest)stopEvent.Value.GetCustomProperty("HttpWebRequest.Request");
HttpWebRequest stopRequest = (HttpWebRequest)stopEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.RequestCustomPropertyName);
Assert.Equal(startRequest, stopRequest);
HttpWebResponse stopResponse = (HttpWebResponse)stopEvent.Value.GetCustomProperty("HttpWebRequest.Response");
HttpWebResponse stopResponse = (HttpWebResponse)stopEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.ResponseCustomPropertyName);
Assert.NotNull(stopResponse);
VerifyActivityStopTags(204, "No Content", activity);
@ -587,9 +587,9 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair<string, Activity> exceptionEvent));
Assert.Equal("Stop", exceptionEvent.Key);
HttpWebRequest exceptionRequest = (HttpWebRequest)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Request");
HttpWebRequest exceptionRequest = (HttpWebRequest)exceptionEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.RequestCustomPropertyName);
Assert.Equal(startRequest, exceptionRequest);
Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Exception");
Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.ExceptionCustomPropertyName);
Assert.Equal(webException, exceptionException);
Assert.Contains(activity.Tags, i => i.Key == SpanAttributeConstants.StatusCodeKey);
@ -631,7 +631,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair<string, Activity> exceptionEvent));
Assert.Equal("Stop", exceptionEvent.Key);
Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Exception");
Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.ExceptionCustomPropertyName);
Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusCodeKey);
Assert.DoesNotContain(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusDescriptionKey);
@ -672,7 +672,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair<string, Activity> exceptionEvent));
Assert.Equal("Stop", exceptionEvent.Key);
Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Exception");
Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.ExceptionCustomPropertyName);
Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusCodeKey);
Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusDescriptionKey);
@ -716,7 +716,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair<string, Activity> exceptionEvent));
Assert.Equal("Stop", exceptionEvent.Key);
Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty("HttpWebRequest.Exception");
Exception exceptionException = (Exception)exceptionEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.ExceptionCustomPropertyName);
Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusCodeKey);
Assert.Contains(exceptionEvent.Value.Tags, i => i.Key == SpanAttributeConstants.StatusDescriptionKey);
@ -741,7 +741,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));
WebRequest thisRequest = (WebRequest)eventRecords.Records.First().Value.GetCustomProperty("HttpWebRequest.Request");
WebRequest thisRequest = (WebRequest)eventRecords.Records.First().Value.GetCustomProperty(HttpWebRequestActivitySource.RequestCustomPropertyName);
string[] correlationContext = thisRequest.Headers["baggage"].Split(',');
Assert.Equal(3, correlationContext.Length);
@ -809,7 +809,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
pair.Key == "Stop",
"An unexpected event of name " + pair.Key + "was received");
WebRequest request = (WebRequest)activity.GetCustomProperty("HttpWebRequest.Request");
WebRequest request = (WebRequest)activity.GetCustomProperty(HttpWebRequestActivitySource.RequestCustomPropertyName);
Assert.Equal("HttpWebRequest", request.GetType().Name);
if (pair.Key == "Start")
@ -831,7 +831,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
else
{
// This must be the response.
WebResponse response = (WebResponse)activity.GetCustomProperty("HttpWebRequest.Response");
WebResponse response = (WebResponse)activity.GetCustomProperty(HttpWebRequestActivitySource.ResponseCustomPropertyName);
Assert.Equal("HttpWebResponse", response.GetType().Name);
// By the time we see the response, the request object may already have been redirected with a different
@ -871,7 +871,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
{
Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair<string, Activity> startEvent));
Assert.Equal("Start", startEvent.Key);
HttpWebRequest startRequest = (HttpWebRequest)startEvent.Value.GetCustomProperty("HttpWebRequest.Request");
HttpWebRequest startRequest = (HttpWebRequest)startEvent.Value.GetCustomProperty(HttpWebRequestActivitySource.RequestCustomPropertyName);
Assert.NotNull(startRequest);
return (startEvent.Value, startRequest);
}