public static void AfterAction(
            object diagnosticSource,
            object actionDescriptor,
            object httpContext,
            object routeData,
            int opCode)
        {
            AspNetCoreMvc2Integration integration = null;

            if (!Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationName))
            {
                // integration disabled
                return;
            }

            try
            {
                if (httpContext.TryGetPropertyValue("Items", out IDictionary <object, object> contextItems))
                {
                    integration = contextItems?[HttpContextKey] as AspNetCoreMvc2Integration;
                }
            }
            catch (Exception ex)
            {
                Log.ErrorExceptionForFilter($"Error accessing {nameof(AspNetCoreMvc2Integration)}.", ex);
            }

            try
            {
                if (_afterAction == null)
                {
                    var type = actionDescriptor.GetType().Assembly.GetType("Microsoft.AspNetCore.Mvc.Internal.MvcCoreDiagnosticSourceExtensions");

                    _afterAction = Emit.DynamicMethodBuilder <Action <object, object, object, object> > .CreateMethodCallDelegate(
                        type,
                        "AfterAction");
                }
            }
            catch
            {
                // TODO: log this as an instrumentation error, we cannot call instrumented method,
                // profiled app will continue working without DiagnosticSource
            }

            try
            {
                // call the original method, catching and rethrowing any unhandled exceptions
                _afterAction?.Invoke(diagnosticSource, actionDescriptor, httpContext, routeData);
            }
            catch (Exception ex)
            {
                integration?.SetException(ex);

                throw;
            }
            finally
            {
                integration?.Dispose();
            }
        }
        public static void BeforeAction(
            object diagnosticSource,
            object actionDescriptor,
            object httpContext,
            object routeData,
            int opCode)
        {
            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.ErrorExceptionForFilter($"Error creating {nameof(AspNetCoreMvc2Integration)}.", ex);
            }

            try
            {
                if (_beforeAction == null)
                {
                    var assembly = actionDescriptor.GetType().GetTypeInfo().Assembly;
                    var type     = assembly.GetType("Microsoft.AspNetCore.Mvc.Internal.MvcCoreDiagnosticSourceExtensions");

                    _beforeAction = Emit.DynamicMethodBuilder <Action <object, object, object, object> > .CreateMethodCallDelegate(
                        type,
                        "BeforeAction");
                }
            }
            catch (Exception ex)
            {
                // profiled app will continue working without DiagnosticSource
                Log.ErrorException("Error calling Microsoft.AspNetCore.Mvc.Internal.MvcCoreDiagnosticSourceExtensions.BeforeAction()", ex);
            }

            try
            {
                // call the original method, catching and rethrowing any unhandled exceptions
                _beforeAction?.Invoke(diagnosticSource, actionDescriptor, httpContext, routeData);
            }
            catch (Exception ex) when(integration?.SetException(ex) ?? false)
            {
                // unreachable code
                throw;
            }
        }
