public static T ExecuteSyncImpl <T>( object multiplexer, object message, object processor, object server, int opCode, int mdToken, long moduleVersionPtr) { if (multiplexer == null) { throw new ArgumentNullException(nameof(multiplexer)); } var genericType = typeof(T); var multiplexerType = multiplexer.GetInstrumentedType(ConnectionMultiplexerTypeName); Func <object, object, object, object, T> instrumentedMethod; try { instrumentedMethod = MethodBuilder <Func <object, object, object, object, T> > .Start(moduleVersionPtr, mdToken, opCode, nameof(ExecuteSyncImpl)) .WithConcreteType(multiplexerType) .WithParameters(message, processor, server) .WithMethodGenerics(genericType) .WithNamespaceAndNameFilters( ClrNames.Ignore, StackExchangeRedisMessage, StackExchangeRedisResultProcessor, StackExchangeRedisServerEndPoint) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: ConnectionMultiplexerTypeName, methodName: nameof(ExecuteSyncImpl), instanceType: multiplexer.GetType().AssemblyQualifiedName); throw; } using (var scope = CreateScope(multiplexer, message)) { try { return(instrumentedMethod(multiplexer, message, processor, server)); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object CallElasticsearch <TResponse>( object pipeline, object requestData, int opCode, 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(); var genericArgument = typeof(TResponse); try { callElasticSearch = MethodBuilder <Func <object, object, TResponse> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(pipelineType) .WithMethodGenerics(genericArgument) .WithParameters(requestData) .WithNamespaceAndNameFilters(ClrNames.Ignore, "Elasticsearch.Net.RequestData") .Build(); } catch (Exception ex) { // profiled app will not continue working as expected without this method Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: RequestPipelineInterfaceTypeName, methodName: methodName, instanceType: pipeline.GetType().AssemblyQualifiedName); throw; } using (var scope = ElasticsearchNetCommon.CreateScope(Tracer.Instance, IntegrationName, pipeline, requestData)) { try { var returned = callElasticSearch(pipeline, requestData); scope?.Span.SetDbStatementFromRequestData(requestData); return(returned); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
public static object Execute( object wireProtocol, object connection, object cancellationTokenSource, int opCode, int mdToken, long moduleVersionPtr) { if (wireProtocol == null) { throw new ArgumentNullException(nameof(wireProtocol)); } const string methodName = nameof(Execute); Func <object, object, CancellationToken, object> execute; var wireProtocolType = wireProtocol.GetType(); var tokenSource = cancellationTokenSource as CancellationTokenSource; var cancellationToken = tokenSource?.Token ?? CancellationToken.None; try { execute = MethodBuilder <Func <object, object, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(wireProtocolType) .WithParameters(connection, cancellationToken) .WithNamespaceAndNameFilters(ClrNames.Void, "MongoDB.Driver.Core.Connections.IConnection", ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: IWireProtocol, methodName: methodName, instanceType: wireProtocol.GetType().AssemblyQualifiedName); throw; } using (var scope = CreateScope(wireProtocol, connection)) { try { return(execute(wireProtocol, connection, cancellationToken)); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
public static void InvokePreStartInitMethods( object methodInfoCollection, int opCode, int mdToken, long moduleVersionPtr) { // The whole point of instrumenting a method so early on in the application load process // is to register our HttpModule. HttpApplication.RegisterModule(typeof(TracingHttpModule)); Action <object> instrumentedMethod; Type concreteType = null; try { var module = ModuleLookup.GetByPointer(moduleVersionPtr); concreteType = module.GetType(BuildManagerTypeName); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: BuildManagerTypeName, methodName: nameof(InvokePreStartInitMethods), instanceType: null, relevantArguments: new[] { concreteType?.AssemblyQualifiedName }); throw; } try { instrumentedMethod = MethodBuilder <Action <object> > .Start(moduleVersionPtr, mdToken, opCode, nameof(InvokePreStartInitMethods)) .WithParameters(methodInfoCollection) .WithConcreteType(concreteType) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, null, methodName: nameof(InvokePreStartInitMethods)); throw; } instrumentedMethod(methodInfoCollection); }
public static void Execute( object wireProtocol, object connection, object boxedCancellationToken, int opCode, int mdToken, long moduleVersionPtr) { if (wireProtocol == null) { throw new ArgumentNullException(nameof(wireProtocol)); } const string methodName = nameof(Execute); Action <object, object, CancellationToken> execute; var wireProtocolType = wireProtocol.GetType(); var cancellationToken = (CancellationToken)boxedCancellationToken; try { execute = MethodBuilder <Action <object, object, CancellationToken> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(wireProtocolType) .WithParameters(connection, cancellationToken) .WithNamespaceAndNameFilters(ClrNames.Void, "MongoDB.Driver.Core.Connections.IConnection", ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: IWireProtocol, methodName: methodName, instanceType: wireProtocol.GetType().AssemblyQualifiedName); throw; } using (var scope = CreateScope(wireProtocol, connection)) { try { execute(wireProtocol, connection, cancellationToken); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object CallElasticsearch <TResponse>( object pipeline, object requestData, int opCode, 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(); var genericArgument = typeof(TResponse); try { callElasticSearch = MethodBuilder <Func <object, object, object> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(pipelineType) .WithMethodGenerics(genericArgument) .WithNamespaceAndNameFilters("Elasticsearch.Net.ElasticsearchResponse`1", "Elasticsearch.Net.RequestData") .WithParameters(requestData) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: RequestPipelineInterfaceTypeName, methodName: methodName, instanceType: pipeline.GetType().AssemblyQualifiedName); throw; } using (var scope = ElasticsearchNetCommon.CreateScope(Tracer.Instance, IntegrationName, pipeline, requestData)) { try { return(callElasticSearch(pipeline, requestData)); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object HttpMessageHandler_SendAsync( object handler, object request, object cancellationTokenSource, int opCode, 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; var cancellationToken = tokenSource?.Token ?? CancellationToken.None; var callOpCode = (OpCodeValue)opCode; var httpMessageHandler = typeof(HttpMessageHandler); // Note the HttpMessageHandler to match the method call we replaced Func <HttpMessageHandler, HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > instrumentedMethod = null; try { instrumentedMethod = MethodBuilder <Func <HttpMessageHandler, HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > > .Start(moduleVersionPtr, mdToken, opCode, SendAsync) .WithConcreteType(httpMessageHandler) .WithParameters(request, cancellationToken) .WithNamespaceAndNameFilters(ClrNames.GenericTask, ClrNames.HttpRequestMessage, ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: HttpMessageHandler, methodName: SendAsync, instanceType: handler.GetType().AssemblyQualifiedName); throw; } return(SendAsyncInternal( instrumentedMethod, reportedType: callOpCode == OpCodeValue.Call ? httpMessageHandler : handler.GetType(), (HttpMessageHandler)handler, (HttpRequestMessage)request, cancellationToken)); }
public static object ExecuteReader( object command, int opCode, int mdToken, long moduleVersionPtr) { const string methodName = AdoNetConstants.MethodNames.ExecuteReader; Func <IDbCommand, IDataReader> instrumentedMethod; try { var targetType = command.GetInstrumentedInterface(IDbCommandTypeName); instrumentedMethod = MethodBuilder <Func <IDbCommand, IDataReader> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(targetType) .WithNamespaceAndNameFilters(AdoNetConstants.TypeNames.IDataReader) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: IDbCommandTypeName, methodName: methodName, instanceType: command.GetType().AssemblyQualifiedName); throw; } var dbCommand = command as IDbCommand; using (var scope = ScopeFactory.CreateDbCommandScope(Tracer.Instance, dbCommand, IntegrationName)) { try { return(instrumentedMethod(dbCommand)); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static T SendReceive <T>( object redisNativeClient, byte[][] cmdWithBinaryArgs, object fn, object completePipelineFn, bool sendWithoutRead, int opCode, int mdToken, long moduleVersionPtr) { if (redisNativeClient == null) { throw new ArgumentNullException(nameof(redisNativeClient)); } Func <object, byte[][], object, object, bool, T> instrumentedMethod; try { var instrumentedType = redisNativeClient.GetInstrumentedType(RedisNativeClient); instrumentedMethod = MethodBuilder <Func <object, byte[][], object, object, bool, T> > .Start(moduleVersionPtr, mdToken, opCode, nameof(SendReceive)) .WithConcreteType(instrumentedType) .WithParameters(cmdWithBinaryArgs, fn, completePipelineFn, sendWithoutRead) .WithMethodGenerics(typeof(T)) .WithNamespaceAndNameFilters(ClrNames.Ignore, "System.Byte[][]", "System.Func`1", "System.Action`1", ClrNames.Bool) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: RedisNativeClient, methodName: nameof(SendReceive), instanceType: redisNativeClient.GetType().AssemblyQualifiedName); throw; } using (var scope = RedisHelper.CreateScope( Tracer.Instance, IntegrationName, GetHost(redisNativeClient), GetPort(redisNativeClient), GetRawCommand(cmdWithBinaryArgs))) { try { return(instrumentedMethod(redisNativeClient, cmdWithBinaryArgs, fn, completePipelineFn, sendWithoutRead)); } catch (Exception ex) { scope?.Span?.SetException(ex); throw; } } }
/// <summary> /// Calls the underlying ExecuteAsync and traces the request. /// </summary> /// <param name="apiController">The Api Controller</param> /// <param name="controllerContext">The controller context for the call</param> /// <param name="cancellationToken">The cancellation token</param> /// <param name="opCode">The OpCode used in the original method call.</param> /// <param name="mdToken">The mdToken of the original method call.</param> /// <param name="moduleVersionPtr">A pointer to the module version GUID.</param> /// <returns>A task with the result</returns> private static async Task <HttpResponseMessage> ExecuteAsyncInternal( object apiController, object controllerContext, CancellationToken cancellationToken, int opCode, int mdToken, long moduleVersionPtr) { Func <object, object, CancellationToken, Task <HttpResponseMessage> > instrumentedMethod; try { var httpControllerType = apiController.GetInstrumentedInterface(HttpControllerTypeName); instrumentedMethod = MethodBuilder <Func <object, object, CancellationToken, Task <HttpResponseMessage> > > .Start(moduleVersionPtr, mdToken, opCode, nameof(ExecuteAsync)) .WithConcreteType(httpControllerType) .WithParameters(controllerContext, cancellationToken) .WithNamespaceAndNameFilters( ClrNames.HttpResponseMessageTask, HttpControllerContextTypeName, ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: HttpControllerTypeName, methodName: nameof(ExecuteAsync), instanceType: apiController.GetType().AssemblyQualifiedName); throw; } using (Scope scope = CreateScope(controllerContext)) { try { // call the original method, inspecting (but not catching) any unhandled exceptions var responseMessage = await instrumentedMethod(apiController, controllerContext, cancellationToken).ConfigureAwait(false); if (scope != null) { // some fields aren't set till after execution, so populate anything missing UpdateSpan(controllerContext, scope.Span); } return(responseMessage); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static bool HandleRequest( object channelHandler, object requestContext, object currentOperationContext, int opCode, int mdToken, long moduleVersionPtr) { if (channelHandler == null) { throw new ArgumentNullException(nameof(channelHandler)); } Func <object, object, object, bool> instrumentedMethod; var declaringType = channelHandler.GetInstrumentedType(ChannelHandlerTypeName); try { instrumentedMethod = MethodBuilder <Func <object, object, object, bool> > .Start(moduleVersionPtr, mdToken, opCode, nameof(HandleRequest)) .WithConcreteType(declaringType) .WithParameters(requestContext, currentOperationContext) .WithNamespaceAndNameFilters( ClrNames.Bool, "System.ServiceModel.Channels.RequestContext", "System.ServiceModel.OperationContext") .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: ChannelHandlerTypeName, methodName: nameof(HandleRequest), instanceType: channelHandler.GetType().AssemblyQualifiedName); throw; } using (var scope = CreateScope(requestContext)) { try { return(instrumentedMethod(channelHandler, requestContext, currentOperationContext)); } catch (Exception ex) { scope.Span.SetException(ex); throw; } } }
/// <summary> /// Entry method for invoking the beginning of every web server request pipeline /// </summary> /// <param name="httpContext">Instance being instrumented.</param> /// <param name="features">Initialize features.</param> /// <param name="opCode">The OpCode used in the original method call.</param> /// <param name="mdToken">The mdToken of the original method call.</param> /// <param name="moduleVersionPtr">A pointer to the module version GUID.</param> // [InterceptMethod( // TargetAssembly = "Microsoft.AspNetCore.Http.Abstractions", // 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) { if (httpContext == null) { throw new ArgumentNullException(nameof(httpContext)); } var httpContextType = httpContext.GetInstrumentedType(DefaultHttpContextTypeName); Action <object, object> instrumentedMethod; try { instrumentedMethod = MethodBuilder <Action <object, object> > .Start(moduleVersionPtr, mdToken, opCode, nameof(Initialize)) .WithConcreteType(httpContextType) .WithParameters(features) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: DefaultHttpContextTypeName, methodName: nameof(Initialize), instanceType: httpContext.GetType().AssemblyQualifiedName); throw; } try { instrumentedMethod.Invoke(httpContext, features); } catch (Exception ex) { Log.Error(ex, $"Error calling {DefaultHttpContextTypeName}.{nameof(Initialize)}(...)"); throw; } if (Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationName)) { AspNetAmbientContext.Initialize(httpContext); } }
private static object ExecuteReader( object command, int opCode, int mdToken, long moduleVersionPtr, string sqlClientNamespace, string dataReaderTypeName) { const string methodName = AdoNetConstants.MethodNames.ExecuteReader; Func <object, object> instrumentedMethod; try { var targetType = command.GetInstrumentedType(sqlClientNamespace, SqlCommandTypeName); instrumentedMethod = MethodBuilder <Func <object, object> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(targetType) .WithNamespaceAndNameFilters(dataReaderTypeName) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: $"{sqlClientNamespace}.{SqlCommandTypeName}", methodName: methodName, instanceType: command.GetType().AssemblyQualifiedName); throw; } using (var scope = ScopeFactory.CreateDbCommandScope(Tracer.Instance, command as DbCommand)) { try { return(instrumentedMethod(command)); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object Validate( object documentValidator, object originalQuery, object schema, object document, object rules, object userContext, object inputs, int opCode, int mdToken, long moduleVersionPtr) { if (documentValidator == null) { throw new ArgumentNullException(nameof(documentValidator)); } const string methodName = nameof(Validate); // At runtime, get a Type object for GraphQL.ExecutionResult var documentValidatorInstanceType = documentValidator.GetType(); try { var graphQLAssembly = AppDomain.CurrentDomain .GetAssemblies() .Single(a => a.GetName().Name.Equals(GraphQLAssemblyName)); } catch (Exception ex) { // This shouldn't happen because the GraphQL assembly should have been loaded to construct various other types // profiled app will not continue working as expected without this method Log.Error(ex, $"Error finding types in the GraphQL assembly."); throw; } Func <object, object, object, object, object, object, object, object> instrumentedMethod; try { instrumentedMethod = MethodBuilder <Func <object, object, object, object, object, object, object, object> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(documentValidatorInstanceType) .WithParameters(originalQuery, schema, document, rules, userContext, inputs) .WithNamespaceAndNameFilters( GraphQLValidationResultInterfaceName, ClrNames.String, "GraphQL.Types.ISchema", "GraphQL.Language.AST.Document", "System.Collections.Generic.IEnumerable`1", ClrNames.Ignore, "GraphQL.Inputs") .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: GraphQLDocumentValidatorInterfaceName, methodName: methodName, instanceType: documentValidator.GetType().AssemblyQualifiedName); throw; } using (var scope = CreateScopeFromValidate(document)) { try { var validationResult = instrumentedMethod(documentValidator, originalQuery, schema, document, rules, userContext, inputs); RecordExecutionErrorsIfPresent(scope.Span, "GraphQL.Validation.ValidationError", validationResult.GetProperty("Errors").GetValueOrDefault()); return(validationResult); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object ExecuteAsync( object apiController, object controllerContext, object boxedCancellationToken, int opCode, int mdToken, long moduleVersionPtr) { if (apiController == null) { throw new ArgumentNullException(nameof(apiController)); } var cancellationToken = (CancellationToken)boxedCancellationToken; var callOpCode = (OpCodeValue)opCode; var httpControllerType = apiController.GetInstrumentedInterface(HttpControllerTypeName); Type taskResultType; try { var request = controllerContext.GetProperty <object>("Request").GetValueOrDefault(); var httpRequestMessageType = request.GetInstrumentedType("System.Net.Http.HttpRequestMessage"); // The request should never be null, so get the base type found in System.Net.Http.dll if (httpRequestMessageType != null) { var systemNetHttpAssembly = httpRequestMessageType.Assembly; taskResultType = systemNetHttpAssembly.GetType("System.Net.Http.HttpResponseMessage", true); } // This should never happen, but put in a reasonable fallback of finding the first System.Net.Http.dll in the AppDomain else { Log.Warning($"{nameof(AspNetWebApi2Integration)}.{nameof(ExecuteAsync)}: Unable to find System.Net.Http.HttpResponseMessage Type from method arguments. Using fallback logic to find the Type needed for return type."); var statsd = Tracer.Instance.Statsd; statsd?.Warning(source: $"{nameof(AspNetWebApi2Integration)}.{nameof(ExecuteAsync)}", message: "Unable to find System.Net.Http.HttpResponseMessage Type from method arguments. Using fallback logic to find the Type needed for return type.", null); var systemNetHttpAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(assembly => assembly.GetName().Name.Equals("System.Net.Http", StringComparison.OrdinalIgnoreCase)); var firstSystemNetHttpAssembly = systemNetHttpAssemblies.First(); taskResultType = firstSystemNetHttpAssembly.GetType("System.Net.Http.HttpResponseMessage", true); } } catch (Exception ex) { // This shouldn't happen because the System.Net.Http assembly should have been loaded if this method was called // The profiled app will not continue working as expected without this method Log.Error(ex, "Error finding types in the user System.Net.Http assembly."); throw; } Func <object, object, CancellationToken, object> instrumentedMethod = null; try { instrumentedMethod = MethodBuilder <Func <object, object, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, nameof(ExecuteAsync)) .WithConcreteType(httpControllerType) .WithParameters(controllerContext, cancellationToken) .WithNamespaceAndNameFilters( ClrNames.GenericTask, HttpControllerContextTypeName, ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: HttpControllerTypeName, methodName: nameof(ExecuteAsync), instanceType: apiController.GetType().AssemblyQualifiedName); throw; } return(AsyncHelper.InvokeGenericTaskDelegate( owningType: apiController.GetType(), taskResultType: taskResultType, nameOfIntegrationMethod: nameof(ExecuteAsyncInternal), integrationType: typeof(AspNetWebApi2Integration), instrumentedMethod, apiController, controllerContext, cancellationToken)); }
public static void BeforeAction( object diagnosticSource, object actionDescriptor, object httpContext, object routeData, int opCode, int mdToken, long moduleVersionPtr) { AspNetCoreMvc2Integration integration = null; if (!Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationName)) { // integration disabled return; } try { integration = new AspNetCoreMvc2Integration(actionDescriptor, httpContext); if (httpContext.TryGetPropertyValue("Items", out IDictionary <object, object> contextItems)) { contextItems[HttpContextKey] = integration; } } catch (Exception ex) { Log.Error(ex, $"Error creating {nameof(AspNetCoreMvc2Integration)}."); } Action <object, object, object, object> instrumentedMethod = null; try { instrumentedMethod = MethodBuilder <Action <object, object, object, object> > .Start(moduleVersionPtr, mdToken, opCode, nameof(BeforeAction)) .WithConcreteType(DiagnosticSourceType) .WithParameters(diagnosticSource, actionDescriptor, httpContext, routeData) .WithNamespaceAndNameFilters( ClrNames.Void, ClrNames.Ignore, "Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor", "Microsoft.AspNetCore.Http.HttpContext", "Microsoft.AspNetCore.Routing.RouteData") .Build(); } catch (Exception ex) { // profiled app will continue working as expected without this method Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: DiagnosticSourceTypeName, methodName: nameof(BeforeAction), instanceType: null, relevantArguments: new[] { diagnosticSource?.GetType().AssemblyQualifiedName }); } try { // call the original method, catching and rethrowing any unhandled exceptions instrumentedMethod?.Invoke(diagnosticSource, actionDescriptor, httpContext, routeData); } catch (Exception ex) when(integration?.SetException(ex) ?? false) { // unreachable code throw; } }
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; try { var instrumentedType = webRequest.GetInstrumentedType("System.Net.WebRequest"); callGetResponse = MethodBuilder <Func <object, WebResponse> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(instrumentedType) .WithNamespaceAndNameFilters("System.Net.WebResponse") .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: WebRequestTypeName, methodName: methodName, instanceType: webRequest.GetType().AssemblyQualifiedName); throw; } var request = (WebRequest)webRequest; if (!(request is HttpWebRequest) || !IsTracingEnabled(request)) { return(callGetResponse(webRequest)); } using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, request.Method, request.RequestUri, IntegrationName, out var tags)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } WebResponse response = callGetResponse(webRequest); if (scope != null && response is HttpWebResponse webResponse) { tags.HttpStatusCode = HttpTags.ConvertStatusCodeToString((int)webResponse.StatusCode); } return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object BeginInvokeAction( object asyncControllerActionInvoker, object controllerContext, object actionName, object callback, object state, int opCode, int mdToken, long moduleVersionPtr) { if (asyncControllerActionInvoker == null) { throw new ArgumentNullException(nameof(asyncControllerActionInvoker)); } Scope scope = null; try { if (HttpContext.Current != null) { scope = CreateScope(controllerContext); HttpContext.Current.Items[HttpContextKey] = scope; } } catch (Exception ex) { Log.Error(ex, "Error instrumenting method {0}", "System.Web.Mvc.Async.IAsyncActionInvoker.BeginInvokeAction()"); } Func <object, object, object, object, object, object> instrumentedMethod; try { var asyncActionInvokerType = asyncControllerActionInvoker.GetInstrumentedInterface(AsyncActionInvokerTypeName); instrumentedMethod = MethodBuilder <Func <object, object, object, object, object, object> > .Start(moduleVersionPtr, mdToken, opCode, nameof(BeginInvokeAction)) .WithConcreteType(asyncActionInvokerType) .WithParameters(controllerContext, actionName, callback, state) .WithNamespaceAndNameFilters( ClrNames.IAsyncResult, "System.Web.Mvc.ControllerContext", ClrNames.String, ClrNames.AsyncCallback, ClrNames.Object) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: AsyncActionInvokerTypeName, methodName: nameof(BeginInvokeAction), instanceType: asyncControllerActionInvoker.GetType().AssemblyQualifiedName); throw; } try { // call the original method, inspecting (but not catching) any unhandled exceptions return(instrumentedMethod(asyncControllerActionInvoker, controllerContext, actionName, callback, state)); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } }
public static object HttpMessageHandler_SendAsync( object handler, object request, object boxedCancellationToken, int opCode, int mdToken, long moduleVersionPtr) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } // original signature: // Task<HttpResponseMessage> HttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) var cancellationToken = (CancellationToken)boxedCancellationToken; var callOpCode = (OpCodeValue)opCode; var httpMessageHandler = handler.GetInstrumentedType(HttpMessageHandler); Type taskResultType; try { var currentHttpAssembly = httpMessageHandler.Assembly; taskResultType = currentHttpAssembly.GetType("System.Net.Http.HttpResponseMessage", true); } catch (Exception ex) { // This shouldn't happen because the System.Net.Http assembly should have been loaded if this method was called // profiled app will not continue working as expected without this method Log.Error(ex, "Error finding types in the user System.Net.Http assembly."); throw; } Func <object, object, CancellationToken, object> instrumentedMethod = null; try { instrumentedMethod = MethodBuilder <Func <object, object, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, SendAsync) .WithConcreteType(httpMessageHandler) .WithParameters(request, cancellationToken) .WithNamespaceAndNameFilters(ClrNames.GenericTask, ClrNames.HttpRequestMessage, ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: HttpMessageHandler, methodName: SendAsync, instanceType: handler.GetType().AssemblyQualifiedName); throw; } return(AsyncHelper.InvokeGenericTaskDelegate( owningType: handler.GetType(), taskResultType: taskResultType, nameOfIntegrationMethod: nameof(SendAsyncInternal), integrationType: typeof(HttpMessageHandlerIntegration), instrumentedMethod, callOpCode == OpCodeValue.Call ? httpMessageHandler : handler.GetType(), handler, request, cancellationToken)); }
public static object Validate( object documentValidator, object originalQuery, object schema, object document, object rules, object userContext, object inputs, int opCode, int mdToken, long moduleVersionPtr) { if (documentValidator == null) { throw new ArgumentNullException(nameof(documentValidator)); } const string methodName = nameof(Validate); // At runtime, get a Type object for GraphQL.ExecutionResult var documentValidatorInstanceType = documentValidator.GetType(); Func <object, object, object, object, object, object, object, object> instrumentedMethod; try { instrumentedMethod = MethodBuilder <Func <object, object, object, object, object, object, object, object> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(documentValidatorInstanceType) .WithParameters(originalQuery, schema, document, rules, userContext, inputs) .WithNamespaceAndNameFilters( GraphQLValidationResultInterfaceName, ClrNames.String, "GraphQL.Types.ISchema", "GraphQL.Language.AST.Document", "System.Collections.Generic.IEnumerable`1", ClrNames.Ignore, "GraphQL.Inputs") .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: GraphQLDocumentValidatorInterfaceName, methodName: methodName, instanceType: documentValidator.GetType().AssemblyQualifiedName); throw; } using (var scope = CreateScopeFromValidate(document)) { try { var validationResult = instrumentedMethod(documentValidator, originalQuery, schema, document, rules, userContext, inputs); RecordExecutionErrorsIfPresent(scope.Span, "GraphQL.Validation.ValidationError", validationResult.GetProperty("Errors").GetValueOrDefault()); return(validationResult); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object TestInvoker_RunAsync( object testInvoker, int opCode, int mdToken, long moduleVersionPtr) { if (testInvoker == null) { throw new ArgumentNullException(nameof(testInvoker)); } Type testInvokerType = testInvoker.GetType(); Func <object, object> executeAsync; try { executeAsync = MethodBuilder <Func <object, object> > .Start(moduleVersionPtr, mdToken, opCode, XUnitRunAsyncMethod) .WithConcreteType(testInvokerType) .WithDeclaringTypeGenerics(testInvokerType.BaseType.GenericTypeArguments) .WithNamespaceAndNameFilters(ClrNames.GenericTask) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: XUnitTestInvokerType, methodName: XUnitRunAsyncMethod, instanceType: testInvokerType.AssemblyQualifiedName); throw; } object returnValue = null; Exception exception = null; try { returnValue = executeAsync(testInvoker); } catch (TargetInvocationException ex) { exception = ex.InnerException; throw; } catch (Exception ex) { exception = ex; throw; } finally { returnValue = AsyncTool.AddContinuation(returnValue, exception, testInvoker, (r, ex, state) => InvokerContinuation(r, ex, state)); } return(returnValue); }
/// <summary> /// Execute an asynchronous redis operation. /// </summary> /// <typeparam name="T">The result type</typeparam> /// <param name="redisBase">The object this method is called on</param> /// <param name="message">The message</param> /// <param name="processor">The result processor</param> /// <param name="server">The server</param> /// <param name="callOpCode">The <see cref="OpCodeValue"/> used in the original method call.</param> /// <param name="mdToken">The mdToken of the original method call.</param> /// <param name="moduleVersionPtr">A pointer to the module version GUID.</param> /// <returns>An asynchronous task.</returns> private static async Task <T> ExecuteAsyncInternal <T>( object redisBase, object message, object processor, object server, int callOpCode, int mdToken, long moduleVersionPtr) { if (redisBase == null) { throw new ArgumentNullException(nameof(redisBase)); } Func <object, object, object, object, Task <T> > instrumentedMethod; try { var instrumentedType = redisBase.GetInstrumentedType(RedisBaseTypeName); instrumentedMethod = MethodBuilder <Func <object, object, object, object, Task <T> > > .Start(moduleVersionPtr, mdToken, callOpCode, nameof(ExecuteAsync)) .WithConcreteType(instrumentedType) .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: redisBase.GetType().AssemblyQualifiedName); throw; } // we only trace RedisBatch methods here var thisType = redisBase.GetType(); var batchType = thisType.Assembly.GetType("StackExchange.Redis.RedisBatch", throwOnError: false); if (thisType == batchType) { using (var scope = CreateScope(redisBase, message)) { try { return(await instrumentedMethod(redisBase, message, processor, server).ConfigureAwait(false)); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } } return(await instrumentedMethod(redisBase, message, processor, server).ConfigureAwait(false)); }
public static object HttpMessageHandler_SendAsync( object handler, object request, object boxedCancellationToken, int opCode, int mdToken, long moduleVersionPtr) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } // original signature: // Task<HttpResponseMessage> HttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) var cancellationToken = (CancellationToken)boxedCancellationToken; var callOpCode = (OpCodeValue)opCode; var httpMessageHandler = handler.GetInstrumentedType(SystemNetHttp, HttpMessageHandlerTypeName); Func <object, object, CancellationToken, object> instrumentedMethod = null; try { instrumentedMethod = MethodBuilder <Func <object, object, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, SendAsync) .WithConcreteType(httpMessageHandler) .WithParameters(request, cancellationToken) .WithNamespaceAndNameFilters(NamespaceAndNameFilters) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: HttpMessageHandler, methodName: SendAsync, instanceType: handler.GetType().AssemblyQualifiedName); throw; } var reportedType = callOpCode == OpCodeValue.Call ? httpMessageHandler : handler.GetType(); var headers = request.GetProperty <object>("Headers").GetValueOrDefault(); if (!(reportedType.FullName.Equals(HttpClientHandler, StringComparison.OrdinalIgnoreCase) || IsSocketsHttpHandlerEnabled(reportedType)) || !IsTracingEnabled(headers)) { // skip instrumentation return(instrumentedMethod(handler, request, cancellationToken)); } Type taskResultType = _httpMessageHandlerResultType; if (taskResultType == null || taskResultType.Assembly != httpMessageHandler.Assembly) { try { var currentHttpAssembly = httpMessageHandler.Assembly; taskResultType = currentHttpAssembly.GetType("System.Net.Http.HttpResponseMessage", true); _httpMessageHandlerResultType = taskResultType; } catch (Exception ex) { // This shouldn't happen because the System.Net.Http assembly should have been loaded if this method was called // profiled app will not continue working as expected without this method Log.Error(ex, "Error finding types in the user System.Net.Http assembly."); throw; } } return(SendAsyncInternal( instrumentedMethod, reportedType, headers, handler, request, cancellationToken) .Cast(taskResultType)); }
public static object TestCommand_Execute( object testMethodCommand, object testExecutionContext, int opCode, int mdToken, long moduleVersionPtr) { if (testMethodCommand == null) { throw new ArgumentNullException(nameof(testMethodCommand)); } Type testMethodCommandType = testMethodCommand.GetType(); Func <object, object, object> execute; try { execute = MethodBuilder <Func <object, object, object> > .Start(moduleVersionPtr, mdToken, opCode, NUnitExecuteMethod) .WithConcreteType(testMethodCommandType) .WithParameters(testExecutionContext) .WithNamespaceAndNameFilters(NUnitTestResultType, NUnitTestExecutionContextType) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: NUnitTestCommandType, methodName: NUnitExecuteMethod, instanceType: testMethodCommandType.AssemblyQualifiedName); throw; } if (testMethodCommandType.FullName != NUnitTestMethodCommandType && testMethodCommandType.FullName != NUnitSkipCommandType) { return(execute(testMethodCommand, testExecutionContext)); } Scope scope = CreateScope(testExecutionContext, testMethodCommandType); if (scope is null) { return(execute(testMethodCommand, testExecutionContext)); } using (scope) { object result = null; Exception exception = null; try { scope.Span.ResetStartTime(); result = execute(testMethodCommand, testExecutionContext); } catch (Exception ex) { exception = ex; throw; } finally { FinishScope(scope, testExecutionContext, exception); } return(result); } }