diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt index 2a3aa89a04a..dd82537749e 100644 --- a/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,14 +1,22 @@ OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Enrich.get -> System.Action -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithException.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithException.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpRequestMessage.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpRequestMessage.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpResponseMessage.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpResponseMessage.set -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Filter.get -> System.Func OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.HttpClientInstrumentationOptions() -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.RecordException.set -> void OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions -OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.Enrich.get -> System.Action -OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.EnrichWithException.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.EnrichWithException.set -> void +OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.EnrichWithHttpWebRequest.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.EnrichWithHttpWebRequest.set -> void +OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.EnrichWithHttpWebResponse.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.EnrichWithHttpWebResponse.set -> void OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.Filter.get -> System.Func OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.HttpWebRequestInstrumentationOptions() -> void diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Unshipped.txt index 0224a11a2e5..1590f0c3d90 100644 --- a/src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,6 +1,10 @@ OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Enrich.get -> System.Action -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithException.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithException.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpRequestMessage.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpRequestMessage.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpResponseMessage.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpResponseMessage.set -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Filter.get -> System.Func OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.HttpClientInstrumentationOptions() -> void diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 9ae28b84d26..1590f0c3d90 100644 --- a/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,6 +1,10 @@ OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Enrich.get -> System.Action -OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithException.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithException.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpRequestMessage.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpRequestMessage.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpResponseMessage.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.EnrichWithHttpResponseMessage.set -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Filter.get -> System.Func OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.HttpClientInstrumentationOptions() -> void @@ -11,4 +15,4 @@ OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureHttpClientInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHttpClientInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHttpClientInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 6688ae8112f..ce0ac8eb52c 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -2,6 +2,22 @@ ## Unreleased +* *Breaking change** The `Enrich` callback option has been removed. For better + usability, it has been replaced by three separate options: In case of + `HttpClient` the new options are `EnrichWithHttpRequestMessage`, + `EnrichWithHttpResponseMessage` and `EnrichWithException` and in case of + `HttpWebRequest` the new options are `EnrichWithHttpWebRequest`, + `EnrichWithHttpWebResponse` and `EnrichWithException`. Previously, the single + `Enrich` callback required the consumer to detect which event triggered the + callback to be invoked (e.g., request start, response end, or an exception) + and then cast the object received to the appropriate type: + `HttpRequestMessage`, `HttpResponsemessage`, or `Exception` in case of + `HttpClient` and `HttpWebRequest`,`HttpWebResponse` and `Exception` in case of + `HttpWebRequest`. The separate callbacks make it clear what event triggers + them and there is no longer the need to cast the argument to the expected +type. +([#3792](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3792)) + * Added back `netstandard2.0` target. ([#3787](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3787)) diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs index 6206cfee3c8..8bf9a96be78 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationOptions.cs @@ -36,15 +36,31 @@ public class HttpClientInstrumentationOptions public Func Filter { get; set; } /// - /// Gets or sets an action to enrich an Activity. + /// Gets or sets an action to enrich an Activity with . /// /// /// : the activity being enriched. - /// string: the name of the event. - /// object: the raw object from which additional information can be extracted to enrich the activity. - /// The type of this object depends on the event, which is given by the above parameter. + /// object from which additional information can be extracted to enrich the activity. /// - public Action Enrich { get; set; } + public Action EnrichWithHttpRequestMessage { get; set; } + + /// + /// Gets or sets an action to enrich an Activity with . + /// + /// + /// : the activity being enriched. + /// object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithHttpResponseMessage { get; set; } + + /// + /// Gets or sets an action to enrich an Activity with . + /// + /// + /// : the activity being enriched. + /// object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithException { get; set; } /// /// Gets or sets a value indicating whether exception will be recorded as ActivityEvent or not. diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpWebRequestInstrumentationOptions.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/HttpWebRequestInstrumentationOptions.netfx.cs index b695aebf367..11243d151a9 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpWebRequestInstrumentationOptions.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpWebRequestInstrumentationOptions.netfx.cs @@ -36,15 +36,31 @@ public class HttpWebRequestInstrumentationOptions public Func Filter { get; set; } /// - /// Gets or sets an action to enrich an Activity. + /// Gets or sets an action to enrich an Activity with . /// /// /// : the activity being enriched. - /// string: the name of the event. - /// object: the raw object from which additional information can be extracted to enrich the activity. - /// The type of this object depends on the event, which is given by the above parameter. + /// object from which additional information can be extracted to enrich the activity. /// - public Action Enrich { get; set; } + public Action EnrichWithHttpWebRequest { get; set; } + + /// + /// Gets or sets an action to enrich an Activity with . + /// + /// + /// : the activity being enriched. + /// object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithHttpWebResponse { get; set; } + + /// + /// Gets or sets an action to enrich an Activity with . + /// + /// + /// : the activity being enriched. + /// object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithException { get; set; } /// /// Gets or sets a value indicating whether exception will be recorded as ActivityEvent or not. diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index 7b066c0c755..4a0ed555d9c 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -160,7 +160,7 @@ public void OnStartActivity(Activity activity, object payload) try { - this.options.Enrich?.Invoke(activity, "OnStartActivity", request); + this.options.EnrichWithHttpRequestMessage?.Invoke(activity, request); } catch (Exception ex) { @@ -217,7 +217,7 @@ public void OnStopActivity(Activity activity, object payload) try { - this.options.Enrich?.Invoke(activity, "OnStopActivity", response); + this.options.EnrichWithHttpResponseMessage?.Invoke(activity, response); } catch (Exception ex) { @@ -258,7 +258,7 @@ public void OnException(Activity activity, object payload) try { - this.options.Enrich?.Invoke(activity, "OnException", exc); + this.options.EnrichWithException?.Invoke(activity, exc); } catch (Exception ex) { diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs index 1eb7c9cd2dc..26c34cbd789 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -104,7 +104,7 @@ private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, A try { - Options.Enrich?.Invoke(activity, "OnStartActivity", request); + Options.EnrichWithHttpWebRequest?.Invoke(activity, request); } catch (Exception ex) { @@ -124,7 +124,7 @@ private static void AddResponseTags(HttpWebResponse response, Activity activity) try { - Options.Enrich?.Invoke(activity, "OnStopActivity", response); + Options.EnrichWithHttpWebResponse?.Invoke(activity, response); } catch (Exception ex) { @@ -190,7 +190,7 @@ private static void AddExceptionTags(Exception exception, Activity activity) try { - Options.Enrich?.Invoke(activity, "OnException", exception); + Options.EnrichWithException?.Invoke(activity, exception); } catch (Exception ex) { diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index 41994615b26..6dcd670597b 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -112,22 +112,19 @@ and the `Filter` option does the filtering *after* the Sampler is invoked. ### Enrich -This option allows one to enrich the activity with additional information from -the raw request and response objects. The `Enrich` action is called only when -`activity.IsAllDataRequested` is `true`. It contains the activity itself (which -can be enriched), the name of the event, and the actual raw object. The object -type is different for `HttpClientInstrumentationOptions` vs +This instrumentation library provides options that can be used to +enrich the activity with additional information. These actions are called +only when `activity.IsAllDataRequested` is `true`. It contains the activity +itself (which can be enriched) and the actual raw object. The options +are different for `HttpClientInstrumentationOptions` vs `HttpWebRequestInstrumentationOptions` and is detailed below. #### HttpClientInstrumentationOptions -For event name "OnStartActivity", the actual object will be -`HttpRequestMessage`. - -For event name "OnStopActivity", the actual object will be -`HttpResponseMessage`. - -For event name "OnException", the actual object will be `Exception`. +HttpClientInstrumentationOptions provides 3 enrich options, +`EnrichWithHttpRequestMessage`, `EnrichWithHttpResponseMessage` and +`EnrichWithException`. These are based on the raw object that is passed in to +the action to enrich the activity. Example: @@ -135,40 +132,30 @@ Example: using System.Net.Http; var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddHttpClientInstrumentation((options) => options.Enrich - = (activity, eventName, rawObject) => + .AddHttpClientInstrumentation((options) => { - if (eventName.Equals("OnStartActivity")) + options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { - if (rawObject is HttpRequestMessage request) - { - activity.SetTag("requestVersion", request.Version); - } - } - else if (eventName.Equals("OnStopActivity")) + activity.SetTag("requestVersion", httpRequestMessage.Version); + }; + options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { - if (rawObject is HttpResponseMessage response) - { - activity.SetTag("responseVersion", response.Version); - } - } - else if (eventName.Equals("OnException")) + activity.SetTag("responseVersion", httpResponseMessage.Version); + }; + options.EnrichWithException = (activity, exception) => { - if (rawObject is Exception exception) - { - activity.SetTag("stackTrace", exception.StackTrace); - } - } - }).Build(); + activity.SetTag("stackTrace", exception.StackTrace); + }; + }) + .Build(); ``` #### HttpWebRequestInstrumentationOptions -For event name "OnStartActivity", the actual object will be `HttpWebRequest`. - -For event name "OnStopActivity", the actual object will be `HttpWebResponse`. - -For event name "OnException", the actual object will be `Exception`. +HttpClientInstrumentationOptions provides 3 enrich options, +`EnrichWithHttpWebRequest`, `EnrichWithHttpWebResponse` and +`EnrichWithException`. These are based on the raw object that is passed in to +the action to enrich the activity. Example: @@ -176,31 +163,22 @@ Example: using System.Net; var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddHttpClientInstrumentation((options) => options.Enrich - = (activity, eventName, rawObject) => + .AddHttpClientInstrumentation((options) => { - if (eventName.Equals("OnStartActivity")) + options.EnrichWithHttpWebRequest = (activity, httpWebRequest) => { - if (rawObject is HttpWebRequest request) - { - activity.SetTag("requestVersion", request.ProtocolVersion); - } - } - else if (eventName.Equals("OnStopActivity")) + activity.SetTag("requestVersion", httpWebRequest.Version); + }; + options.EnrichWithHttpWebResponse = (activity, httpWebResponse) => { - if (rawObject is HttpWebResponse response) - { - activity.SetTag("responseVersion", response.ProtocolVersion); - } - } - else if (eventName.Equals("OnException")) + activity.SetTag("responseVersion", httpWebResponse.Version); + }; + options.EnrichWithException = (activity, exception) => { - if (rawObject is Exception exception) - { - activity.SetTag("stackTrace", exception.StackTrace); - } - } - }).Build(); + activity.SetTag("stackTrace", exception.StackTrace); + }; + }) + .Build(); ``` [Processor](../../docs/trace/extending-the-sdk/README.md#processor), is the diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index 557b1c50312..2716ff7da49 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -21,6 +21,7 @@ using System.Net.Http; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Moq; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Http.Implementation; @@ -96,7 +97,12 @@ public void AddHttpClientInstrumentation_BadArgs() public async Task HttpClientInstrumentationInjectsHeadersAsync(bool shouldEnrich) { var processor = new Mock>(); - processor.Setup(x => x.OnStart(It.IsAny())).Callback(c => c.SetTag("enriched", "no")); + processor.Setup(x => x.OnStart(It.IsAny())).Callback(c => + { + c.SetTag("enrichedWithHttpRequestMessage", "no"); + c.SetTag("enrichedWithHttpResponseMessage", "no"); + }); + var request = new HttpRequestMessage { RequestUri = new Uri(this.url), @@ -131,7 +137,15 @@ public async Task HttpClientInstrumentationInjectsHeadersAsync(bool shouldEnrich { if (shouldEnrich) { - o.Enrich = ActivityEnrichmentSetTag; + o.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => + { + activity.SetTag("enrichedWithHttpRequestMessage", "yes"); + }; + + o.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => + { + activity.SetTag("enrichedWithHttpResponseMessage", "yes"); + }; } }) .AddProcessor(processor.Object) @@ -158,8 +172,10 @@ public async Task HttpClientInstrumentationInjectsHeadersAsync(bool shouldEnrich Assert.Equal($"00-{activity.Context.TraceId}-{activity.Context.SpanId}-01", traceparents.Single()); Assert.Equal("k1=v1,k2=v2", tracestates.Single()); - Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enriched")); - Assert.Equal(shouldEnrich ? "yes" : "no", activity.Tags.Where(tag => tag.Key == "enriched").FirstOrDefault().Value); + Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enrichedWithHttpRequestMessage")); + Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enrichedWithHttpResponseMessage")); + Assert.Equal(shouldEnrich ? "yes" : "no", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpRequestMessage").FirstOrDefault().Value); + Assert.Equal(shouldEnrich ? "yes" : "no", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpResponseMessage").FirstOrDefault().Value); } [Theory] @@ -167,6 +183,9 @@ public async Task HttpClientInstrumentationInjectsHeadersAsync(bool shouldEnrich [InlineData(false)] public async Task HttpClientInstrumentationInjectsHeadersAsync_CustomFormat(bool shouldEnrich) { + bool enrichWithHttpRequestMessageCalled = false; + bool enrichWithHttpResponseMessageCalled = false; + var propagator = new Mock(); propagator.Setup(m => m.Inject(It.IsAny(), It.IsAny(), It.IsAny>())) .Callback>((context, message, action) => @@ -196,7 +215,8 @@ public async Task HttpClientInstrumentationInjectsHeadersAsync_CustomFormat(bool { if (shouldEnrich) { - opt.Enrich = ActivityEnrichment; + opt.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; + opt.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; } }) .AddProcessor(processor.Object) @@ -227,6 +247,12 @@ public async Task HttpClientInstrumentationInjectsHeadersAsync_CustomFormat(bool new TraceContextPropagator(), new BaggagePropagator(), })); + + if (shouldEnrich) + { + Assert.True(enrichWithHttpRequestMessageCalled); + Assert.True(enrichWithHttpResponseMessageCalled); + } } [Fact] @@ -400,6 +426,9 @@ public async Task HttpClientInstrumentationCorrelationAndBaggage() { var activityProcessor = new Mock>(); + bool enrichWithHttpRequestMessageCalled = false; + bool enrichWithHttpResponseMessageCalled = false; + using var parent = new Activity("w3c activity"); parent.SetIdFormat(ActivityIdFormat.W3C); parent.AddBaggage("k1", "v1"); @@ -409,7 +438,11 @@ public async Task HttpClientInstrumentationCorrelationAndBaggage() Baggage.SetBaggage("k2", "v2"); using (Sdk.CreateTracerProviderBuilder() - .AddHttpClientInstrumentation(options => options.Enrich = ActivityEnrichment) + .AddHttpClientInstrumentation(options => + { + options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; + options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; + }) .AddProcessor(activityProcessor.Object) .Build()) { @@ -418,6 +451,8 @@ public async Task HttpClientInstrumentationCorrelationAndBaggage() } Assert.Equal(5, activityProcessor.Invocations.Count); + Assert.True(enrichWithHttpRequestMessageCalled); + Assert.True(enrichWithHttpResponseMessageCalled); } [Fact] @@ -555,33 +590,6 @@ public void Dispose() Activity.Current = null; GC.SuppressFinalize(this); } - - private static void ActivityEnrichmentSetTag(Activity activity, string method, object obj) - { - ActivityEnrichment(activity, method, obj); - activity.SetTag("enriched", "yes"); - } - - private static void ActivityEnrichment(Activity activity, string method, object obj) - { - switch (method) - { - case "OnStartActivity": - Assert.True(obj is HttpRequestMessage); - break; - - case "OnStopActivity": - Assert.True(obj is HttpResponseMessage); - break; - - case "OnException": - Assert.True(obj is Exception); - break; - - default: - break; - } - } } } #endif diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs index 7407e134527..047deb4d496 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs @@ -33,14 +33,16 @@ namespace OpenTelemetry.Instrumentation.Http.Tests { public partial class HttpClientTests { - private static int counter; - public static IEnumerable TestData => HttpTestData.ReadTestCases(); [Theory] [MemberData(nameof(TestData))] public async Task HttpOutCallsAreCollectedSuccessfullyAsync(HttpTestData.HttpOutTestCase tc) { + bool enrichWithHttpRequestMessageCalled = false; + bool enrichWithHttpResponseMessageCalled = false; + bool enrichWithExceptionCalled = false; + var serverLifeTime = TestHttpServer.RunServer( (ctx) => { @@ -65,7 +67,9 @@ public async Task HttpOutCallsAreCollectedSuccessfullyAsync(HttpTestData.HttpOut using (Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation((opt) => { - opt.Enrich = ActivityEnrichment; + opt.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; + opt.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; + opt.EnrichWithException = (activity, exception) => { enrichWithExceptionCalled = true; }; opt.RecordException = tc.RecordException ?? false; }) .AddProcessor(processor.Object) @@ -109,6 +113,12 @@ public async Task HttpOutCallsAreCollectedSuccessfullyAsync(HttpTestData.HttpOut Assert.Equal(ActivityKind.Client, activity.Kind); Assert.Equal(tc.SpanName, activity.DisplayName); + Assert.True(enrichWithHttpRequestMessageCalled); + if (tc.ResponseExpected) + { + Assert.True(enrichWithHttpResponseMessageCalled); + } + // Assert.Equal(tc.SpanStatus, d[span.Status.CanonicalCode]); Assert.Equal(tc.SpanStatus, activity.Status.ToString()); @@ -131,6 +141,7 @@ public async Task HttpOutCallsAreCollectedSuccessfullyAsync(HttpTestData.HttpOut if (tc.RecordException.HasValue && tc.RecordException.Value) { Assert.Single(activity.Events.Where(evt => evt.Name.Equals("exception"))); + Assert.True(enrichWithExceptionCalled); } if (tc.ResponseExpected) @@ -214,17 +225,23 @@ public async Task DebugIndividualTestAsync() [Fact] public async Task CheckEnrichmentWhenSampling() { - await CheckEnrichment(new AlwaysOffSampler(), 0, this.url).ConfigureAwait(false); - await CheckEnrichment(new AlwaysOnSampler(), 2, this.url).ConfigureAwait(false); + await CheckEnrichment(new AlwaysOffSampler(), false, this.url).ConfigureAwait(false); + await CheckEnrichment(new AlwaysOnSampler(), true, this.url).ConfigureAwait(false); } - private static async Task CheckEnrichment(Sampler sampler, int expect, string url) + private static async Task CheckEnrichment(Sampler sampler, bool enrichExpected, string url) { - counter = 0; + bool enrichWithHttpRequestMessageCalled = false; + bool enrichWithHttpResponseMessageCalled = false; + var processor = new Mock>(); using (Sdk.CreateTracerProviderBuilder() .SetSampler(sampler) - .AddHttpClientInstrumentation(options => options.Enrich = ActivityEnrichmentCounter) + .AddHttpClientInstrumentation(options => + { + options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; + options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; + }) .AddProcessor(processor.Object) .Build()) { @@ -232,12 +249,16 @@ private static async Task CheckEnrichment(Sampler sampler, int expect, string ur using var r = await c.GetAsync(url).ConfigureAwait(false); } - Assert.Equal(expect, counter); - } - - private static void ActivityEnrichmentCounter(Activity activity, string method, object obj) - { - counter++; + if (enrichExpected) + { + Assert.True(enrichWithHttpRequestMessageCalled); + Assert.True(enrichWithHttpResponseMessageCalled); + } + else + { + Assert.False(enrichWithHttpRequestMessageCalled); + Assert.False(enrichWithHttpResponseMessageCalled); + } } } } diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs index 1d10b03d65d..a4073069167 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs @@ -43,7 +43,15 @@ static HttpWebRequestActivitySourceTests() { HttpWebRequestInstrumentationOptions options = new HttpWebRequestInstrumentationOptions { - Enrich = ActivityEnrichment, + EnrichWithHttpWebRequest = (activity, httpWebRequest) => + { + VerifyHeaders(httpWebRequest); + + if (validateBaggage) + { + ValidateBaggage(httpWebRequest); + } + }, }; HttpWebRequestActivitySource.Options = options; diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.netfx.cs index a31ddbaaf43..9768999ab3b 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.netfx.cs @@ -45,12 +45,18 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpTestData.HttpOutTestCase tc out var host, out var port); + bool enrichWithHttpWebRequestCalled = false; + bool enrichWithHttpWebResponseCalled = false; + bool enrichWithExceptionCalled = false; + var activityProcessor = new Mock>(); using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddProcessor(activityProcessor.Object) .AddHttpClientInstrumentation(options => { - options.Enrich = ActivityEnrichment; + options.EnrichWithHttpWebRequest = (activity, httpWebRequest) => { enrichWithHttpWebRequestCalled = true; }; + options.EnrichWithHttpWebResponse = (activity, httpWebResponse) => { enrichWithHttpWebResponseCalled = true; }; + options.EnrichWithException = (activity, exception) => { enrichWithExceptionCalled = true; }; options.RecordException = tc.RecordException.HasValue ? tc.RecordException.Value : false; }) .Build(); @@ -128,9 +134,16 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpTestData.HttpOutTestCase tc Assert.Equal(value, tagValue); } + Assert.True(enrichWithHttpWebRequestCalled); + if (tc.ResponseExpected) + { + Assert.True(enrichWithHttpWebResponseCalled); + } + if (tc.RecordException.HasValue && tc.RecordException.Value) { Assert.Single(activity.Events.Where(evt => evt.Name.Equals("exception"))); + Assert.True(enrichWithExceptionCalled); } } @@ -165,27 +178,6 @@ private static void ValidateHttpWebRequestActivity(Activity activityToValidate) { Assert.Equal(ActivityKind.Client, activityToValidate.Kind); } - - private static void ActivityEnrichment(Activity activity, string method, object obj) - { - switch (method) - { - case "OnStartActivity": - Assert.True(obj is HttpWebRequest); - break; - - case "OnStopActivity": - Assert.True(obj is HttpWebResponse); - break; - - case "OnException": - Assert.True(obj is Exception); - break; - - default: - break; - } - } } } #endif