.NET Framework HttpClient Instrumentation: Fix missing events on instances created before TracerProvider (Part 2) (#2375)

* CHANGELOG update.

* Test and bug fixes.

* Update src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md

Co-authored-by: Robert Pająk <pellared@hotmail.com>

* Lint

Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Co-authored-by: Robert Pająk <pellared@hotmail.com>
This commit is contained in:
Mikel Blanchard 2021-09-20 10:37:29 -07:00 committed by GitHub
parent 67e4e071a4
commit 58054d16cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 11 deletions

View File

@ -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

View File

@ -492,10 +492,29 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
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<TClass, TField> CreateFieldGetter<TClass, TField>(string fieldName, BindingFlags flags)
where TClass : class
{
@ -968,17 +987,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
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);
}
}

View File

@ -264,6 +264,24 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
})
.Build();
}
[Fact]
public async Task HttpWebRequestInstrumentationOnExistingInstance()
{
using HttpClient client = new HttpClient();
await client.GetAsync(this.url).ConfigureAwait(false);
var activityProcessor = new Mock<BaseProcessor<Activity>>();
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