Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
CodeBlanch marked this conversation as resolved.
Show resolved Hide resolved
.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