예제 #3
0
        public static void BeforeAction(
            object diagnosticSource,
            object actionDescriptor,
            object httpContext,
            object routeData,
            int opCode,
            int mdToken)
        {
            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.ErrorExceptionForFilter($"Error creating {nameof(AspNetCoreMvc2Integration)}.", ex);
            }

            Action <object, object, object, object> instrumentedMethod = null;

            try
            {
                instrumentedMethod =
                    MethodBuilder <Action <object, object, object, object> >
                    .Start(Assembly.GetCallingAssembly(), mdToken, opCode, nameof(BeforeAction))
                    .WithConcreteTypeName(DiagnosticSource)
                    .WithParameters(diagnosticSource, actionDescriptor, httpContext, routeData)
                    .Build();
            }
            catch (Exception ex)
            {
                // profiled app will continue working as expected without this method
                Log.ErrorException($"Error resolving {DiagnosticSource}.{nameof(BeforeAction)}(...)", ex);
            }

            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;
            }
        }
        /// <summary>
        /// Wrapper method used to instrument Microsoft.AspNetCore.Mvc.Internal.MvcCoreDiagnosticSourceExtensions.AfterAction()
        /// </summary>
        /// <param name="diagnosticSource">The DiagnosticSource that this extension method was called on.</param>
        /// <param name="actionDescriptor">An ActionDescriptor with information about the current action.</param>
        /// <param name="httpContext">The HttpContext for the current request.</param>
        /// <param name="routeData">A RouteData with information about the current route.</param>
        public static void AfterAction(
            object diagnosticSource,
            object actionDescriptor,
            dynamic httpContext,
            object routeData)
        {
            AspNetCoreMvc2Integration integration = null;

            try
            {
                IDictionary <object, object> contextItems = httpContext?.Items;
                integration = contextItems?[HttpContextKey] as AspNetCoreMvc2Integration;
            }
            catch
            {
                // TODO: log this as an instrumentation error, but continue calling instrumented method
            }

            try
            {
                if (_afterAction == null)
                {
                    Type type = actionDescriptor.GetType().Assembly.GetType("Microsoft.AspNetCore.Mvc.Internal.MvcCoreDiagnosticSourceExtensions");

                    _afterAction = DynamicMethodBuilder.CreateMethodCallDelegate <Action <object, object, object, object> >(
                        type,
                        "AfterAction",
                        isStatic: true);
                }
            }
            catch
            {
                // TODO: log this as an instrumentation error, we cannot call instrumented method,
                // profiled app will continue working without DiagnosticSource
            }

            try
            {
                // call the original method, catching and rethrowing any unhandled exceptions
                _afterAction?.Invoke(diagnosticSource, actionDescriptor, httpContext, routeData);
            }
            catch (Exception ex)
            {
                integration?.SetException(ex);
                throw;
            }
            finally
            {
                integration?.Dispose();
            }
        }
        public static void Rethrow(object context, int opCode)
        {
            AspNetCoreMvc2Integration integration = null;
            const string methodName = nameof(Rethrow);

            try
            {
                if (context.TryGetPropertyValue("HttpContext", out object httpContext))
                {
                    if (httpContext.TryGetPropertyValue("Items", out IDictionary <object, object> contextItems))
                    {
                        integration = contextItems?[HttpContextKey] as AspNetCoreMvc2Integration;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.ErrorExceptionForFilter($"Error accessing {nameof(AspNetCoreMvc2Integration)}.", ex);
            }

            Action <object> rethrow;

            try
            {
                rethrow = RethrowAccess.GetInterceptedMethod(
                    assembly: Assembly.GetCallingAssembly(),
                    owningType: ResourceInvoker,
                    returnType: Interception.VoidType,
                    methodName: methodName,
                    generics: Interception.NullTypeArray,
                    parameters: Interception.ParamsToTypes(context));
            }
            catch (Exception ex)
            {
                // profiled app will not continue working as expected without this rethrow method
                Log.ErrorException($"Error calling {ResourceInvoker}.{methodName}(object context)", ex);
                throw;
            }

            try
            {
                // call the original method, catching and rethrowing any unhandled exceptions
                rethrow.Invoke(context);
            }
            catch (Exception ex) when(integration?.SetException(ex) ?? false)
            {
                // unreachable code
                throw;
            }
        }
예제 #6
0
        public static void BeforeAction(
            object diagnosticSource,
            object actionDescriptor,
            dynamic httpContext,
            object routeData)
        {
            AspNetCoreMvc2Integration integration = null;

            try
            {
                integration = new AspNetCoreMvc2Integration(actionDescriptor, httpContext);
                IDictionary <object, object> contextItems = httpContext.Items;
                contextItems[HttpContextKey] = integration;
            }
            catch
            {
                // TODO: log this as an instrumentation error, but continue calling instrumented method
            }

            try
            {
                if (_beforeAction == null)
                {
                    Assembly assembly = actionDescriptor.GetType().GetTypeInfo().Assembly;
                    Type     type     = assembly.GetType("Microsoft.AspNetCore.Mvc.Internal.MvcCoreDiagnosticSourceExtensions");

                    _beforeAction = DynamicMethodBuilder <Action <object, object, object, object> > .CreateMethodCallDelegate(
                        type,
                        "BeforeAction");
                }
            }
            catch
            {
                // TODO: log this as an instrumentation error, we cannot call instrumented method,
                // profiled app will continue working without DiagnosticSource
            }

            try
            {
                // call the original method, catching and rethrowing any unhandled exceptions
                _beforeAction?.Invoke(diagnosticSource, actionDescriptor, httpContext, routeData);
            }
            catch (Exception ex)
            {
                integration?.SetException(ex);
                throw;
            }
        }
        public static void Rethrow(object context, int opCode, int mdToken, long moduleVersionPtr)
        {
            if (context == null)
            {
                // Every rethrow method in every v2.x returns when the context is null
                // We need the type of context to call the correct method as there are 3
                // Remove this when we introduce the type arrays within the profiler
                return;
            }

            var shouldTrace = Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationName);

            Action <object> instrumentedMethod;

            try
            {
                instrumentedMethod =
                    MethodBuilder <Action <object> >
                    .Start(moduleVersionPtr, mdToken, opCode, nameof(Rethrow))
                    .WithConcreteType(ResourceInvokerType)
                    .WithParameters(context)
                    .WithNamespaceAndNameFilters(ClrNames.Void, ClrNames.Ignore)
                    .Build();
            }
            catch (Exception ex)
            {
                Log.ErrorRetrievingMethod(
                    exception: ex,
                    moduleVersionPointer: moduleVersionPtr,
                    mdToken: mdToken,
                    opCode: opCode,
                    instrumentedType: ResourceInvokerTypeName,
                    methodName: nameof(Rethrow),
                    instanceType: null,
                    relevantArguments: new[] { context.GetType().AssemblyQualifiedName });
                throw;
            }

            AspNetCoreMvc2Integration integration = null;

            if (shouldTrace)
            {
                try
                {
                    if (context.TryGetPropertyValue("HttpContext", out object httpContext))
                    {
                        if (httpContext.TryGetPropertyValue("Items", out IDictionary <object, object> contextItems))
                        {
                            integration = contextItems?[HttpContextKey] as AspNetCoreMvc2Integration;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex, $"Error accessing {nameof(AspNetCoreMvc2Integration)}.");
                }
            }

            try
            {
                // call the original method, catching and rethrowing any unhandled exceptions
                instrumentedMethod.Invoke(context);
            }
            catch (Exception ex) when(integration?.SetException(ex) ?? false)
            {
                // unreachable code
                throw;
            }
        }
        public static void AfterAction(
            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
            {
                if (httpContext.TryGetPropertyValue("Items", out IDictionary <object, object> contextItems))
                {
                    integration = contextItems?[HttpContextKey] as AspNetCoreMvc2Integration;
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, $"Error accessing {nameof(AspNetCoreMvc2Integration)}.");
            }

            Action <object, object, object, object> instrumentedMethod = null;

            try
            {
                instrumentedMethod =
                    MethodBuilder <Action <object, object, object, object> >
                    .Start(moduleVersionPtr, mdToken, opCode, nameof(AfterAction))
                    .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(AfterAction),
                    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)
            {
                integration?.SetException(ex);
                throw;
            }
            finally
            {
                integration?.Dispose();
            }
        }
예제 #9
0
        public static void Rethrow(object context, int opCode, int mdToken)
        {
            if (context == null)
            {
                // Every rethrow method in every v2.x returns when the context is null
                // We need the type of context to call the correct method as there are 3
                // Remove this when we introduce the type arrays within the profiler
                return;
            }

            var shouldTrace = Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationName);

            Action <object> instrumentedMethod = null;

            try
            {
                instrumentedMethod =
                    MethodBuilder <Action <object> >
                    .Start(Assembly.GetCallingAssembly(), mdToken, opCode, nameof(Rethrow))
                    .WithConcreteTypeName(ResourceInvoker)
                    .WithParameters(context)
                    .Build();
            }
            catch (Exception ex)
            {
                // profiled app will not continue working as expected without this method
                var contextTypeName = (context == null) ? string.Empty : (context.GetType().FullName + " ");
                var methodDef       = $"{ResourceInvoker}.{nameof(Rethrow)}({contextTypeName}context)";
                Log.ErrorException($"Error retrieving {methodDef}", ex);
                throw;
            }

            AspNetCoreMvc2Integration integration = null;

            if (shouldTrace)
            {
                try
                {
                    if (context.TryGetPropertyValue("HttpContext", out object httpContext))
                    {
                        if (httpContext.TryGetPropertyValue("Items", out IDictionary <object, object> contextItems))
                        {
                            integration = contextItems?[HttpContextKey] as AspNetCoreMvc2Integration;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.ErrorExceptionForFilter($"Error accessing {nameof(AspNetCoreMvc2Integration)}.", ex);
                }
            }

            try
            {
                // call the original method, catching and rethrowing any unhandled exceptions
                instrumentedMethod.Invoke(context);
            }
            catch (Exception ex) when(integration?.SetException(ex) ?? false)
            {
                // unreachable code
                throw;
            }
        }