Consistent Logs for Method Retrieval (#498)
* Log all potentially relevant data in consistent format for method retrieval
This commit is contained in:
parent
2134d7a0f0
commit
8e7cb504c0
|
|
@ -4,7 +4,6 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.InteropServices;
|
||||
using Datadog.Trace.ClrProfiler.Helpers;
|
||||
using Datadog.Trace.Configuration;
|
||||
using Datadog.Trace.Logging;
|
||||
|
|
@ -74,17 +73,11 @@ namespace Datadog.Trace.ClrProfiler.Emit
|
|||
|
||||
public static MethodBuilder<TDelegate> Start(long moduleVersionPtr, int mdToken, int opCode, string methodName)
|
||||
{
|
||||
var ptr = new IntPtr(moduleVersionPtr);
|
||||
|
||||
#if NET45
|
||||
// deprecated
|
||||
var moduleVersionId = (Guid)Marshal.PtrToStructure(ptr, typeof(Guid));
|
||||
#else
|
||||
// added in net451
|
||||
var moduleVersionId = Marshal.PtrToStructure<Guid>(ptr);
|
||||
#endif
|
||||
|
||||
return new MethodBuilder<TDelegate>(moduleVersionId, mdToken, opCode, methodName);
|
||||
return new MethodBuilder<TDelegate>(
|
||||
PointerHelpers.GetGuidFromNativePointer(moduleVersionPtr),
|
||||
mdToken,
|
||||
opCode,
|
||||
methodName);
|
||||
}
|
||||
|
||||
public MethodBuilder<TDelegate> WithConcreteType(Type type)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Datadog.Trace.ClrProfiler.Helpers
|
||||
{
|
||||
internal static class PointerHelpers
|
||||
{
|
||||
public static Guid GetGuidFromNativePointer(long nativePointer)
|
||||
{
|
||||
var ptr = new IntPtr(nativePointer);
|
||||
#if NET45
|
||||
// deprecated
|
||||
var moduleVersionId = (Guid)Marshal.PtrToStructure(ptr, typeof(Guid));
|
||||
#else
|
||||
// added in net451
|
||||
var moduleVersionId = Marshal.PtrToStructure<Guid>(ptr);
|
||||
#endif
|
||||
return moduleVersionId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Datadog.Trace.ClrProfiler.Emit;
|
||||
|
|
@ -20,9 +19,9 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
private const string Major4 = "4";
|
||||
private const string FrameworkAssembly = "System.Data";
|
||||
private const string CoreAssembly = "System.Data.Common";
|
||||
private const string SystemDataCommonDbCommand = "System.Data.Common.DbCommand";
|
||||
private const string SystemDataCommonDbDataReader = "System.Data.Common.DbDataReader";
|
||||
private const string SystemDataCommonCommandBehavior = "System.Data.CommandBehavior";
|
||||
private const string DbCommandTypeName = "System.Data.Common.DbCommand";
|
||||
private const string DbDataReaderTypeName = "System.Data.Common.DbDataReader";
|
||||
private const string CommandBehaviorTypeName = "System.Data.CommandBehavior";
|
||||
|
||||
private static readonly ILog Log = LogProvider.GetLogger(typeof(AdoNetIntegration));
|
||||
|
||||
|
|
@ -37,14 +36,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
/// <returns>The value returned by the instrumented method.</returns>
|
||||
[InterceptMethod(
|
||||
TargetAssembly = FrameworkAssembly, // .NET Framework
|
||||
TargetType = SystemDataCommonDbCommand,
|
||||
TargetSignatureTypes = new[] { SystemDataCommonDbDataReader, SystemDataCommonCommandBehavior },
|
||||
TargetType = DbCommandTypeName,
|
||||
TargetSignatureTypes = new[] { DbDataReaderTypeName, CommandBehaviorTypeName },
|
||||
TargetMinimumVersion = Major4,
|
||||
TargetMaximumVersion = Major4)]
|
||||
[InterceptMethod(
|
||||
TargetAssembly = CoreAssembly, // .NET Core
|
||||
TargetType = SystemDataCommonDbCommand,
|
||||
TargetSignatureTypes = new[] { SystemDataCommonDbDataReader, SystemDataCommonCommandBehavior },
|
||||
TargetType = DbCommandTypeName,
|
||||
TargetSignatureTypes = new[] { DbDataReaderTypeName, CommandBehaviorTypeName },
|
||||
TargetMinimumVersion = Major4,
|
||||
TargetMaximumVersion = Major4)]
|
||||
public static object ExecuteDbDataReader(
|
||||
|
|
@ -54,6 +53,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (@this == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(@this));
|
||||
}
|
||||
|
||||
Func<object, CommandBehavior, object> instrumentedMethod = null;
|
||||
var commandBehavior = (CommandBehavior)behavior;
|
||||
|
||||
|
|
@ -65,12 +69,19 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
.Start(moduleVersionPtr, mdToken, opCode, nameof(ExecuteDbDataReader))
|
||||
.WithConcreteType(instrumentedType)
|
||||
.WithParameters(commandBehavior)
|
||||
.WithNamespaceAndNameFilters(SystemDataCommonDbDataReader, SystemDataCommonCommandBehavior)
|
||||
.WithNamespaceAndNameFilters(DbDataReaderTypeName, CommandBehaviorTypeName)
|
||||
.Build();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {SystemDataCommonDbCommand}.{nameof(ExecuteDbDataReader)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: DbCommandTypeName,
|
||||
methodName: nameof(ExecuteDbDataReader),
|
||||
instanceType: @this.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -100,14 +111,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
/// <returns>The value returned by the instrumented method.</returns>
|
||||
[InterceptMethod(
|
||||
TargetAssembly = FrameworkAssembly, // .NET Framework
|
||||
TargetType = SystemDataCommonDbCommand,
|
||||
TargetSignatureTypes = new[] { "System.Threading.Tasks.Task`1<System.Data.Common.DbDataReader>", SystemDataCommonCommandBehavior, ClrNames.CancellationToken },
|
||||
TargetType = DbCommandTypeName,
|
||||
TargetSignatureTypes = new[] { "System.Threading.Tasks.Task`1<System.Data.Common.DbDataReader>", CommandBehaviorTypeName, ClrNames.CancellationToken },
|
||||
TargetMinimumVersion = Major4,
|
||||
TargetMaximumVersion = Major4)]
|
||||
[InterceptMethod(
|
||||
TargetAssembly = CoreAssembly, // .NET Core
|
||||
TargetType = SystemDataCommonDbCommand,
|
||||
TargetSignatureTypes = new[] { "System.Threading.Tasks.Task`1<System.Data.Common.DbDataReader>", SystemDataCommonCommandBehavior, ClrNames.CancellationToken },
|
||||
TargetType = DbCommandTypeName,
|
||||
TargetSignatureTypes = new[] { "System.Threading.Tasks.Task`1<System.Data.Common.DbDataReader>", CommandBehaviorTypeName, ClrNames.CancellationToken },
|
||||
TargetMinimumVersion = Major4,
|
||||
TargetMaximumVersion = Major4)]
|
||||
public static object ExecuteDbDataReaderAsync(
|
||||
|
|
@ -118,6 +129,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (@this == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(@this));
|
||||
}
|
||||
|
||||
var tokenSource = cancellationTokenSource as CancellationTokenSource;
|
||||
var cancellationToken = tokenSource?.Token ?? CancellationToken.None;
|
||||
var instrumentedType = typeof(DbCommand);
|
||||
|
|
@ -132,12 +148,19 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
.Start(moduleVersionPtr, mdToken, opCode, nameof(ExecuteDbDataReaderAsync))
|
||||
.WithConcreteType(instrumentedType)
|
||||
.WithParameters(commandBehavior, cancellationToken)
|
||||
.WithNamespaceAndNameFilters(ClrNames.GenericTask, SystemDataCommonCommandBehavior, ClrNames.CancellationToken)
|
||||
.WithNamespaceAndNameFilters(ClrNames.GenericTask, CommandBehaviorTypeName, ClrNames.CancellationToken)
|
||||
.Build();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {SystemDataCommonDbCommand}.{nameof(ExecuteDbDataReaderAsync)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: DbCommandTypeName,
|
||||
methodName: nameof(ExecuteDbDataReaderAsync),
|
||||
instanceType: @this.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,15 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will continue working as expected without this method
|
||||
Log.ErrorException($"Error resolving {DiagnosticSourceTypeName}.{nameof(BeforeAction)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: DiagnosticSourceTypeName,
|
||||
methodName: nameof(BeforeAction),
|
||||
instanceType: null,
|
||||
relevantArguments: new[] { diagnosticSource?.GetType().AssemblyQualifiedName });
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -266,7 +274,15 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will continue working as expected without this method
|
||||
Log.ErrorException($"Error resolving {methodDef}", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: DiagnosticSourceTypeName,
|
||||
methodName: nameof(AfterAction),
|
||||
instanceType: null,
|
||||
relevantArguments: new[] { diagnosticSource?.GetType().AssemblyQualifiedName });
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -326,10 +342,15 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
var contextTypeName = context.GetType().FullName + " ";
|
||||
var methodDef = $"{ResourceInvokerTypeName}.{nameof(Rethrow)}({contextTypeName} context)";
|
||||
Log.ErrorException($"Error retrieving {methodDef}", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: ResourceInvokerTypeName,
|
||||
methodName: nameof(Rethrow),
|
||||
instanceType: null,
|
||||
relevantArguments: new[] { context.GetType().AssemblyQualifiedName });
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,6 +183,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (asyncControllerActionInvoker == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(asyncControllerActionInvoker));
|
||||
}
|
||||
|
||||
Scope scope = null;
|
||||
|
||||
try
|
||||
|
|
@ -218,7 +223,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {AsyncActionInvokerTypeName}.{nameof(BeginInvokeAction)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: AsyncActionInvokerTypeName,
|
||||
methodName: nameof(BeginInvokeAction),
|
||||
instanceType: asyncControllerActionInvoker.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -257,6 +269,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (asyncControllerActionInvoker == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(asyncControllerActionInvoker));
|
||||
}
|
||||
|
||||
Scope scope = null;
|
||||
var httpContext = HttpContext.Current;
|
||||
|
||||
|
|
@ -284,7 +301,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {AsyncActionInvokerTypeName}.{nameof(EndInvokeAction)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: AsyncActionInvokerTypeName,
|
||||
methodName: nameof(EndInvokeAction),
|
||||
instanceType: asyncControllerActionInvoker.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {HttpControllerTypeName}.{nameof(ExecuteAsync)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: HttpControllerTypeName,
|
||||
methodName: nameof(ExecuteAsync),
|
||||
instanceType: apiController.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
public static class HttpContextIntegration
|
||||
{
|
||||
private const string IntegrationName = "HttpContext";
|
||||
private const string DefaultHttpContextTypeName = "Microsoft.AspNetCore.Http.DefaultHttpContext";
|
||||
private static readonly ILog Log = LogProvider.GetLogger(typeof(HttpContextIntegration));
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -22,15 +23,19 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
/// <param name="moduleVersionPtr">A pointer to the module version GUID.</param>
|
||||
// [InterceptMethod(
|
||||
// TargetAssembly = "Microsoft.AspNetCore.Http.Abstractions",
|
||||
// TargetType = "Microsoft.AspNetCore.Http.DefaultHttpContext",
|
||||
// TargetType = DefaultHttpContextTypeName,
|
||||
// TargetSignatureTypes = new[] { ClrNames.Void, ClrNames.Ignore })]
|
||||
// ***************************************************************
|
||||
// DISABLED UNTIL WE FIX SCOPING ISSUES AT HTTP CONTEXT LEVEL
|
||||
// ***************************************************************
|
||||
public static void Initialize(object httpContext, object features, int opCode, int mdToken, long moduleVersionPtr)
|
||||
{
|
||||
var httpContextType = httpContext.GetType();
|
||||
string methodDef = $"{httpContextType.FullName}.Initialize(IFeatureCollection features)";
|
||||
if (httpContext == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(httpContext));
|
||||
}
|
||||
|
||||
var httpContextType = httpContext.GetInstrumentedType(DefaultHttpContextTypeName);
|
||||
|
||||
Action<object, object> instrumentedMethod;
|
||||
|
||||
|
|
@ -45,7 +50,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error retrieving {methodDef}", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: DefaultHttpContextTypeName,
|
||||
methodName: nameof(Initialize),
|
||||
instanceType: httpContext.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +67,7 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error calling {methodDef}", ex);
|
||||
Log.ErrorException($"Error calling {DefaultHttpContextTypeName}.{nameof(Initialize)}(...)", ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
private const string IntegrationName = "ElasticsearchNet5";
|
||||
private const string Version5 = "5";
|
||||
private const string ElasticsearchAssembly = "Elasticsearch.Net";
|
||||
private const string RequestPipelineInterface = "Elasticsearch.Net.IRequestPipeline";
|
||||
private const string RequestPipelineInterfaceTypeName = "Elasticsearch.Net.IRequestPipeline";
|
||||
|
||||
private static readonly ILog Log = LogProvider.GetLogger(typeof(ElasticsearchNet5Integration));
|
||||
private static readonly Type ElasticsearchResponseType = Type.GetType("Elasticsearch.Net.ElasticsearchResponse`1, Elasticsearch.Net", throwOnError: false);
|
||||
|
|
@ -33,7 +33,7 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
[InterceptMethod(
|
||||
CallerAssembly = ElasticsearchAssembly,
|
||||
TargetAssembly = ElasticsearchAssembly,
|
||||
TargetType = RequestPipelineInterface,
|
||||
TargetType = RequestPipelineInterfaceTypeName,
|
||||
TargetSignatureTypes = new[] { "Elasticsearch.Net.ElasticsearchResponse`1<T>", "Elasticsearch.Net.RequestData" },
|
||||
TargetMinimumVersion = Version5,
|
||||
TargetMaximumVersion = Version5)]
|
||||
|
|
@ -44,6 +44,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (pipeline == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(pipeline));
|
||||
}
|
||||
|
||||
const string methodName = nameof(CallElasticsearch);
|
||||
Func<object, object, object> callElasticSearch;
|
||||
var pipelineType = pipeline.GetType();
|
||||
|
|
@ -62,8 +67,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error retrieving {pipelineType.Name}.{methodName}(RequestData requestData)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: RequestPipelineInterfaceTypeName,
|
||||
methodName: methodName,
|
||||
instanceType: pipeline.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +106,7 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
[InterceptMethod(
|
||||
CallerAssembly = ElasticsearchAssembly,
|
||||
TargetAssembly = ElasticsearchAssembly,
|
||||
TargetType = RequestPipelineInterface,
|
||||
TargetType = RequestPipelineInterfaceTypeName,
|
||||
TargetSignatureTypes = new[] { "System.Threading.Tasks.Task`1<Elasticsearch.Net.ElasticsearchResponse`1<T>>", "Elasticsearch.Net.RequestData", ClrNames.CancellationToken },
|
||||
TargetMinimumVersion = Version5,
|
||||
TargetMaximumVersion = Version5)]
|
||||
|
|
@ -107,6 +118,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (pipeline == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(pipeline));
|
||||
}
|
||||
|
||||
var tokenSource = cancellationTokenSource as CancellationTokenSource;
|
||||
var cancellationToken = tokenSource?.Token ?? CancellationToken.None;
|
||||
|
||||
|
|
@ -129,7 +145,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving Elasticsearch.Net.IRequestPipeline.{nameof(CallElasticsearchAsync)}<T>(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: RequestPipelineInterfaceTypeName,
|
||||
methodName: nameof(CallElasticsearchAsync),
|
||||
instanceType: pipeline.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
// NOTE: keep this name without the 6 to avoid breaking changes
|
||||
private const string IntegrationName = "ElasticsearchNet";
|
||||
private const string Version6 = "6";
|
||||
private const string ElasticsearchAssemblyName = "Elasticsearch.Net";
|
||||
private const string RequestPipelineInterfaceTypeName = "Elasticsearch.Net.IRequestPipeline";
|
||||
|
||||
private static readonly ILog Log = LogProvider.GetLogger(typeof(ElasticsearchNet6Integration));
|
||||
|
||||
|
|
@ -28,9 +30,9 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
/// <param name="moduleVersionPtr">A pointer to the module version GUID.</param>
|
||||
/// <returns>The original result</returns>
|
||||
[InterceptMethod(
|
||||
CallerAssembly = "Elasticsearch.Net",
|
||||
TargetAssembly = "Elasticsearch.Net",
|
||||
TargetType = "Elasticsearch.Net.IRequestPipeline",
|
||||
CallerAssembly = ElasticsearchAssemblyName,
|
||||
TargetAssembly = ElasticsearchAssemblyName,
|
||||
TargetType = RequestPipelineInterfaceTypeName,
|
||||
TargetSignatureTypes = new[] { "T", "Elasticsearch.Net.RequestData" },
|
||||
TargetMinimumVersion = Version6,
|
||||
TargetMaximumVersion = Version6)]
|
||||
|
|
@ -41,6 +43,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (pipeline == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(pipeline));
|
||||
}
|
||||
|
||||
const string methodName = nameof(CallElasticsearch);
|
||||
Func<object, object, TResponse> callElasticSearch;
|
||||
var pipelineType = pipeline.GetType();
|
||||
|
|
@ -60,7 +67,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error retrieving {pipelineType.Name}.{methodName}(RequestData requestData)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: RequestPipelineInterfaceTypeName,
|
||||
methodName: methodName,
|
||||
instanceType: pipeline.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -90,9 +104,9 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
/// <param name="moduleVersionPtr">A pointer to the module version GUID.</param>
|
||||
/// <returns>The original result</returns>
|
||||
[InterceptMethod(
|
||||
CallerAssembly = "Elasticsearch.Net",
|
||||
TargetAssembly = "Elasticsearch.Net",
|
||||
TargetType = "Elasticsearch.Net.IRequestPipeline",
|
||||
CallerAssembly = ElasticsearchAssemblyName,
|
||||
TargetAssembly = ElasticsearchAssemblyName,
|
||||
TargetType = RequestPipelineInterfaceTypeName,
|
||||
TargetSignatureTypes = new[] { "System.Threading.Tasks.Task`1<T>", "Elasticsearch.Net.RequestData", ClrNames.CancellationToken },
|
||||
TargetMinimumVersion = Version6,
|
||||
TargetMaximumVersion = Version6)]
|
||||
|
|
@ -146,8 +160,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error retrieving {pipelineType.Name}.{methodName}(RequestData requestData, CancellationToken cancellationToken)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: RequestPipelineInterfaceTypeName,
|
||||
methodName: methodName,
|
||||
instanceType: pipelineType.AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,16 +73,12 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
|
||||
// At runtime, get a Type object for GraphQL.ExecutionResult
|
||||
var documentValidatorInstanceType = documentValidator.GetType();
|
||||
Type graphQLExecutionResultType;
|
||||
Type documentValidatorInterfaceType;
|
||||
|
||||
try
|
||||
{
|
||||
var graphQLAssembly = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Where(a => a.GetName().Name.Equals(GraphQLAssemblyName))
|
||||
.Single();
|
||||
graphQLExecutionResultType = graphQLAssembly.GetType(GraphQLExecutionResultName, throwOnError: true);
|
||||
documentValidatorInterfaceType = graphQLAssembly.GetType(GraphQLDocumentValidatorInterfaceName, throwOnError: true);
|
||||
var graphQLAssembly = AppDomain.CurrentDomain
|
||||
.GetAssemblies()
|
||||
.Single(a => a.GetName().Name.Equals(GraphQLAssemblyName));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -113,8 +109,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error resolving {documentValidatorInterfaceType.Name}.{methodName}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: GraphQLDocumentValidatorInterfaceName,
|
||||
methodName: methodName,
|
||||
instanceType: documentValidator.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -189,8 +191,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error resolving {executionStrategyInterfaceType.Name}.{methodName}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: GraphQLExecutionStrategyInterfaceName,
|
||||
methodName: methodName,
|
||||
instanceType: executionStrategy.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(handler));
|
||||
}
|
||||
|
||||
// original signature:
|
||||
// Task<HttpResponseMessage> HttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
var tokenSource = cancellationTokenSource as CancellationTokenSource;
|
||||
|
|
@ -70,7 +75,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {HttpMessageHandler}.{SendAsync}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: HttpMessageHandler,
|
||||
methodName: SendAsync,
|
||||
instanceType: handler.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -107,6 +119,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (handler == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(handler));
|
||||
}
|
||||
|
||||
// original signature:
|
||||
// Task<HttpResponseMessage> HttpClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
var tokenSource = cancellationTokenSource as CancellationTokenSource;
|
||||
|
|
@ -128,7 +145,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {HttpClientHandler}.{SendAsync}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: HttpClientHandler,
|
||||
methodName: SendAsync,
|
||||
instanceType: handler.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using Datadog.Trace.ClrProfiler.Helpers;
|
||||
using Datadog.Trace.Logging;
|
||||
|
||||
namespace Datadog.Trace.ClrProfiler.Integrations
|
||||
{
|
||||
internal static class LoggerExtensions
|
||||
{
|
||||
public static void ErrorRetrievingMethod(
|
||||
this ILog logger,
|
||||
Exception exception,
|
||||
long moduleVersionPointer,
|
||||
int mdToken,
|
||||
int opCode,
|
||||
string instrumentedType,
|
||||
string methodName,
|
||||
string instanceType = null,
|
||||
string[] relevantArguments = null)
|
||||
{
|
||||
var instrumentedMethod = $"{instrumentedType}.{methodName}(...)";
|
||||
|
||||
if (instanceType != null)
|
||||
{
|
||||
instrumentedMethod = $"{instrumentedMethod} on {instanceType}";
|
||||
}
|
||||
|
||||
if (relevantArguments != null)
|
||||
{
|
||||
instrumentedMethod = $"{instrumentedMethod} with {string.Join(", ", relevantArguments)}";
|
||||
}
|
||||
|
||||
var moduleVersionId = PointerHelpers.GetGuidFromNativePointer(moduleVersionPointer);
|
||||
logger.ErrorException(
|
||||
message: $"Error (MVID: {moduleVersionId}, mdToken: {mdToken}, opCode: {opCode}) could not retrieve: {instrumentedMethod}",
|
||||
exception: exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -71,8 +71,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error retrieving {wireProtocolType.Name}.{methodName}(IConnection connection, CancellationToken cancellationToken)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: IWireProtocol,
|
||||
methodName: methodName,
|
||||
instanceType: wireProtocol.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -136,8 +142,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error retrieving {wireProtocolType.Name}.{methodName}(IConnection connection, CancellationToken cancellationToken)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: IWireProtocolGeneric,
|
||||
methodName: methodName,
|
||||
instanceType: wireProtocol.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -204,8 +216,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error calling {wireProtocolType.Name}.{methodName}(IConnection connection, CancellationToken cancellationToken)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: IWireProtocolGeneric,
|
||||
methodName: methodName,
|
||||
instanceType: wireProtocol.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (redisNativeClient == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(redisNativeClient));
|
||||
}
|
||||
|
||||
Func<object, byte[][], object, object, bool, T> instrumentedMethod;
|
||||
|
||||
try
|
||||
|
|
@ -64,7 +69,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {RedisNativeClient}.{nameof(SendReceive)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: RedisNativeClient,
|
||||
methodName: nameof(SendReceive),
|
||||
instanceType: redisNativeClient.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error resolving {ConnectionMultiplexerTypeName}.{nameof(ExecuteSyncImpl)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: ConnectionMultiplexerTypeName,
|
||||
methodName: nameof(ExecuteSyncImpl),
|
||||
instanceType: multiplexer.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -173,8 +179,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error resolving {ConnectionMultiplexerTypeName}.{nameof(ExecuteAsyncImpl)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: ConnectionMultiplexerTypeName,
|
||||
methodName: nameof(ExecuteAsyncImpl),
|
||||
instanceType: multiplexer.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Datadog.Trace.ClrProfiler.Emit;
|
||||
using Datadog.Trace.Logging;
|
||||
|
||||
namespace Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis
|
||||
{
|
||||
|
|
@ -17,6 +18,8 @@ namespace Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis
|
|||
private const string Major1 = "1";
|
||||
private const string Major2 = "2";
|
||||
|
||||
private static readonly ILog Log = LogProvider.GetLogger(typeof(RedisBatch));
|
||||
|
||||
private static Assembly _redisAssembly;
|
||||
private static Type _redisBaseType;
|
||||
private static Type _batchType;
|
||||
|
|
@ -103,17 +106,34 @@ namespace Datadog.Trace.ClrProfiler.Integrations.StackExchange.Redis
|
|||
_batchType = _redisAssembly.GetType("StackExchange.Redis.RedisBatch");
|
||||
}
|
||||
|
||||
var instrumentedMethod = MethodBuilder<Func<object, object, object, object, Task<T>>>
|
||||
.Start(moduleVersionPtr, mdToken, callOpCode, nameof(ExecuteAsync))
|
||||
.WithConcreteType(_redisBaseType)
|
||||
.WithMethodGenerics(typeof(T))
|
||||
.WithParameters(message, processor, server)
|
||||
.WithNamespaceAndNameFilters(
|
||||
ClrNames.GenericTask,
|
||||
"StackExchange.Redis.Message",
|
||||
"StackExchange.Redis.ResultProcessor`1",
|
||||
"StackExchange.Redis.ServerEndPoint")
|
||||
.Build();
|
||||
Func<object, object, object, object, Task<T>> instrumentedMethod;
|
||||
|
||||
try
|
||||
{
|
||||
instrumentedMethod = MethodBuilder<Func<object, object, object, object, Task<T>>>
|
||||
.Start(moduleVersionPtr, mdToken, callOpCode, nameof(ExecuteAsync))
|
||||
.WithConcreteType(_redisBaseType)
|
||||
.WithMethodGenerics(typeof(T))
|
||||
.WithParameters(message, processor, server)
|
||||
.WithNamespaceAndNameFilters(
|
||||
ClrNames.GenericTask,
|
||||
"StackExchange.Redis.Message",
|
||||
"StackExchange.Redis.ResultProcessor`1",
|
||||
"StackExchange.Redis.ServerEndPoint")
|
||||
.Build();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: callOpCode,
|
||||
instrumentedType: RedisBaseTypeName,
|
||||
methodName: nameof(ExecuteAsync),
|
||||
instanceType: thisType.AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
// we only trace RedisBatch methods here
|
||||
if (thisType == _batchType)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,11 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
int mdToken,
|
||||
long moduleVersionPtr)
|
||||
{
|
||||
if (channelHandler == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(channelHandler));
|
||||
}
|
||||
|
||||
Func<object, object, object, bool> instrumentedMethod;
|
||||
var declaringType = channelHandler.GetInstrumentedType(ChannelHandlerTypeName);
|
||||
|
||||
|
|
@ -63,7 +68,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException($"Error resolving {ChannelHandlerTypeName}.{nameof(HandleRequest)}(...)", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: ChannelHandlerTypeName,
|
||||
methodName: nameof(HandleRequest),
|
||||
instanceType: channelHandler.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
/// </summary>
|
||||
public static class WebRequestIntegration
|
||||
{
|
||||
private const string WebRequestTypeName = "System.Net.WebRequest";
|
||||
private const string IntegrationName = "WebRequest";
|
||||
private const string Major4 = "4";
|
||||
|
||||
|
|
@ -27,18 +28,23 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
/// <returns>Returns the value returned by the inner method call.</returns>
|
||||
[InterceptMethod(
|
||||
TargetAssembly = "System", // .NET Framework
|
||||
TargetType = "System.Net.WebRequest",
|
||||
TargetType = WebRequestTypeName,
|
||||
TargetSignatureTypes = new[] { "System.Net.WebResponse" },
|
||||
TargetMinimumVersion = Major4,
|
||||
TargetMaximumVersion = Major4)]
|
||||
[InterceptMethod(
|
||||
TargetAssembly = "System.Net.Requests", // .NET Core
|
||||
TargetType = "System.Net.WebRequest",
|
||||
TargetType = WebRequestTypeName,
|
||||
TargetSignatureTypes = new[] { "System.Net.WebResponse" },
|
||||
TargetMinimumVersion = Major4,
|
||||
TargetMaximumVersion = Major4)]
|
||||
public static object GetResponse(object webRequest, int opCode, int mdToken, long moduleVersionPtr)
|
||||
{
|
||||
if (webRequest == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(webRequest));
|
||||
}
|
||||
|
||||
const string methodName = nameof(GetResponse);
|
||||
|
||||
Func<object, WebResponse> callGetResponse;
|
||||
|
|
@ -55,8 +61,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error retrieving System.Net.WebRequest.{methodName}()", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: WebRequestTypeName,
|
||||
methodName: methodName,
|
||||
instanceType: webRequest.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +116,7 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
/// <returns>Returns the value returned by the inner method call.</returns>
|
||||
[InterceptMethod(
|
||||
TargetAssembly = "System.Net",
|
||||
TargetType = "System.Net.WebRequest",
|
||||
TargetType = WebRequestTypeName,
|
||||
TargetSignatureTypes = new[] { "System.Threading.Tasks.Task`1<System.Net.WebResponse>" },
|
||||
TargetMinimumVersion = Major4,
|
||||
TargetMaximumVersion = Major4)]
|
||||
|
|
@ -125,8 +137,14 @@ namespace Datadog.Trace.ClrProfiler.Integrations
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// profiled app will not continue working as expected without this method
|
||||
Log.ErrorException($"Error retrieving System.Net.WebRequest.{methodName}()", ex);
|
||||
Log.ErrorRetrievingMethod(
|
||||
exception: ex,
|
||||
moduleVersionPointer: moduleVersionPtr,
|
||||
mdToken: mdToken,
|
||||
opCode: opCode,
|
||||
instrumentedType: WebRequestTypeName,
|
||||
methodName: methodName,
|
||||
instanceType: webRequest.GetType().AssemblyQualifiedName);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Datadog.Trace.Tests
|
|||
/// </summary>
|
||||
private static ulong _maxId = ulong.MaxValue / 2;
|
||||
private static int _numberOfBuckets = 20;
|
||||
private static ulong _numberOfIdsToGenerate = 3_000_000;
|
||||
private static ulong _numberOfIdsToGenerate = 1_500_000;
|
||||
|
||||
// Helper numbers for logging and calculating
|
||||
private static decimal _bucketSizePercentage = 100 / _numberOfBuckets;
|
||||
|
|
@ -135,7 +135,7 @@ namespace Datadog.Trace.Tests
|
|||
var biggestDiff = new[] { maxDiff, minDiff }.Max();
|
||||
var variance = biggestDiff / actualApproximateBucketSize;
|
||||
|
||||
var maximumVariance = 0.01m;
|
||||
var maximumVariance = 0.05m;
|
||||
_output.WriteLine($"The maximum variance in all buckets is {variance}.");
|
||||
Assert.True(maximumVariance >= variance, $"The variance between buckets should be less than {maximumVariance}, but it is {variance}.");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue