Repository: DataDog/dd-trace-dotnet
Pull request #6843: [CallTarget] Flag to skip method execution
Author: login: tonyredondo
Labels: name: type:enhancement
description: Improvement to an existing feature
name: area:tracer
description: The core tracer library (Datadog.Trace, does not include OpenTracing, native code, or integrations)
name: area:automatic-instrumentation
description: Automatic instrumentation managed C# code (Datadog.Trace.ClrProfiler.Managed)
name: area:native-library
description: Automatic instrumentation native C++ code (Datadog.Trace.ClrProfiler.Native)
Created: 2025-04-11T13:08:36Z | Merged: 2025-04-15T23:21:34Z

## Summary of changes

This pull request introduces a new feature to the `CallTargetState` struct, allowing for the skipping of method body execution. The changes span multiple files, primarily within the `tracer` directory, and include updates to constructors, method definitions, and test cases.

## Reason for change

This feature was in the backlog

## Implementation details


Key changes include:

### Enhancements to `CallTargetState`:

* Added a new private readonly field `_skipMethodBody` to the `CallTargetState` struct and updated its constructors to include a `skipMethodBody` parameter. (`tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs`) [[1]](diffhunk://#diff-6bca25324afdbcc9bef068ea9fd8cdded19a17427172b29376e19d3a554b84a3R28-R42) [[2]](diffhunk://#diff-6bca25324afdbcc9bef068ea9fd8cdded19a17427172b29376e19d3a554b84a3L47-R75) [[3]](diffhunk://#diff-6bca25324afdbcc9bef068ea9fd8cdded19a17427172b29376e19d3a554b84a3L76-R109) [[4]](diffhunk://#diff-6bca25324afdbcc9bef068ea9fd8cdded19a17427172b29376e19d3a554b84a3R122-R139)
* Implemented a new property `SkipMethodBody` to expose the `_skipMethodBody` field. (`tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs`)
* Updated the `ToString` method to include the `_skipMethodBody` field. (`tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs`)

### Updates to Native Code:

* Introduced a new member reference for `get_SkipMethodBody` in `calltarget_tokens.cpp` and `calltarget_tokens.h`. (`tracer/src/Datadog.Tracer.Native/calltarget_tokens.cpp`, `tracer/src/Datadog.Tracer.Native/calltarget_tokens.h`) [[1]](diffhunk://#diff-dfc090035366d45569de2e6f4414259e3265d4673c0517b86e0d5841f8804030R21) [[2]](diffhunk://#diff-dfc090035366d45569de2e6f4414259e3265d4673c0517b86e0d5841f8804030R197-R206) [[3]](diffhunk://#diff-dfc090035366d45569de2e6f4414259e3265d4673c0517b86e0d5841f8804030R665-R686) [[4]](diffhunk://#diff-998773bcea2f4ae4d31443a76ebcca0284b17676ab13012d8ab7de951abf770aR39) [[5]](diffhunk://#diff-998773bcea2f4ae4d31443a76ebcca0284b17676ab13012d8ab7de951abf770aR98-R99)
* Modified the `TracerMethodRewriter` to check the `SkipMethodBody` property and conditionally skip the method body execution. (`tracer/src/Datadog.Tracer.Native/tracer_method_rewriter.cpp`) [[1]](diffhunk://#diff-4bd15ed24c1cd226cd9498e79a56b8784718f399a8786780b087381c6615bc33R455-R471) [[2]](diffhunk://#diff-4bd15ed24c1cd226cd9498e79a56b8784718f399a8786780b087381c6615bc33R659-R661) [[3]](diffhunk://#diff-4bd15ed24c1cd226cd9498e79a56b8784718f399a8786780b087381c6615bc33R679-R681)

### Test Case Adjustments:

* Added a constant `SKIPMETHODBODY` and logic to handle the skipping of method bodies in `Noop1ArgumentsIntegration`. (`tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsIntegration.cs`) [[1]](diffhunk://#diff-0324df49703bc605f1f12bd891bf5b35c04db28d927676cb8f9fb27c4bbc3d45R12-R13) [[2]](diffhunk://#diff-0324df49703bc605f1f12bd891bf5b35c04db28d927676cb8f9fb27c4bbc3d45R25-R35) [[3]](diffhunk://#diff-0324df49703bc605f1f12bd891bf5b35c04db28d927676cb8f9fb27c4bbc3d45R45-R55)
* Updated `With1Arguments` to test the new `SkipMethodBody` functionality. (`tracer/test/test-applications/instrumentation/CallTargetNativeTest/With1Arguments.cs`) [[1]](diffhunk://#diff-f0146f91f363fc8ad1e70e4c8e146b43b67202eba7d7ec14ce828244fc4a0287R2) [[2]](diffhunk://#diff-f0146f91f363fc8ad1e70e4c8e146b43b67202eba7d7ec14ce828244fc4a0287R21-R23)

## Test coverage

The CallTargetNative test app was update with two cases testing the skip method flag.

## Other details
<!-- Fixes #{issue} -->

<!--  ⚠️ Note: where possible, please obtain 2 approvals prior to merging. Unless CODEOWNERS specifies otherwise, for external teams it is typically best to have one review from a team member, and one review from apm-dotnet. Trivial changes do not require 2 reviews. -->



Diff:
diff --git a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Logging/NLog/LogsInjection/LoggerImplWriteIntegrationV4.cs b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Logging/NLog/LogsInjection/LoggerImplWriteIntegrationV4.cs
index fc6e4208d6b4..085c55899020 100644
--- a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Logging/NLog/LogsInjection/LoggerImplWriteIntegrationV4.cs
+++ b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/Logging/NLog/LogsInjection/LoggerImplWriteIntegrationV4.cs
@@ -53,7 +53,7 @@ internal static CallTargetState OnMethodBegin<TTarget, TTargets, TLogEventInfo,
                 if (DiagnosticContextHelper.Cache<TTarget>.Mdc is { } mdc)
                 {
                     var removeSpanId = DiagnosticContextHelper.SetMdcState(mdc, tracer);
-                    return new CallTargetState(scope: null, removeSpanId);
+                    return new CallTargetState(scope: null, (object)removeSpanId);
                 }
             }
 
diff --git a/tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs b/tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs
index b3678563f037..b6267a191969 100644
--- a/tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs
+++ b/tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs
@@ -25,17 +25,21 @@ public readonly struct CallTargetState
 
     private readonly IReadOnlyDictionary<string, string>? _previousDistributedSpanContext;
 
+    private readonly bool _skipMethodBody;
+
     /// <summary>
     /// Initializes a new instance of the <see cref="CallTargetState"/> struct.
     /// </summary>
     /// <param name="scope">Scope instance</param>
-    internal CallTargetState(Scope? scope)
+    /// <param name="skipMethodBody">Flag to skip the original method body execution</param>
+    internal CallTargetState(Scope? scope, bool skipMethodBody = false)
     {
         _previousScope = null;
         _scope = scope;
         _state = null;
         _startTime = null;
         _previousDistributedSpanContext = null;
+        _skipMethodBody = skipMethodBody;
     }
 
     /// <summary>
@@ -44,13 +48,15 @@ internal CallTargetState(Scope? scope)
     /// <param name="scope">Scope instance</param>
     /// <param name="previousScope">Previous scope instance</param>
     /// <param name="previousDistributedSpanContext">Previous distributed span context</param>
-    internal CallTargetState(Scope? scope, Scope? previousScope, IReadOnlyDictionary<string, string>? previousDistributedSpanContext)
+    /// <param name="skipMethodBody">Flag to skip the original method body execution</param>
+    internal CallTargetState(Scope? scope, Scope? previousScope, IReadOnlyDictionary<string, string>? previousDistributedSpanContext, bool skipMethodBody = false)
     {
         _previousScope = previousScope;
         _scope = scope;
         _state = null;
         _startTime = null;
         _previousDistributedSpanContext = previousDistributedSpanContext;
+        _skipMethodBody = skipMethodBody;
     }
 
     /// <summary>
@@ -58,13 +64,15 @@ internal CallTargetState(Scope? scope, Scope? previousScope, IReadOnlyDictionary
     /// </summary>
     /// <param name="scope">Scope instance</param>
     /// <param name="state">Object state instance</param>
-    internal CallTargetState(Scope? scope, object? state)
+    /// <param name="skipMethodBody">Flag to skip the original method body execution</param>
+    internal CallTargetState(Scope? scope, object? state, bool skipMethodBody = false)
     {
         _previousScope = null;
         _scope = scope;
         _state = state;
         _startTime = null;
         _previousDistributedSpanContext = null;
+        _skipMethodBody = skipMethodBody;
     }
 
     /// <summary>
@@ -73,15 +81,23 @@ internal CallTargetState(Scope? scope, object? state)
     /// <param name="scope">Scope instance</param>
     /// <param name="state">Object state instance</param>
     /// <param name="startTime">The intended start time of the scope, intended for scopes created in the OnMethodEnd handler</param>
-    internal CallTargetState(Scope? scope, object? state, DateTimeOffset? startTime)
+    /// <param name="skipMethodBody">Flag to skip the original method body execution</param>
+    internal CallTargetState(Scope? scope, object? state, DateTimeOffset? startTime, bool skipMethodBody = false)
     {
         _previousScope = null;
         _scope = scope;
         _state = state;
         _startTime = startTime;
         _previousDistributedSpanContext = null;
+        _skipMethodBody = skipMethodBody;
     }
 
+    /// <summary>
+    /// Initializes a new instance of the <see cref="CallTargetState"/> struct.
+    /// </summary>
+    /// <param name="previousScope">Previous scope instance</param>
+    /// <param name="previousDistributedSpanContext">Previous distributed span context</param>
+    /// <param name="state">Object state instance</param>
     internal CallTargetState(Scope? previousScope, IReadOnlyDictionary<string, string>? previousDistributedSpanContext, CallTargetState state)
     {
         _previousScope = previousScope;
@@ -89,6 +105,7 @@ internal CallTargetState(Scope? previousScope, IReadOnlyDictionary<string, strin
         _state = state._state;
         _startTime = state._startTime;
         _previousDistributedSpanContext = previousDistributedSpanContext;
+        _skipMethodBody = state._skipMethodBody;
     }
 
     /// <summary>
@@ -106,8 +123,14 @@ internal CallTargetState(Scope? previousScope, IReadOnlyDictionary<string, strin
     /// </summary>
     public DateTimeOffset? StartTime => _startTime;
 
+    /// <summary>
+    /// Gets the previous scope
+    /// </summary>
     internal Scope? PreviousScope => _previousScope;
 
+    /// <summary>
+    /// Gets the previous distributed span context
+    /// </summary>
     internal IReadOnlyDictionary<string, string>? PreviousDistributedSpanContext => _previousDistributedSpanContext;
 
     /// <summary>
@@ -120,12 +143,18 @@ public static CallTargetState GetDefault()
         return default;
     }
 
+    /// <summary>
+    /// Gets a value indicating whether if the original method body should be skipped
+    /// </summary>
+    /// <returns>True if the method body should be skipped; otherwise false.</returns>
+    public bool GetSkipMethodBody() => _skipMethodBody;
+
     /// <summary>
     /// ToString override
     /// </summary>
     /// <returns>String value</returns>
     public override string ToString()
     {
-        return $"{typeof(CallTargetState).FullName}({_previousScope}, {_scope}, {_state})";
+        return $"{typeof(CallTargetState).FullName}({_previousScope}, {_scope}, {_state}, {_skipMethodBody})";
     }
 }
diff --git a/tracer/src/Datadog.Tracer.Native/calltarget_tokens.cpp b/tracer/src/Datadog.Tracer.Native/calltarget_tokens.cpp
index d6ffbe6ecccc..72a6bc4b54bf 100644
--- a/tracer/src/Datadog.Tracer.Native/calltarget_tokens.cpp
+++ b/tracer/src/Datadog.Tracer.Native/calltarget_tokens.cpp
@@ -193,6 +193,16 @@ mdMemberRef CallTargetTokens::GetCallTargetStateDefaultMemberRef()
     return callTargetStateTypeGetDefault;
 }
 
+mdMemberRef CallTargetTokens::GetCallTargetStateSkipMethodBodyMemberRef()
+{
+    auto hr = EnsureBaseCalltargetTokens();
+    if (FAILED(hr))
+    {
+        return mdMemberRefNil;
+    }
+    return callTargetStateTypeSkipMethodBodyMemberRef;
+}
+
 mdMemberRef CallTargetTokens::GetCallTargetReturnVoidDefaultMemberRef()
 {
     auto hr = EnsureBaseCalltargetTokens();
@@ -651,6 +661,28 @@ HRESULT CallTargetTokens::EnsureBaseCalltargetTokens()
         callTargetStateTypeGetDefault = newCallTargetStateTypeGetDefault;
     }
 
+    // *** Ensure CallTargetState.get_SkipMethodBody() member ref
+    if (callTargetStateTypeSkipMethodBodyMemberRef == mdMemberRefNil)
+    {
+        COR_SIGNATURE signature[3] = {
+            IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS,
+            0x00,
+            ELEMENT_TYPE_BOOLEAN,
+        };
+
+        mdMemberRef newCallTargetStateTypeSkipMethodBodyMemberRef;
+        auto hr = module_metadata->metadata_emit->DefineMemberRef(
+            callTargetStateTypeRef, calltargetstate_skipmethodbody_function_name.data(), signature,
+            3, &newCallTargetStateTypeSkipMethodBodyMemberRef);
+        if (FAILED(hr))
+        {
+            Logger::Warn("Wrapper callTargetStateTypeSkipMethodBodyMemberRef could not be defined.");
+            return hr;
+        }
+
+        callTargetStateTypeSkipMethodBodyMemberRef = newCallTargetStateTypeSkipMethodBodyMemberRef;
+    }
+
     // *** Ensure calltargetrefstruct type ref
     if (callTargetRefStructTypeRef == mdTypeRefNil) {
         if (GetCallTargetRefStructType() != EmptyWStr) {
diff --git a/tracer/src/Datadog.Tracer.Native/calltarget_tokens.h b/tracer/src/Datadog.Tracer.Native/calltarget_tokens.h
index 909beb374f9a..e4057e4534a5 100644
--- a/tracer/src/Datadog.Tracer.Native/calltarget_tokens.h
+++ b/tracer/src/Datadog.Tracer.Native/calltarget_tokens.h
@@ -36,6 +36,7 @@ class CallTargetTokens
 
     volatile mdMemberRef callTargetStateTypeGetDefault = mdMemberRefNil;
     volatile mdMemberRef callTargetReturnVoidTypeGetDefault = mdMemberRefNil;
+    volatile mdMemberRef callTargetStateTypeSkipMethodBodyMemberRef = mdMemberRefNil;
     volatile mdMemberRef getDefaultMemberRef = mdMemberRefNil;
 
     mdTypeRef GetTargetStateTypeRef();
@@ -94,6 +95,8 @@ class CallTargetTokens
     mdAssemblyRef GetCorLibAssemblyRef();
     mdToken GetCurrentTypeRef(const TypeInfo* currentType, bool& isValueType);
 
+    mdMethodDef GetCallTargetStateSkipMethodBodyMemberRef();
+
     HRESULT ModifyLocalSigAndInitialize(void* rewriterWrapperPtr, TypeSignature* methodReturnType, std::vector<TypeSignature>* methodTypeArguments,
                                         ULONG* callTargetStateIndex, ULONG* exceptionIndex, ULONG* callTargetReturnIndex, ULONG* returnValueIndex,
                                         mdToken* callTargetStateToken, mdToken* exceptionToken,
diff --git a/tracer/src/Datadog.Tracer.Native/cor_profiler.cpp b/tracer/src/Datadog.Tracer.Native/cor_profiler.cpp
index 5f6ba0477589..1b32c364f3cb 100644
--- a/tracer/src/Datadog.Tracer.Native/cor_profiler.cpp
+++ b/tracer/src/Datadog.Tracer.Native/cor_profiler.cpp
@@ -983,6 +983,8 @@ HRESULT CorProfiler::TryRejitModule(ModuleID module_id, std::vector<ModuleID>& m
             call_target_bubble_up_exception_function_available = EnsureIsCallTargetBubbleUpExceptionFunctionAvailable(module_metadata, bubbleUpTypeDef);
         }
 
+        call_target_state_skip_method_body_function_available = IsSkipMethodBodyEnabled() && EnsureCallTargetStateSkipMethodBodyFunctionAvailable(module_metadata);
+
         auto native_loader_library_path = GetNativeLoaderFilePath();
         if (fs::exists(native_loader_library_path))
         {
@@ -3240,6 +3242,23 @@ bool CorProfiler::EnsureIsCallTargetBubbleUpExceptionFunctionAvailable(const Mod
     return res;
 }
 
+bool CorProfiler::EnsureCallTargetStateSkipMethodBodyFunctionAvailable(const ModuleMetadata& module_metadata)
+{
+    mdTypeDef typeDef;
+    const auto type_found = module_metadata.metadata_import->FindTypeDefByName(calltargetstate_type_name.c_str(), mdTokenNil, &typeDef);
+    if (SUCCEEDED(type_found))
+    {
+        mdMethodDef methodDef = mdTokenNil;
+        const auto function_found = module_metadata.metadata_import->FindMethod(typeDef, calltargetstate_skipmethodbody_function_name.c_str(), 0, 0, &methodDef);
+        const auto res = SUCCEEDED(function_found);
+        Logger::Debug("CallTargetState.SkipMethodBody property found: ", res);
+        return res;
+    }
+
+    Logger::Debug("CallTargetState.SkipMethodBody property not found: ", type_found);
+    return false;
+}
+
 //
 // Startup methods
 //
diff --git a/tracer/src/Datadog.Tracer.Native/cor_profiler.h b/tracer/src/Datadog.Tracer.Native/cor_profiler.h
index 7be27ea6a403..fab9f7d254a7 100644
--- a/tracer/src/Datadog.Tracer.Native/cor_profiler.h
+++ b/tracer/src/Datadog.Tracer.Native/cor_profiler.h
@@ -78,6 +78,7 @@ class CorProfiler : public CorProfilerBase
     bool trace_annotations_enabled = false;
     bool call_target_bubble_up_exception_available = false;
     bool call_target_bubble_up_exception_function_available = false;
+    bool call_target_state_skip_method_body_function_available = false;
 
     //
     // Debugger Members
@@ -132,7 +133,7 @@ class CorProfiler : public CorProfilerBase
     static bool TypeNameMatchesTraceAttribute(WCHAR type_name[], DWORD type_name_len);
     static bool EnsureCallTargetBubbleUpExceptionTypeAvailable(const ModuleMetadata& module_metadata, mdTypeDef* mdTypeDefToken);
     static bool EnsureIsCallTargetBubbleUpExceptionFunctionAvailable(const ModuleMetadata& module_metadata, mdTypeDef typeDef);
-    
+    static bool EnsureCallTargetStateSkipMethodBodyFunctionAvailable(const ModuleMetadata& module_metadata);
     //
     // Startup methods
     //
diff --git a/tracer/src/Datadog.Tracer.Native/dd_profiler_constants.h b/tracer/src/Datadog.Tracer.Native/dd_profiler_constants.h
index b0275f81a6bc..e6eb15a10ada 100644
--- a/tracer/src/Datadog.Tracer.Native/dd_profiler_constants.h
+++ b/tracer/src/Datadog.Tracer.Native/dd_profiler_constants.h
@@ -144,6 +144,9 @@ const shared::WSTRING instrumentation_type_name = WStr("Datadog.Trace.ClrProfile
 const shared::WSTRING libdatadog_exporter_nativemethods_type = WStr("Datadog.Trace.LibDatadog.NativeInterop+Exporter");
 const shared::WSTRING libdatadog_config_nativemethods_type = WStr("Datadog.Trace.LibDatadog.NativeInterop+Config");
 
+const shared::WSTRING calltargetstate_type_name = WStr("Datadog.Trace.ClrProfiler.CallTarget.CallTargetState");
+const shared::WSTRING calltargetstate_skipmethodbody_function_name = WStr("GetSkipMethodBody");
+
 #ifdef _WIN32
 const shared::WSTRING native_dll_filename = WStr("DATADOG.TRACER.NATIVE.DLL");
 #elif MACOS
diff --git a/tracer/src/Datadog.Tracer.Native/environment_variables.h b/tracer/src/Datadog.Tracer.Native/environment_variables.h
index c324f6c942a7..09978a328bf8 100644
--- a/tracer/src/Datadog.Tracer.Native/environment_variables.h
+++ b/tracer/src/Datadog.Tracer.Native/environment_variables.h
@@ -135,6 +135,9 @@ namespace environment
 
     // Security Controls config.
     const shared::WSTRING security_controls_configuration = WStr("DD_IAST_SECURITY_CONTROLS_CONFIGURATION");
+
+    // Enables or disables the skip method body feature
+    const shared::WSTRING internal_skip_method_body_enabled = WStr("DD_INTERNAL_SKIP_METHOD_BODY_ENABLED");
 } // namespace environment
 } // namespace trace
 
diff --git a/tracer/src/Datadog.Tracer.Native/environment_variables_util.cpp b/tracer/src/Datadog.Tracer.Native/environment_variables_util.cpp
index cca86cdd2848..6fce420f925a 100644
--- a/tracer/src/Datadog.Tracer.Native/environment_variables_util.cpp
+++ b/tracer/src/Datadog.Tracer.Native/environment_variables_util.cpp
@@ -80,5 +80,9 @@ bool IsEditAndContinueEnabled()
 {
     return IsEditAndContinueEnabledCore() || IsEditAndContinueEnabledNetFx();
 }
+bool IsSkipMethodBodyEnabled()
+{
+    ToBooleanWithDefault(shared::GetEnvironmentValue(environment::internal_skip_method_body_enabled), true);
+}
 
 } // namespace trace
\ No newline at end of file
diff --git a/tracer/src/Datadog.Tracer.Native/environment_variables_util.h b/tracer/src/Datadog.Tracer.Native/environment_variables_util.h
index e459932927d8..12ecaefa0eac 100644
--- a/tracer/src/Datadog.Tracer.Native/environment_variables_util.h
+++ b/tracer/src/Datadog.Tracer.Native/environment_variables_util.h
@@ -61,6 +61,7 @@ bool IsVersionCompatibilityEnabled();
 bool IsIastEnabled();
 bool IsRaspEnabled();
 bool IsEditAndContinueEnabled();
+bool IsSkipMethodBodyEnabled();
 
 } // namespace trace
 
diff --git a/tracer/src/Datadog.Tracer.Native/tracer_method_rewriter.cpp b/tracer/src/Datadog.Tracer.Native/tracer_method_rewriter.cpp
index 4d04fddfce8e..bc8acf77b726 100644
--- a/tracer/src/Datadog.Tracer.Native/tracer_method_rewriter.cpp
+++ b/tracer/src/Datadog.Tracer.Native/tracer_method_rewriter.cpp
@@ -452,12 +452,36 @@ HRESULT TracerMethodRewriter::Rewrite(RejitHandlerModule* moduleHandler, RejitHa
         beginMethodExClause.m_ClassToken = tracerTokens->GetExceptionTypeRef();
     }
 
-    // ***
-    // METHOD EXECUTION
-    // ***
-    ILInstr* beginOriginalMethodInstr = reWriterWrapper.GetCurrentILInstr();
-    pStateLeaveToBeginOriginalMethodInstr->m_pTarget = beginOriginalMethodInstr;
-    beginMethodCatchLeaveInstr->m_pTarget = beginOriginalMethodInstr;
+    // Let's check if the CallTargetState.SkipMethodBody property is available.
+    ILInstr* skipMethodBodyReturnInstr = nullptr;
+    if (m_corProfiler->call_target_state_skip_method_body_function_available)
+    {
+        // ***
+        // CHECK IF WE NEED TO SKIP THE METHOD BODY
+        // ***
+        ILInstr* skipMethodCheckFirstMethodInstr = reWriterWrapper.LoadLocalAddress(callTargetStateIndex);
+        reWriterWrapper.CallMember(tracerTokens->GetCallTargetStateSkipMethodBodyMemberRef(), false);
+
+        ILInstr* brTrueSJumpMethodInstr = rewriter.NewILInstr();
+        brTrueSJumpMethodInstr->m_opcode = CEE_BRFALSE_S;
+        brTrueSJumpMethodInstr->m_pTarget = reWriterWrapper.GetCurrentILInstr();
+        rewriter.InsertBefore(reWriterWrapper.GetCurrentILInstr(), brTrueSJumpMethodInstr);
+
+        skipMethodBodyReturnInstr = reWriterWrapper.Return();
+
+        // leave from the begin method structure should go here in skip method body check
+        pStateLeaveToBeginOriginalMethodInstr->m_pTarget = skipMethodCheckFirstMethodInstr;
+        beginMethodCatchLeaveInstr->m_pTarget = skipMethodCheckFirstMethodInstr;
+    }
+    else
+    {
+        // ***
+        // METHOD EXECUTION
+        // ***
+        ILInstr* beginOriginalMethodInstr = reWriterWrapper.GetCurrentILInstr();
+        pStateLeaveToBeginOriginalMethodInstr->m_pTarget = beginOriginalMethodInstr;
+        beginMethodCatchLeaveInstr->m_pTarget = beginOriginalMethodInstr;
+    }
 
     // ***
     // ENDING OF THE METHOD EXECUTION
@@ -641,7 +665,7 @@ HRESULT TracerMethodRewriter::Rewrite(RejitHandlerModule* moduleHandler, RejitHa
             {
                 if (pInstr != methodReturnInstr)
                 {
-                    if (isVoid)
+                    if (isVoid || pInstr == skipMethodBodyReturnInstr)
                     {
                         pInstr->m_opcode = CEE_LEAVE_S;
                         pInstr->m_pTarget = endFinallyInstr->m_pNext;
diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CallTargetNativeTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CallTargetNativeTests.cs
index f1c8d6d01a03..1dbd9a8bd3e5 100644
--- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CallTargetNativeTests.cs
+++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/CallTargetNativeTests.cs
@@ -24,7 +24,7 @@ public CallTargetNativeTests(ITestOutputHelper output)
 
         public static IEnumerable<object[]> MethodArgumentsData()
         {
-            for (var i = 0; i < 1; i++)
+            for (var i = 0; i < 9; i++)
             {
                 var fastPath = i < 9;
                 yield return new object[] { i, fastPath };
@@ -69,6 +69,12 @@ public async Task MethodArgumentsInstrumentation(int numberOfArguments, bool fas
                     Assert.Equal(180, endMethodCount);
                     Assert.Equal(44, exceptionCount);
                 }
+                else if (numberOfArguments == 1)
+                {
+                    Assert.Equal(175, beginMethodCount);
+                    Assert.Equal(175, endMethodCount);
+                    Assert.Equal(40, exceptionCount);
+                }
                 else
                 {
                     Assert.Equal(168, beginMethodCount);
@@ -104,9 +110,9 @@ public async Task MethodRefArguments()
                     ".VoidRefMethod",
                 };
 
-                Assert.Equal(8, beginMethodCount);
+                Assert.Equal(9, beginMethodCount);
                 Assert.Equal(8, begin2MethodCount);
-                Assert.Equal(16, endMethodCount);
+                Assert.Equal(17, endMethodCount);
 
                 foreach (var typeName in typeNames)
                 {
@@ -198,8 +204,8 @@ public async Task MethodInterface()
                     ".ReturnValueMethod",
                 };
 
-                Assert.Equal(3, begin1MethodCount);
-                Assert.Equal(3, endMethodCount);
+                Assert.Equal(5, begin1MethodCount);
+                Assert.Equal(5, endMethodCount);
 
                 foreach (var typeName in typeNames)
                 {
diff --git a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/Interface.cs b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/Interface.cs
index 9651c95b441e..8f4c1aebac39 100644
--- a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/Interface.cs
+++ b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/Interface.cs
@@ -1,4 +1,5 @@
 using System;
+using CallTargetNativeTest.NoOp;
 using Datadog.Trace.ClrProfiler.CallTarget;
 
 namespace CallTargetNativeTest;
@@ -10,10 +11,12 @@ private static void InterfaceMethod()
         InterfaceType implicitImpl = new ImplicitImplInterface();
         Console.WriteLine($"{typeof(ImplicitImplInterface).FullName}.VoidMethod");
         RunMethod(() => implicitImpl.VoidMethod("Hello World"));
+        RunMethod(() => implicitImpl.VoidMethod(Noop1ArgumentsVoidIntegration.SKIPMETHODBODY));
 
         InterfaceType explicitImpl = new ExplicitImplInterface();
         Console.WriteLine($"{typeof(ExplicitImplInterface).FullName}.VoidMethod");
         RunMethod(() => explicitImpl.VoidMethod("Hello World"));
+        RunMethod(() => explicitImpl.VoidMethod(Noop1ArgumentsVoidIntegration.SKIPMETHODBODY));
 
         // Note: This demonstrates that, through interface instrumentation, the instrumented type must directly implement the interface
         // This case requires additional derived instrumentation
diff --git a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/GenericOutModificationVoidIntegration.cs b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/GenericOutModificationVoidIntegration.cs
index 302eb5c7fa86..aa1d81562b3c 100644
--- a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/GenericOutModificationVoidIntegration.cs
+++ b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/GenericOutModificationVoidIntegration.cs
@@ -8,9 +8,8 @@ public static class GenericOutModificationVoidIntegration
         public static CallTargetState OnMethodBegin<TTarget, TArg1>(TTarget instance, out TArg1 arg01)
         {
             arg01 = default;
-            CallTargetState returnValue = CallTargetState.GetDefault();
             Console.WriteLine($"ProfilerOK: BeginMethod(1)<{typeof(GenericOutModificationVoidIntegration)}, {typeof(TTarget)}, {typeof(TArg1)}>({instance}, {arg01})");
-            return returnValue;
+            return CallTargetState.GetDefault();;
         }
 
         public static CallTargetReturn OnMethodEnd<TTarget>(TTarget instance, Exception exception, in CallTargetState state)
diff --git a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/GenericRefModificationVoidIntegration.cs b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/GenericRefModificationVoidIntegration.cs
index 11244c86090f..90504935a59e 100644
--- a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/GenericRefModificationVoidIntegration.cs
+++ b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/GenericRefModificationVoidIntegration.cs
@@ -5,18 +5,24 @@ namespace CallTargetNativeTest.NoOp
 {
     public static class GenericRefModificationVoidIntegration
     {
+        public const string SKIPMETHODBODY = "SKIPMETHODBODY";
+
         public static CallTargetState OnMethodBegin<TTarget, TArg1>(TTarget instance, ref TArg1 arg01)
         {
-            CallTargetState returnValue = CallTargetState.GetDefault();
             Console.WriteLine($"ProfilerOK: BeginMethod(1)<{typeof(GenericRefModificationVoidIntegration)}, {typeof(TTarget)}, {typeof(TArg1)}>({instance}, {arg01})");
-            return returnValue;
+            
+            if (arg01 is SKIPMETHODBODY)
+            {
+                return new CallTargetState(null, null, skipMethodBody: true);
+            }
+            
+            return CallTargetState.GetDefault();
         }
 
         public static CallTargetReturn OnMethodEnd<TTarget>(TTarget instance, Exception exception, in CallTargetState state)
         {
-            CallTargetReturn returnValue = CallTargetReturn.GetDefault();
             Console.WriteLine($"ProfilerOK: EndMethod(0)<{typeof(GenericRefModificationVoidIntegration)}, {typeof(TTarget)}>({instance}, {exception?.ToString() ?? "(null)"}, {state})");
-            return returnValue;
+            return CallTargetReturn.GetDefault();
         }
     }
 }
diff --git a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsIntegration.cs b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsIntegration.cs
index 7b52ecec1604..44c8d3b34012 100644
--- a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsIntegration.cs
+++ b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsIntegration.cs
@@ -9,10 +9,11 @@ namespace CallTargetNativeTest.NoOp
     /// </summary>
     public static class Noop1ArgumentsIntegration
     {
+        public const string SKIPMETHODBODY = "SKIPMETHODBODY";
+
         public static CallTargetState OnMethodBegin<TTarget, TArg1>(TTarget instance, TArg1 arg1)
             where TTarget : IInstance, IDuckType
         {
-            CallTargetState returnValue = new CallTargetState(null, instance.Instance);
             Console.WriteLine($"ProfilerOK: BeginMethod(1)<{typeof(Noop1ArgumentsIntegration)}, {typeof(TTarget)}, {typeof(TArg1)}>({instance}, {arg1})");
             if (instance.Instance?.GetType().Name.Contains("ThrowOnBegin") == true)
             {
@@ -20,14 +21,19 @@ public static CallTargetState OnMethodBegin<TTarget, TArg1>(TTarget instance, TA
                 throw new Exception();
             }
 
-            return returnValue;
+            Console.WriteLine(arg1 as string);
+            if (arg1 as string == SKIPMETHODBODY)
+            {
+                return new CallTargetState(null, instance.Instance, skipMethodBody: true);
+            }
+
+            return new CallTargetState(null, instance.Instance);
         }
 
         public static CallTargetReturn<TReturn> OnMethodEnd<TTarget, TReturn>(TTarget instance, TReturn returnValue, Exception exception, in CallTargetState state)
             where TTarget : IInstance, IDuckType
-            where TReturn : IReturnValue
+            where TReturn : IReturnValue, IDuckType
         {
-            CallTargetReturn<TReturn> rValue = new CallTargetReturn<TReturn>(returnValue);
             Console.WriteLine($"ProfilerOK: EndMethod(1)<{typeof(Noop1ArgumentsIntegration)}, {typeof(TTarget)}, {typeof(TReturn)}>({instance}, {returnValue}, {exception?.ToString() ?? "(null)"}, {state})");
             if (instance.Instance?.GetType().Name.Contains("ThrowOnEnd") == true)
             {
@@ -35,7 +41,18 @@ public static CallTargetReturn<TReturn> OnMethodEnd<TTarget, TReturn>(TTarget in
                 throw new Exception();
             }
 
-            return rValue;
+            if (state.GetSkipMethodBody() && returnValue.Type == typeof(int))
+            {
+                // if we skip the method body, for an int return value we should have the default int value (0) as return value.
+                // originally in the example we always return 42.
+                if (returnValue.Instance is int and not 0)
+                {
+                    Console.WriteLine("Exception thrown.");
+                    throw new Exception();
+                }
+            }
+
+            return new CallTargetReturn<TReturn>(returnValue);;
         }
 
         public static TReturn OnAsyncMethodEnd<TTarget, TReturn>(TTarget instance, TReturn returnValue, Exception exception, in CallTargetState state)
diff --git a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsVoidIntegration.cs b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsVoidIntegration.cs
index 9209b708b51e..dd52787ac44d 100644
--- a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsVoidIntegration.cs
+++ b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/NoOp/Noop1ArgumentsVoidIntegration.cs
@@ -8,9 +8,10 @@ namespace CallTargetNativeTest.NoOp
     /// </summary>
     public static class Noop1ArgumentsVoidIntegration
     {
+        public const string SKIPMETHODBODY = "SKIPMETHODBODY";
+
         public static CallTargetState OnMethodBegin<TTarget, TArg1>(TTarget instance, TArg1 arg1)
         {
-            CallTargetState returnValue = CallTargetState.GetDefault();
             Console.WriteLine($"ProfilerOK: BeginMethod(1)<{typeof(Noop1ArgumentsVoidIntegration)}, {typeof(TTarget)}, {typeof(TArg1)}>({instance}, {arg1})");
             if (instance?.GetType().Name.Contains("ThrowOnBegin") == true)
             {
@@ -18,7 +19,13 @@ public static CallTargetState OnMethodBegin<TTarget, TArg1>(TTarget instance, TA
                 throw new Exception();
             }
 
-            return returnValue;
+            Console.WriteLine(arg1 as string);
+            if (arg1 as string == SKIPMETHODBODY)
+            {
+                return new CallTargetState(null, null, skipMethodBody: true);
+            }
+
+            return CallTargetState.GetDefault();
         }
 
         public static CallTargetReturn OnMethodEnd<TTarget>(TTarget instance, Exception exception, in CallTargetState state)
@@ -30,7 +37,7 @@ public static CallTargetReturn OnMethodEnd<TTarget>(TTarget instance, Exception
                 Console.WriteLine("Exception thrown.");
                 throw new Exception();
             }
-
+            
             return returnValue;
         }
     }
diff --git a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/With1Arguments.cs b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/With1Arguments.cs
index 58d12abf112c..411e4ead696e 100644
--- a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/With1Arguments.cs
+++ b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/With1Arguments.cs
@@ -1,4 +1,5 @@
 using System;
+using CallTargetNativeTest.NoOp;
 
 namespace CallTargetNativeTest;
 
@@ -17,6 +18,8 @@ private static void Argument1()
         RunMethod(() => w1.ReturnGenericMethod<string, string>("Hello world"));
         Console.WriteLine($"{typeof(With1Arguments).FullName}.ReturnGenericMethod<int>");
         RunMethod(() => w1.ReturnGenericMethod<int, int>(42));
+        Console.WriteLine($"{typeof(With1Arguments).FullName}.ReturnValueMethod (SKIPPING METHOD BODY)");
+        RunMethod(() => w1.ReturnValueMethod(Noop1ArgumentsIntegration.SKIPMETHODBODY));
         Console.WriteLine();
         //
         var w1g1 = new With1ArgumentsGeneric<string>();
@@ -28,6 +31,8 @@ private static void Argument1()
         RunMethod(() => w1g1.ReturnReferenceMethod("Hello World"));
         Console.WriteLine($"{typeof(With1ArgumentsGeneric<string>).FullName}.ReturnGenericMethod");
         RunMethod(() => w1g1.ReturnGenericMethod<string>("Hello World"));
+        Console.WriteLine($"{typeof(With1ArgumentsGeneric<string>).FullName}.ReturnValueMethod (SKIPPING METHOD BODY)");
+        RunMethod(() => w1g1.ReturnValueMethod(Noop1ArgumentsIntegration.SKIPMETHODBODY));
         Console.WriteLine();
         //
         var w1g2 = new With1ArgumentsGeneric<int>();
@@ -39,6 +44,8 @@ private static void Argument1()
         RunMethod(() => w1g2.ReturnReferenceMethod("Hello world"));
         Console.WriteLine($"{typeof(With1ArgumentsGeneric<int>).FullName}.ReturnGenericMethod");
         RunMethod(() => w1g2.ReturnGenericMethod<int>(42));
+        Console.WriteLine($"{typeof(With1ArgumentsGeneric<int>).FullName}.ReturnValueMethod (SKIPPING METHOD BODY)");
+        RunMethod(() => w1g2.ReturnValueMethod(Noop1ArgumentsIntegration.SKIPMETHODBODY));
         Console.WriteLine();
         //
         var w1in = new With1ArgumentsInherits();
@@ -52,6 +59,8 @@ private static void Argument1()
         RunMethod(() => w1in.ReturnGenericMethod<string, int>(42));
         Console.WriteLine($"{typeof(With1ArgumentsInherits).FullName}.ReturnGenericMethod<int>");
         RunMethod(() => w1in.ReturnGenericMethod<int, string>("Hello World"));
+        Console.WriteLine($"{typeof(With1ArgumentsInherits).FullName}.ReturnValueMethod (SKIPPING METHOD BODY)");
+        RunMethod(() => w1in.ReturnValueMethod(Noop1ArgumentsIntegration.SKIPMETHODBODY));
         Console.WriteLine();
         //
         var w1inGen = new With1ArgumentsInheritsGeneric();
@@ -63,6 +72,8 @@ private static void Argument1()
         RunMethod(() => w1inGen.ReturnReferenceMethod("Hello World"));
         Console.WriteLine($"{typeof(With1ArgumentsInheritsGeneric).FullName}.ReturnGenericMethod");
         RunMethod(() => w1inGen.ReturnGenericMethod<int>(42));
+        Console.WriteLine($"{typeof(With1ArgumentsInheritsGeneric).FullName}.ReturnValueMethod (SKIPPING METHOD BODY)");
+        RunMethod(() => w1inGen.ReturnValueMethod(Noop1ArgumentsIntegration.SKIPMETHODBODY));
         Console.WriteLine();
         //
         var w1Struct = new With1ArgumentsStruct();
@@ -76,6 +87,8 @@ private static void Argument1()
         RunMethod(() => w1Struct.ReturnGenericMethod<string, int>(42));
         Console.WriteLine($"{typeof(With1ArgumentsStruct).FullName}.ReturnGenericMethod<int>");
         RunMethod(() => w1Struct.ReturnGenericMethod<int, string>("Hello World"));
+        Console.WriteLine($"{typeof(With1ArgumentsStruct).FullName}.ReturnValueMethod (SKIPPING METHOD BODY)");
+        RunMethod(() => w1Struct.ReturnValueMethod(Noop1ArgumentsIntegration.SKIPMETHODBODY));
         Console.WriteLine();
         //
         Console.WriteLine($"{typeof(With1ArgumentsStatic).FullName}.VoidMethod");
@@ -88,6 +101,8 @@ private static void Argument1()
         RunMethod(() => With1ArgumentsStatic.ReturnGenericMethod<string, int>(42));
         Console.WriteLine($"{typeof(With1ArgumentsStatic).FullName}.ReturnGenericMethod<int>");
         RunMethod(() => With1ArgumentsStatic.ReturnGenericMethod<int, string>("Hello World"));
+        Console.WriteLine($"{typeof(With1ArgumentsStatic).FullName}.ReturnValueMethod (SKIPPING METHOD BODY)");
+        RunMethod(() => With1ArgumentsStatic.ReturnValueMethod(Noop1ArgumentsIntegration.SKIPMETHODBODY));
         Console.WriteLine();
         //
         var w1TBegin = new With1ArgumentsThrowOnBegin();
diff --git a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/WithRefArguments.cs b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/WithRefArguments.cs
index c651263035d9..af25d3450491 100644
--- a/tracer/test/test-applications/instrumentation/CallTargetNativeTest/WithRefArguments.cs
+++ b/tracer/test/test-applications/instrumentation/CallTargetNativeTest/WithRefArguments.cs
@@ -1,4 +1,5 @@
 using System;
+using CallTargetNativeTest.NoOp;
 
 namespace CallTargetNativeTest;
 
@@ -40,6 +41,16 @@ private static void WithRefArguments()
             }
         });
         RunMethod(() =>
+        {
+            string strVal = GenericRefModificationVoidIntegration.SKIPMETHODBODY;
+            wRefArg.VoidRefMethod(ref strVal);
+
+            if (strVal != GenericRefModificationVoidIntegration.SKIPMETHODBODY)
+            {
+                throw new Exception("Error skipping method body.");
+            }
+        });
+        RunMethod(() =>
         {
             string strVal = "MyString";
             int intVal = 15;


Reviews:
user: login: andrewlock
body: Nice work, thanks!
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-14T08:47:41Z
user: login: bricefriha
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T08:59:12Z
user: login: zacharycmontoya
body: Looks great!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T21:45:28Z
user: login: bouwkast
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-15T15:27:08Z
user: login: bouwkast
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-15T15:27:37Z
user: login: tonyredondo
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-15T23:19:12Z
user: login: andrewlock
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-16T08:41:27Z
user: login: andrewlock
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-16T08:42:14Z
user: login: andrewlock
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-16T10:25:47Z

Review comments:
diff_hunk: @@ -101,13 +118,24 @@ internal CallTargetState(Scope? previousScope, IReadOnlyDictionary<string, strin
     /// </summary>
     public object? State => _state;
 
+    /// <summary>
+    /// Gets a value indicating whether if the original method body should be skipped
+    /// </summary>
+    public bool SkipMethodBody => _skipMethodBody;
+
     /// <summary>
     /// Gets the CallTarget state StartTime
     /// </summary>
     public DateTimeOffset? StartTime => _startTime;
 
+    /// <summary>
+    /// Gets the previous scope
+    /// </summary>
path: tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs
user: login: andrewlock
body: Yeah, _that_ really clears things up - let me guess, more copilot suggestions? 😉 
created_at: 2025-04-14T08:16:46Z
author_association: MEMBER
diff_hunk: @@ -101,13 +118,24 @@ internal CallTargetState(Scope? previousScope, IReadOnlyDictionary<string, strin
     /// </summary>
     public object? State => _state;
 
+    /// <summary>
+    /// Gets a value indicating whether if the original method body should be skipped
+    /// </summary>
+    public bool SkipMethodBody => _skipMethodBody;
+
     /// <summary>
     /// Gets the CallTarget state StartTime
     /// </summary>
     public DateTimeOffset? StartTime => _startTime;
 
+    /// <summary>
+    /// Gets the previous scope
+    /// </summary>
path: tracer/src/Datadog.Trace/ClrProfiler/CallTarget/CallTargetState.cs
user: login: bricefriha
body: To be honest, without copilot, sometimes I leave comments like these without realising how obvious they are 😄
created_at: 2025-04-14T08:59:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -41,6 +41,7 @@ public NLogTests(ITestOutputHelper output)
             : base(output, "LogsInjection.NLog")
         {
             SetServiceVersion("1.0.0");
+            // SetEnvironmentVariable("DD_INTERNAL_SKIP_METHOD_BODY_ENABLED", "0");
path: tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/NLogTests.cs
user: login: bouwkast
body: ```suggestion
```
created_at: 2025-04-15T15:26:23Z
author_association: COLLABORATOR
diff_hunk: @@ -41,6 +41,7 @@ public NLogTests(ITestOutputHelper output)
             : base(output, "LogsInjection.NLog")
         {
             SetServiceVersion("1.0.0");
+            // SetEnvironmentVariable("DD_INTERNAL_SKIP_METHOD_BODY_ENABLED", "0");
path: tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/NLogTests.cs
user: login: bouwkast
body: I am going through these tests though so I can clean this up in it as well if you don't want to re-run CI
created_at: 2025-04-15T15:27:36Z
author_association: COLLABORATOR
diff_hunk: @@ -41,6 +41,7 @@ public NLogTests(ITestOutputHelper output)
             : base(output, "LogsInjection.NLog")
         {
             SetServiceVersion("1.0.0");
+            // SetEnvironmentVariable("DD_INTERNAL_SKIP_METHOD_BODY_ENABLED", "0");
path: tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/NLogTests.cs
user: login: tonyredondo
body:  removed.
created_at: 2025-04-15T23:19:12Z
author_association: MEMBER
diff_hunk: @@ -135,6 +135,9 @@ namespace environment
 
     // Security Controls config.
     const shared::WSTRING security_controls_configuration = WStr("DD_IAST_SECURITY_CONTROLS_CONFIGURATION");
+
+    // Enables or disables the skip method body feature
+    const shared::WSTRING internal_skip_method_body_enabled = WStr("DD_INTERNAL_SKIP_METHOD_BODY_ENABLED");
path: tracer/src/Datadog.Tracer.Native/environment_variables.h
user: login: andrewlock
body: Is this really necessary 🤔 It looks like it was something you thought you would need when trying to figure out the issue, but it isn't actually necessary?
created_at: 2025-04-16T08:41:26Z
author_association: MEMBER
diff_hunk: @@ -135,6 +135,9 @@ namespace environment
 
     // Security Controls config.
     const shared::WSTRING security_controls_configuration = WStr("DD_IAST_SECURITY_CONTROLS_CONFIGURATION");
+
+    // Enables or disables the skip method body feature
+    const shared::WSTRING internal_skip_method_body_enabled = WStr("DD_INTERNAL_SKIP_METHOD_BODY_ENABLED");
path: tracer/src/Datadog.Tracer.Native/environment_variables.h
user: login: andrewlock
body: What's more, it looks essentially dangerous, this doesn't seem like it's something that should be configurable 🤔 
created_at: 2025-04-16T08:42:13Z
author_association: MEMBER
diff_hunk: @@ -135,6 +135,9 @@ namespace environment
 
     // Security Controls config.
     const shared::WSTRING security_controls_configuration = WStr("DD_IAST_SECURITY_CONTROLS_CONFIGURATION");
+
+    // Enables or disables the skip method body feature
+    const shared::WSTRING internal_skip_method_body_enabled = WStr("DD_INTERNAL_SKIP_METHOD_BODY_ENABLED");
path: tracer/src/Datadog.Tracer.Native/environment_variables.h
user: login: andrewlock
body: I created a separate PR to remove this and tweak some things: https://github.com/DataDog/dd-trace-dotnet/pull/6861
created_at: 2025-04-16T10:25:46Z
author_association: MEMBER

PR comments:
user: login: datadog-ddstaging[bot]
created_at: 2025-04-12T02:09:27Z
body: 
## Datadog Report

Branch report: [`tony/calltarget-skip-method-body`](https://ddstaging.datadoghq.com/ci/test-branch/github.com%2Fdatadog%2Fdd-trace-dotnet/dd-trace-dotnet/tony%2Fcalltarget-skip-method-body?env=ci&index=citest&_user_click_origin_=github)
Commit report: [`5f72db5`](https://ddstaging.datadoghq.com/ci/test-commit/github.com%2Fdatadog%2Fdd-trace-dotnet/dd-trace-dotnet/tony%2Fcalltarget-skip-method-body/5f72db52200d7ca374f40a2d18d830a7bdc1a351?env=ci&index=citest&_user_click_origin_=github)
Test service: `dd-trace-dotnet`

:white_check_mark: 0 Failed, 6 Passed, 0 Skipped, 0s Total Time




author_association: NONE
user: login: andrewlock
created_at: 2025-04-14T07:56:01Z
body: ## Execution-Time Benchmarks Report :stopwatch:

Execution-time results for samples comparing the following branches/commits:
- [This PR (6843)](https://github.com/DataDog/dd-trace-dotnet/tree/cdd705f1aa2b24a341e7ad17ff1935af44f22953)
- [master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)

Execution-time benchmarks measure the whole time it takes to execute a program. And are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are shown in **red**. The following thresholds were used for comparing the execution times:
* Welch test with statistical test for significance of **5%**
* Only results indicating a difference greater than **5%** and **5 ms** are considered.


Note that these results are based on a _single_ point-in-time result for each branch. For full results, see the [dashboard](https://ddstaging.datadoghq.com/dashboard/4qn-6fi-54p/apm-net-execution-time-benchmarks).

Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph).
```mermaid
gantt
    title Execution time (ms) FakeDbCommand (.NET Framework 4.6.2) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6843) - mean (70ms)  : 67, 73
     .   : milestone, 70,
    master - mean (70ms)  : 67, 72
     .   : milestone, 70,

    section CallTarget+Inlining+NGEN
    This PR (6843) - mean (1,011ms)  : 989, 1033
     .   : milestone, 1011,
    master - mean (1,009ms)  : 988, 1031
     .   : milestone, 1009,

```
```mermaid
gantt
    title Execution time (ms) FakeDbCommand (.NET Core 3.1) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6843) - mean (104ms)  : 102, 106
     .   : milestone, 104,
    master - mean (104ms)  : 102, 106
     .   : milestone, 104,

    section CallTarget+Inlining+NGEN
    This PR (6843) - mean (701ms)  : 681, 720
     .   : milestone, 701,
    master - mean (697ms)  : 677, 716
     .   : milestone, 697,

```
```mermaid
gantt
    title Execution time (ms) FakeDbCommand (.NET 6) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6843) - mean (90ms)  : 88, 92
     .   : milestone, 90,
    master - mean (90ms)  : 88, 92
     .   : milestone, 90,

    section CallTarget+Inlining+NGEN
    This PR (6843) - mean (659ms)  : 639, 679
     .   : milestone, 659,
    master - mean (658ms)  : 634, 682
     .   : milestone, 658,

```
```mermaid
gantt
    title Execution time (ms) HttpMessageHandler (.NET Framework 4.6.2) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6843) - mean (190ms)  : 186, 193
     .   : milestone, 190,
    master - mean (189ms)  : 186, 193
     .   : milestone, 189,

    section CallTarget+Inlining+NGEN
    This PR (6843) - mean (1,115ms)  : 1086, 1143
     .   : milestone, 1115,
    master - mean (1,105ms)  : 1084, 1126
     .   : milestone, 1105,

```
```mermaid
gantt
    title Execution time (ms) HttpMessageHandler (.NET Core 3.1) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6843) - mean (268ms)  : 264, 271
     .   : milestone, 268,
    master - mean (268ms)  : 264, 272
     .   : milestone, 268,

    section CallTarget+Inlining+NGEN
    This PR (6843) - mean (880ms)  : 849, 911
     .   : milestone, 880,
    master - mean (876ms)  : 852, 901
     .   : milestone, 876,

```
```mermaid
gantt
    title Execution time (ms) HttpMessageHandler (.NET 6) 
    dateFormat  X
    axisFormat %s
    todayMarker off
    section Baseline
    This PR (6843) - mean (260ms)  : 257, 264
     .   : milestone, 260,
    master - mean (261ms)  : 257, 265
     .   : milestone, 261,

    section CallTarget+Inlining+NGEN
    This PR (6843) - mean (870ms)  : 839, 900
     .   : milestone, 870,
    master - mean (863ms)  : 836, 891
     .   : milestone, 863,

```
author_association: MEMBER
user: login: andrewlock
created_at: 2025-04-14T08:33:34Z
body: ## Benchmarks Report for tracer :snail:

Benchmarks for #6843 compared to [master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544): 
* 6 benchmarks are **faster**, with geometric mean 1.150
* 1 benchmarks have **fewer** allocations


The following thresholds were used for comparing the benchmark speeds:
* Mann–Whitney U test with statistical test for significance of **5%**
* Only results indicating a difference greater than **10%** and **0.3 ns** are considered.

Allocation changes below **0.5%** are ignored.


### Benchmark details


<details><summary><strong>Benchmarks.Trace.ActivityBenchmark</strong> - Same speed :heavy_check_mark: Fewer allocations :tada:



#### Fewer allocations :tada: in #6843

|  Benchmark         | Base Allocated | Diff Allocated | Change   | Change % |
|:----------|-----------:|-----------:|--------:|--------:|
| Benchmarks.Trace.ActivityBenchmark.StartStopWithChild&#8209;net6.0 | 5.6 KB | 5.57 KB | -34 B | -0.61%

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartStopWithChild`|net6.0|7.93μs|133ns|1.32μs|0| 0|0|5.6&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartStopWithChild`|netcoreapp3.1|10.4μs|120ns|1.2μs|0| 0|0|5.77&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartStopWithChild`|net472|15.2μs|85.6ns|617ns|0.989| 0.282|0.0706|6.13&nbsp;KB|
|#6843|`StartStopWithChild`|net6.0|7.7μs|92.8ns|923ns|0| 0|0|5.57&nbsp;KB|
|#6843|`StartStopWithChild`|netcoreapp3.1|10.4μs|174ns|1.74μs|0| 0|0|5.76&nbsp;KB|
|#6843|`StartStopWithChild`|net472|14.7μs|37.9ns|137ns|1.03| 0.316|0.0791|6.16&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.AgentWriterBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`WriteAndFlushEnrichedTraces`|net6.0|512μs|1.92μs|7.43μs|0| 0|0|2.71&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`WriteAndFlushEnrichedTraces`|netcoreapp3.1|685μs|1.01μs|3.79μs|0| 0|0|2.7&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`WriteAndFlushEnrichedTraces`|net472|865μs|343ns|1.24μs|0| 0|0|3.31&nbsp;KB|
|#6843|`WriteAndFlushEnrichedTraces`|net6.0|488μs|474ns|1.71μs|0| 0|0|2.7&nbsp;KB|
|#6843|`WriteAndFlushEnrichedTraces`|netcoreapp3.1|643μs|1.68μs|6.27μs|0| 0|0|2.7&nbsp;KB|
|#6843|`WriteAndFlushEnrichedTraces`|net472|859μs|886ns|3.43μs|0| 0|0|3.31&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.AspNetCoreBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendRequest`|net6.0|130μs|698ns|4.01μs|0| 0|0|14.48&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendRequest`|netcoreapp3.1|147μs|726ns|3.25μs|0| 0|0|17.28&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendRequest`|net472|0.000445ns|0.000305ns|0.00114ns|0| 0|0|0&nbsp;b|
|#6843|`SendRequest`|net6.0|129μs|724ns|4.86μs|0| 0|0|14.48&nbsp;KB|
|#6843|`SendRequest`|netcoreapp3.1|147μs|333ns|1.2μs|0| 0|0|17.28&nbsp;KB|
|#6843|`SendRequest`|net472|0.00428ns|0.00128ns|0.00496ns|0| 0|0|0&nbsp;b|
</details>


<details><summary><strong>Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`WriteAndFlushEnrichedTraces`|net6.0|551μs|1.01μs|3.65μs|0| 0|0|41.43&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`WriteAndFlushEnrichedTraces`|netcoreapp3.1|709μs|6.26μs|61.6μs|0| 0|0|41.8&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`WriteAndFlushEnrichedTraces`|net472|857μs|5.71μs|56.8μs|7.81| 0|0|53.28&nbsp;KB|
|#6843|`WriteAndFlushEnrichedTraces`|net6.0|565μs|4.26μs|40.9μs|0| 0|0|41.57&nbsp;KB|
|#6843|`WriteAndFlushEnrichedTraces`|netcoreapp3.1|650μs|3.27μs|15.3μs|0| 0|0|41.7&nbsp;KB|
|#6843|`WriteAndFlushEnrichedTraces`|net472|912μs|5.39μs|53.3μs|8.33| 4.17|0|53.39&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.DbCommandBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`ExecuteNonQuery`|net6.0|1.35μs|3.5ns|13.5ns|0.0133| 0|0|1.03&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`ExecuteNonQuery`|netcoreapp3.1|1.76μs|2.32ns|8.69ns|0.00872| 0|0|1.02&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`ExecuteNonQuery`|net472|2.09μs|4.08ns|15.8ns|0.155| 0.0103|0|995&nbsp;B|
|#6843|`ExecuteNonQuery`|net6.0|1.33μs|2.44ns|9.11ns|0.0134| 0|0|1.03&nbsp;KB|
|#6843|`ExecuteNonQuery`|netcoreapp3.1|1.81μs|5.34ns|19.2ns|0.00899| 0|0|1.02&nbsp;KB|
|#6843|`ExecuteNonQuery`|net472|2.05μs|6.18ns|23.9ns|0.152| 0.0102|0|995&nbsp;B|
</details>


<details><summary><strong>Benchmarks.Trace.ElasticsearchBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`CallElasticsearch`|net6.0|1.23μs|1.22ns|4.74ns|0.0124| 0|0|984&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`CallElasticsearch`|netcoreapp3.1|1.65μs|1.88ns|6.79ns|0.00809| 0|0|984&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`CallElasticsearch`|net472|2.57μs|1.99ns|7.72ns|0.154| 0|0|1&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`CallElasticsearchAsync`|net6.0|1.3μs|0.927ns|3.59ns|0.0129| 0|0|960&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`CallElasticsearchAsync`|netcoreapp3.1|1.68μs|1.91ns|7.13ns|0.00842| 0|0|1.03&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`CallElasticsearchAsync`|net472|2.68μs|1.44ns|5.56ns|0.161| 0|0|1.06&nbsp;KB|
|#6843|`CallElasticsearch`|net6.0|1.25μs|1.24ns|4.82ns|0.0127| 0|0|984&nbsp;B|
|#6843|`CallElasticsearch`|netcoreapp3.1|1.57μs|2.15ns|8.05ns|0.00781| 0|0|984&nbsp;B|
|#6843|`CallElasticsearch`|net472|2.53μs|1.65ns|6.37ns|0.151| 0|0|1&nbsp;KB|
|#6843|`CallElasticsearchAsync`|net6.0|1.22μs|0.643ns|2.41ns|0.0123| 0|0|960&nbsp;B|
|#6843|`CallElasticsearchAsync`|netcoreapp3.1|1.66μs|1.02ns|3.69ns|0.00851| 0|0|1.03&nbsp;KB|
|#6843|`CallElasticsearchAsync`|net472|2.72μs|1.25ns|4.67ns|0.164| 0|0|1.06&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.GraphQLBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`ExecuteAsync`|net6.0|1.37μs|0.829ns|3.21ns|0.0138| 0|0|960&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`ExecuteAsync`|netcoreapp3.1|1.67μs|4.72ns|17.7ns|0.00852| 0|0|960&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`ExecuteAsync`|net472|1.74μs|0.624ns|2.33ns|0.139| 0|0|923&nbsp;B|
|#6843|`ExecuteAsync`|net6.0|1.44μs|1.01ns|3.78ns|0.00721| 0|0|960&nbsp;B|
|#6843|`ExecuteAsync`|netcoreapp3.1|1.7μs|1.02ns|3.95ns|0.00818| 0|0|960&nbsp;B|
|#6843|`ExecuteAsync`|net472|1.84μs|0.633ns|2.45ns|0.138| 0|0|923&nbsp;B|
</details>


<details><summary><strong>Benchmarks.Trace.HttpClientBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendAsync`|net6.0|4.34μs|3.29ns|12.7ns|0.0217| 0|0|2.32&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendAsync`|netcoreapp3.1|5.38μs|4.59ns|17.2ns|0.027| 0|0|2.86&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendAsync`|net472|7.53μs|3.83ns|14.8ns|0.49| 0|0|3.13&nbsp;KB|
|#6843|`SendAsync`|net6.0|4.35μs|2.67ns|10.4ns|0.0217| 0|0|2.32&nbsp;KB|
|#6843|`SendAsync`|netcoreapp3.1|5.33μs|3.85ns|13.9ns|0.0268| 0|0|2.86&nbsp;KB|
|#6843|`SendAsync`|net472|7.55μs|3.55ns|12.3ns|0.487| 0|0|3.13&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.ILoggerBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|net6.0|1.49μs|1.31ns|5.08ns|0.0223| 0|0|1.71&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|netcoreapp3.1|2.24μs|2.3ns|7.98ns|0.0227| 0|0|1.71&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|net472|2.59μs|4.33ns|16.2ns|0.26| 0|0|1.64&nbsp;KB|
|#6843|`EnrichedLog`|net6.0|1.48μs|1.53ns|5.92ns|0.0223| 0|0|1.71&nbsp;KB|
|#6843|`EnrichedLog`|netcoreapp3.1|2.31μs|2.67ns|9.99ns|0.0115| 0|0|1.71&nbsp;KB|
|#6843|`EnrichedLog`|net472|2.71μs|1.21ns|4.54ns|0.257| 0|0|1.64&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.Log4netBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|net6.0|113μs|283ns|1.1μs|0| 0|0|4.32&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|netcoreapp3.1|116μs|214ns|831ns|0| 0|0|4.32&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|net472|150μs|173ns|646ns|0| 0|0|4.51&nbsp;KB|
|#6843|`EnrichedLog`|net6.0|114μs|352ns|1.36μs|0| 0|0|4.32&nbsp;KB|
|#6843|`EnrichedLog`|netcoreapp3.1|115μs|176ns|660ns|0| 0|0|4.32&nbsp;KB|
|#6843|`EnrichedLog`|net472|153μs|357ns|1.38μs|0| 0|0|4.51&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.NLogBenchmark</strong> - Faster :tada: Same allocations :heavy_check_mark:



#### Faster :tada: in #6843

|  Benchmark         | base/diff | Base Median (ns) | Diff Median (ns) | Modality   |
|:----------|-----------:|-----------:|--------:|--------:|
| Benchmarks.Trace.NLogBenchmark.EnrichedLog&#8209;net6.0 | 1.122 | 3,245.75 | 2,892.59 | 

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|net6.0|3.25μs|2.28ns|8.54ns|0.0331| 0|0|2.26&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|netcoreapp3.1|4.26μs|2.3ns|8.3ns|0.0214| 0|0|2.26&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|net472|4.91μs|1.49ns|5.76ns|0.32| 0|0|2.09&nbsp;KB|
|#6843|`EnrichedLog`|net6.0|2.9μs|5.94ns|23ns|0.0291| 0|0|2.26&nbsp;KB|
|#6843|`EnrichedLog`|netcoreapp3.1|4.12μs|4.94ns|18.5ns|0.0208| 0|0|2.26&nbsp;KB|
|#6843|`EnrichedLog`|net472|4.92μs|2.19ns|8.19ns|0.32| 0|0|2.09&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.RedisBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendReceive`|net6.0|1.46μs|1.26ns|4.72ns|0.0146| 0|0|1.15&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendReceive`|netcoreapp3.1|1.69μs|3.65ns|14.1ns|0.00839| 0|0|1.15&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`SendReceive`|net472|2.01μs|1.8ns|6.75ns|0.18| 0|0|1.16&nbsp;KB|
|#6843|`SendReceive`|net6.0|1.45μs|1.17ns|4.52ns|0.0146| 0|0|1.15&nbsp;KB|
|#6843|`SendReceive`|netcoreapp3.1|1.86μs|8.74ns|32.7ns|0.00915| 0|0|1.15&nbsp;KB|
|#6843|`SendReceive`|net472|2.03μs|1.18ns|4.24ns|0.183| 0|0|1.16&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.SerilogBenchmark</strong> - Same speed :heavy_check_mark: Same allocations :heavy_check_mark:

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|net6.0|2.87μs|3.1ns|11.6ns|0.0141| 0|0|1.64&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|netcoreapp3.1|4.02μs|3.37ns|12.6ns|0.0201| 0|0|1.69&nbsp;KB|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`EnrichedLog`|net472|4.57μs|5ns|18ns|0.317| 0|0|2.08&nbsp;KB|
|#6843|`EnrichedLog`|net6.0|2.9μs|1.46ns|5.48ns|0.0146| 0|0|1.64&nbsp;KB|
|#6843|`EnrichedLog`|netcoreapp3.1|3.92μs|3.1ns|11.2ns|0.0195| 0|0|1.69&nbsp;KB|
|#6843|`EnrichedLog`|net472|4.5μs|2.86ns|10.3ns|0.315| 0|0|2.08&nbsp;KB|
</details>


<details><summary><strong>Benchmarks.Trace.SpanBenchmark</strong> - Faster :tada: Same allocations :heavy_check_mark:



#### Faster :tada: in #6843

|  Benchmark         | base/diff | Base Median (ns) | Diff Median (ns) | Modality   |
|:----------|-----------:|-----------:|--------:|--------:|
| Benchmarks.Trace.SpanBenchmark.StartFinishScope&#8209;netcoreapp3.1 | 1.211 | 819.80 | 677.16 | 
| Benchmarks.Trace.SpanBenchmark.StartFinishSpan&#8209;net6.0 | 1.178 | 467.77 | 397.24 | 
| Benchmarks.Trace.SpanBenchmark.StartFinishScope&#8209;net6.0 | 1.143 | 556.05 | 486.41 | 

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartFinishSpan`|net6.0|468ns|0.38ns|1.47ns|0.00711| 0|0|584&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartFinishSpan`|netcoreapp3.1|563ns|0.209ns|0.783ns|0.00568| 0|0|584&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartFinishSpan`|net472|675ns|0.205ns|0.793ns|0.0903| 0|0|586&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartFinishScope`|net6.0|556ns|0.449ns|1.68ns|0.0083| 0|0|704&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartFinishScope`|netcoreapp3.1|820ns|0.49ns|1.77ns|0.00803| 0|0|704&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`StartFinishScope`|net472|866ns|0.322ns|1.25ns|0.104| 0|0|666&nbsp;B|
|#6843|`StartFinishSpan`|net6.0|397ns|0.253ns|0.946ns|0.00792| 0|0|584&nbsp;B|
|#6843|`StartFinishSpan`|netcoreapp3.1|572ns|0.773ns|2.89ns|0.00568| 0|0|584&nbsp;B|
|#6843|`StartFinishSpan`|net472|729ns|0.292ns|1.09ns|0.0913| 0|0|586&nbsp;B|
|#6843|`StartFinishScope`|net6.0|487ns|0.289ns|1.04ns|0.00975| 0|0|704&nbsp;B|
|#6843|`StartFinishScope`|netcoreapp3.1|678ns|0.948ns|3.55ns|0.00678| 0|0|704&nbsp;B|
|#6843|`StartFinishScope`|net472|855ns|0.643ns|2.49ns|0.102| 0|0|666&nbsp;B|
</details>


<details><summary><strong>Benchmarks.Trace.TraceAnnotationsBenchmark</strong> - Faster :tada: Same allocations :heavy_check_mark:



#### Faster :tada: in #6843

|  Benchmark         | base/diff | Base Median (ns) | Diff Median (ns) | Modality   |
|:----------|-----------:|-----------:|--------:|--------:|
| Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin&#8209;net6.0 | 1.135 | 690.10 | 607.81 | 
| Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin&#8209;netcoreapp3.1 | 1.116 | 979.82 | 877.65 | 

</summary>

### Raw results


|  Branch |                      Method |     Toolchain |     Mean | StdError |  StdDev |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|---------|---------------------------- |-------------- |---------:|---------:|--------:|-------:|------:|------:|----------:|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`RunOnMethodBegin`|net6.0|689ns|0.829ns|3.21ns|0.00694| 0|0|704&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`RunOnMethodBegin`|netcoreapp3.1|983ns|1.75ns|6.79ns|0.00505| 0|0|704&nbsp;B|
|[master](https://github.com/DataDog/dd-trace-dotnet/tree/5129dc8d3adcbb897eb9636eab29d9be7be75544)|`RunOnMethodBegin`|net472|1.13μs|0.674ns|2.52ns|0.102| 0|0|666&nbsp;B|
|#6843|`RunOnMethodBegin`|net6.0|608ns|0.509ns|1.97ns|0.00912| 0|0|704&nbsp;B|
|#6843|`RunOnMethodBegin`|netcoreapp3.1|877ns|1.28ns|4.94ns|0.0088| 0|0|704&nbsp;B|
|#6843|`RunOnMethodBegin`|net472|1.1μs|0.569ns|2.2ns|0.101| 0|0|666&nbsp;B|
</details>


author_association: MEMBER