Skip to content

Commit

Permalink
.NET Framework HttpClient Instrumentation: Fix missing events on inst…
Browse files Browse the repository at this point in the history
…ances 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>
  • Loading branch information
3 people authored Sep 20, 2021
1 parent 67e4e07 commit 58054d1
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 11 deletions.
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<TClass, TField> CreateFieldGetter<TClass, TField>(string fieldName, BindingFlags flags)
where TClass : class
{
Expand Down Expand Up @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<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

0 comments on commit 58054d1

Please sign in to comment.