Skip to content

Commit c5987de

Browse files
- Consolidate GetCurrentOperationContext delegate into a property in the WcfCommon.cs class (intentionally new file to avoid rename conflicts with existing WcfIntegration.cs)
- Populate the GetCurrentOperationContext delegate lazily - Check that the WCF integration is enabled and the feature flag is enabled FIRST, before checking whether the GetCurrentOperationContext is non-null
1 parent e529a6b commit c5987de

File tree

5 files changed

+46
-66
lines changed

5 files changed

+46
-66
lines changed

tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Wcf/AsyncMethodInvoker_InvokeBegin_Integration.cs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,11 @@ namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf
2525
ParameterTypeNames = new[] { ClrNames.Object, "System.Object[]", ClrNames.AsyncCallback, ClrNames.Object },
2626
MinimumVersion = "4.0.0",
2727
MaximumVersion = "4.*.*",
28-
IntegrationName = IntegrationName)]
28+
IntegrationName = WcfCommon.IntegrationName)]
2929
[Browsable(false)]
3030
[EditorBrowsable(EditorBrowsableState.Never)]
3131
public class AsyncMethodInvoker_InvokeBegin_Integration
3232
{
33-
private const string IntegrationName = nameof(IntegrationIds.Wcf);
34-
private static readonly Func<object> _getCurrentOperationContext;
35-
36-
static AsyncMethodInvoker_InvokeBegin_Integration()
37-
{
38-
var operationContextType = Type.GetType("System.ServiceModel.OperationContext, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", throwOnError: false);
39-
if (operationContextType is not null)
40-
{
41-
var property = operationContextType.GetProperty("Current", BindingFlags.Public | BindingFlags.Static);
42-
var method = property.GetGetMethod();
43-
_getCurrentOperationContext = (Func<object>)method.CreateDelegate(typeof(Func<object>));
44-
}
45-
}
46-
4733
/// <summary>
4834
/// OnMethodBegin callback
4935
/// </summary>
@@ -63,12 +49,12 @@ public static CallTargetState OnMethodBegin<TTarget>(TTarget instance, object in
6349
//
6450
// context.IncomingMessageProperties contains:
6551
// - ["httpRequest"] key to find distributed tracing headers
66-
if (_getCurrentOperationContext is null || !Tracer.Instance.Settings.WcfEnableNewInstrumentation)
52+
if (!Tracer.Instance.Settings.IsIntegrationEnabled(WcfCommon.IntegrationId) || !Tracer.Instance.Settings.WcfEnableNewInstrumentation || WcfCommon.GetCurrentOperationContext is null)
6753
{
6854
return CallTargetState.GetDefault();
6955
}
7056

71-
var requestContext = _getCurrentOperationContext()?.GetProperty<object>("RequestContext").GetValueOrDefault();
57+
var requestContext = WcfCommon.GetCurrentOperationContext()?.GetProperty<object>("RequestContext").GetValueOrDefault();
7258
return new CallTargetState(WcfIntegration.CreateScope(requestContext));
7359
}
7460
}

tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Wcf/AsyncMethodInvoker_InvokeEnd_Integration.cs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,11 @@ namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf
2424
TargetMethodArgumentsToLoad = new ushort[] { 0, 2 }, // DO NOT pass the "out object[]" parameter into the instrumentation method
2525
MinimumVersion = "4.0.0",
2626
MaximumVersion = "4.*.*",
27-
IntegrationName = IntegrationName)]
27+
IntegrationName = WcfCommon.IntegrationName)]
2828
[Browsable(false)]
2929
[EditorBrowsable(EditorBrowsableState.Never)]
3030
public class AsyncMethodInvoker_InvokeEnd_Integration
3131
{
32-
private const string IntegrationName = nameof(IntegrationIds.Wcf);
33-
private static readonly Func<object> _getCurrentOperationContext;
34-
35-
static AsyncMethodInvoker_InvokeEnd_Integration()
36-
{
37-
var operationContextType = Type.GetType("System.ServiceModel.OperationContext, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", throwOnError: false);
38-
if (operationContextType is not null)
39-
{
40-
var property = operationContextType.GetProperty("Current", BindingFlags.Public | BindingFlags.Static);
41-
var method = property.GetGetMethod();
42-
_getCurrentOperationContext = (Func<object>)method.CreateDelegate(typeof(Func<object>));
43-
}
44-
}
45-
4632
/// <summary>
4733
/// OnMethodEnd callback
4834
/// </summary>

tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Wcf/SyncMethodInvokerIntegration.cs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,11 @@ namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf
2626
TargetMethodArgumentsToLoad = new ushort[] { 0, 1 }, // DO NOT pass the "out object[]" parameter into the instrumentation method
2727
MinimumVersion = "4.0.0",
2828
MaximumVersion = "4.*.*",
29-
IntegrationName = IntegrationName)]
29+
IntegrationName = WcfCommon.IntegrationName)]
3030
[Browsable(false)]
3131
[EditorBrowsable(EditorBrowsableState.Never)]
3232
public class SyncMethodInvokerIntegration
3333
{
34-
private const string IntegrationName = nameof(IntegrationIds.Wcf);
35-
private static readonly Func<object> _getCurrentOperationContext;
36-
37-
static SyncMethodInvokerIntegration()
38-
{
39-
var operationContextType = Type.GetType("System.ServiceModel.OperationContext, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", throwOnError: false);
40-
if (operationContextType is not null)
41-
{
42-
var property = operationContextType.GetProperty("Current", BindingFlags.Public | BindingFlags.Static);
43-
var method = property.GetGetMethod();
44-
_getCurrentOperationContext = (Func<object>)method.CreateDelegate(typeof(Func<object>));
45-
}
46-
}
47-
4834
/// <summary>
4935
/// OnMethodBegin callback
5036
/// </summary>
@@ -62,12 +48,12 @@ public static CallTargetState OnMethodBegin<TTarget>(TTarget instance, object in
6248
//
6349
// context.IncomingMessageProperties contains:
6450
// - ["httpRequest"] key to find distributed tracing headers
65-
if (_getCurrentOperationContext is null || !Tracer.Instance.Settings.WcfEnableNewInstrumentation)
51+
if (!Tracer.Instance.Settings.IsIntegrationEnabled(WcfCommon.IntegrationId) || !Tracer.Instance.Settings.WcfEnableNewInstrumentation || WcfCommon.GetCurrentOperationContext is null)
6652
{
6753
return CallTargetState.GetDefault();
6854
}
6955

70-
var requestContext = _getCurrentOperationContext()?.GetProperty<object>("RequestContext").GetValueOrDefault();
56+
var requestContext = WcfCommon.GetCurrentOperationContext()?.GetProperty<object>("RequestContext").GetValueOrDefault();
7157
return new CallTargetState(WcfIntegration.CreateScope(requestContext));
7258
}
7359

tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Wcf/TaskMethodInvokerIntegration.cs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,11 @@ namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf
2525
ParameterTypeNames = new[] { ClrNames.Object, "System.Object[]" },
2626
MinimumVersion = "4.0.0",
2727
MaximumVersion = "4.*.*",
28-
IntegrationName = IntegrationName)]
28+
IntegrationName = WcfCommon.IntegrationName)]
2929
[Browsable(false)]
3030
[EditorBrowsable(EditorBrowsableState.Never)]
3131
public class TaskMethodInvokerIntegration
3232
{
33-
private const string IntegrationName = nameof(IntegrationIds.Wcf);
34-
private static readonly Func<object> _getCurrentOperationContext;
35-
36-
static TaskMethodInvokerIntegration()
37-
{
38-
var operationContextType = Type.GetType("System.ServiceModel.OperationContext, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", throwOnError: false);
39-
if (operationContextType is not null)
40-
{
41-
var property = operationContextType.GetProperty("Current", BindingFlags.Public | BindingFlags.Static);
42-
var method = property.GetGetMethod();
43-
_getCurrentOperationContext = (Func<object>)method.CreateDelegate(typeof(Func<object>));
44-
}
45-
}
46-
4733
/// <summary>
4834
/// OnMethodBegin callback
4935
/// </summary>
@@ -61,12 +47,12 @@ public static CallTargetState OnMethodBegin<TTarget>(TTarget instance, object in
6147
//
6248
// context.IncomingMessageProperties contains:
6349
// - ["httpRequest"] key to find distributed tracing headers
64-
if (_getCurrentOperationContext is null || !Tracer.Instance.Settings.WcfEnableNewInstrumentation)
50+
if (!Tracer.Instance.Settings.IsIntegrationEnabled(WcfCommon.IntegrationId) || !Tracer.Instance.Settings.WcfEnableNewInstrumentation || WcfCommon.GetCurrentOperationContext is null)
6551
{
6652
return CallTargetState.GetDefault();
6753
}
6854

69-
var requestContext = _getCurrentOperationContext()?.GetProperty<object>("RequestContext").GetValueOrDefault();
55+
var requestContext = WcfCommon.GetCurrentOperationContext()?.GetProperty<object>("RequestContext").GetValueOrDefault();
7056
return new CallTargetState(WcfIntegration.CreateScope(requestContext));
7157
}
7258

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// <copyright file="WcfCommon.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
#if NETFRAMEWORK
7+
using System;
8+
using System.Reflection;
9+
using Datadog.Trace.Configuration;
10+
11+
namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf
12+
{
13+
internal class WcfCommon
14+
{
15+
private static readonly Lazy<Func<object>> _getCurrentOperationContext = new Lazy<Func<object>>(CreateGetCurrentOperationContextDelegate, isThreadSafe: true);
16+
17+
internal const string IntegrationName = nameof(IntegrationIds.Wcf);
18+
internal static readonly IntegrationInfo IntegrationId = IntegrationRegistry.GetIntegrationInfo(IntegrationName);
19+
20+
public static Func<object> GetCurrentOperationContext => _getCurrentOperationContext.Value;
21+
22+
private static Func<object> CreateGetCurrentOperationContextDelegate()
23+
{
24+
var operationContextType = Type.GetType("System.ServiceModel.OperationContext, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", throwOnError: false);
25+
if (operationContextType is not null)
26+
{
27+
var property = operationContextType.GetProperty("Current", BindingFlags.Public | BindingFlags.Static);
28+
var method = property.GetGetMethod();
29+
return (Func<object>)method.CreateDelegate(typeof(Func<object>));
30+
}
31+
32+
return null;
33+
}
34+
}
35+
}
36+
#endif

0 commit comments

Comments
 (0)