diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index de6cd0e0736..53bf878be3c 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -5,6 +5,10 @@ * Removes .NET Framework 4.5.2 support. The minimum .NET Framework version supported is .NET 4.6.1. ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2138)) +* `HttpClient` instances created before `AddHttpClientInstrumentation` is called + on .NET Framework will now also be instrumented + ([#2364](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2364)) + ## 1.0.0-rc7 Released 2021-Jul-12 diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs index d7a1c821e82..b4e6d545cad 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -492,10 +492,29 @@ private static void HookConnectionGroup(object value) ArrayList originalArrayList = connectionListField.GetValue(value) as ArrayList; ConnectionArrayList newArrayList = new ConnectionArrayList(originalArrayList ?? new ArrayList()); + foreach (object connection in originalArrayList) + { + HookConnection(connection); + } + connectionListField.SetValue(value, newArrayList); } } + private static void HookConnection(object value) + { + if (connectionType.IsInstanceOfType(value)) + { + // Replace the HttpWebRequest arraylist inside this Connection object, + // which allows us to intercept each new HttpWebRequest object added under + // this Connection. + ArrayList originalArrayList = writeListField.GetValue(value) as ArrayList; + HttpWebRequestArrayList newArrayList = new HttpWebRequestArrayList(originalArrayList ?? new ArrayList()); + + writeListField.SetValue(value, newArrayList); + } + } + private static Func CreateFieldGetter(string fieldName, BindingFlags flags) where TClass : class { @@ -968,17 +987,7 @@ public ConnectionArrayList(ArrayList list) public override int Add(object value) { - if (connectionType.IsInstanceOfType(value)) - { - // Replace the HttpWebRequest arraylist inside this Connection object, - // which allows us to intercept each new HttpWebRequest object added under - // this Connection. - ArrayList originalArrayList = writeListField.GetValue(value) as ArrayList; - HttpWebRequestArrayList newArrayList = new HttpWebRequestArrayList(originalArrayList ?? new ArrayList()); - - writeListField.SetValue(value, newArrayList); - } - + HookConnection(value); return base.Add(value); } } diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs index db2ec6ddd2c..affd904cad0 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs @@ -264,6 +264,24 @@ public void AddHttpClientInstrumentationUsesHttpWebRequestInstrumentationOptions }) .Build(); } + + [Fact] + public async Task HttpWebRequestInstrumentationOnExistingInstance() + { + using HttpClient client = new HttpClient(); + + await client.GetAsync(this.url).ConfigureAwait(false); + + var activityProcessor = new Mock>(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddHttpClientInstrumentation() + .Build(); + + await client.GetAsync(this.url).ConfigureAwait(false); + + Assert.Equal(3, activityProcessor.Invocations.Count); // SetParentProvider/Begin/End called + } } } #endif