-
Notifications
You must be signed in to change notification settings - Fork 166
Expand file tree
/
Copy pathOcelotMessageInvokerPoolIntegration.cs
More file actions
82 lines (74 loc) · 3.87 KB
/
Copy pathOcelotMessageInvokerPoolIntegration.cs
File metadata and controls
82 lines (74 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// <copyright file="OcelotMessageInvokerPoolIntegration.cs" company="Datadog">
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
// </copyright>
#nullable enable
#if NET6_0_OR_GREATER
using System;
using System.ComponentModel;
using Datadog.Trace.ClrProfiler.CallTarget;
using Datadog.Trace.Configuration;
namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.SocketsHttpHandler;
/// <summary>
/// Ocelot.Requester.MessageInvokerPool::CreateHandler calltarget instrumentation.
/// Disables Activity header propagation on the SocketsHttpHandler to prevent Ocelot
/// from overwriting Datadog trace context headers.
/// </summary>
/// <remarks>
/// <para>
/// v23.0.0 introduced SocketsHttpHandler (previously HttpClientHandler was used).
/// v24.1.0 changed the return type from HttpMessageHandler to SocketsHttpHandler.
/// v25.0.0 keeps the SocketsHttpHandler return type unchanged (only adds net10.0 support).
/// </para>
/// <para>
/// Target method: <see href="https://github.com/ThreeMammals/Ocelot/blob/23.0.0/src/Ocelot/Requester/MessageInvokerPool.cs">MessageInvokerPool.CreateHandler</see>
/// </para>
/// </remarks>
[InstrumentMethod(
AssemblyName = "Ocelot",
TypeName = "Ocelot.Requester.MessageInvokerPool",
MethodName = "CreateHandler",
ReturnTypeName = "System.Net.Http.HttpMessageHandler",
ParameterTypeNames = ["Ocelot.Configuration.DownstreamRoute"],
MinimumVersion = "23.0.0",
MaximumVersion = "24.0.*",
IntegrationName = IntegrationName)]
[InstrumentMethod(
AssemblyName = "Ocelot",
TypeName = "Ocelot.Requester.MessageInvokerPool",
MethodName = "CreateHandler",
ReturnTypeName = "System.Net.Http.SocketsHttpHandler",
ParameterTypeNames = ["Ocelot.Configuration.DownstreamRoute"],
MinimumVersion = "24.1.0",
MaximumVersion = "25.*.*",
IntegrationName = IntegrationName)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public sealed class OcelotMessageInvokerPoolIntegration
{
private const string IntegrationName = nameof(Configuration.IntegrationId.HttpMessageHandler);
private const IntegrationId IntegrationId = Configuration.IntegrationId.HttpMessageHandler;
private const IntegrationId SocketHandlerIntegrationId = Configuration.IntegrationId.HttpSocketsHandler;
internal static CallTargetReturn<TReturn> OnMethodEnd<TTarget, TReturn>(TTarget instance, TReturn returnValue, Exception exception, in CallTargetState state)
{
// If our HttpClient and SocketsHttpHandler integrations are not enabled, do not modify the factory behavior
var settings = Tracer.Instance.CurrentTraceSettings.Settings;
if (!settings.IsIntegrationEnabled(IntegrationId) || !settings.IsIntegrationEnabled(SocketHandlerIntegrationId))
{
return new CallTargetReturn<TReturn>(returnValue);
}
// On net6.0+, SocketsHttpHandler builds an internal handler chain that includes DiagnosticsHandler
// when ActivityHeadersPropagator is non-null. DiagnosticsHandler creates Activities and fires
// DiagnosticSource events, which allows OpenTelemetry SDK (if present) to inject its own trace
// context headers, overwriting headers already set by our HttpClient instrumentation.
// Setting the propagator to null (rather than CreateNoOutputPropagator()) prevents
// DiagnosticsHandler from being added to the chain entirely, ensuring Datadog trace
// context is preserved and avoiding unnecessary Activity creation for Ocelot's downstream calls.
if (returnValue is System.Net.Http.SocketsHttpHandler handler)
{
handler.ActivityHeadersPropagator = null;
}
return new CallTargetReturn<TReturn>(returnValue);
}
}
#endif