DOCUMENTATION

Collect Method Arguments

When analyzing an exception’s call stack, it can be useful to review arguments of methods that were in execution when an exception occurred. Logify Alert provides the following methods to support this functionality:

  • TrackArguments
    Collects arguments passed to the invoked method. Call TrackArguments when handling an exception that occurs during a method execution.

  • ResetTrackArguments
    Removes method argument values which TrackArguments collected previously. Call ResetTrackArguments before a method execution and after method execution succeeds.

The collected method arguments are shown in the Report Details page.

There are several approaches you can use to enable tracking arguments:

  • To collect particular method arguments, call TrackArguments and ResetTrackArguments directly within a method's try/catch blocks.

  • Use different aspect-oriented programming (AOP) tools to avoid manual repeating the same code in each method if you need to track all or multiple methods' arguments in your application. These tools allow you to implement the required logic once and then automatically inject it into all methods. For example, you can use the following AOP tools:

Collect Particular Method Arguments

The following example shows how to enable tracking particular methods' arguments:

        public void DoWork(string work) {
    LogifyAlert.Instance.ResetTrackArguments();
    try {
        DoInnerWork(work, 5);
        LogifyAlert.Instance.ResetTrackArguments();
    }
    catch (Exception ex) {
        LogifyAlert.Instance.TrackArguments(ex, work);
        throw;
    }
}
public void DoInnerWork(string innerWork, int times) {
    LogifyAlert.Instance.ResetTrackArguments();
    try {
        object o = null;
        o.ToString();
        LogifyAlert.Instance.ResetTrackArguments();
    }
    catch (Exception ex) {
        LogifyAlert.Instance.TrackArguments(ex, this, innerWork, times);
        throw;
    }
}
        

Castle DynamicProxy

Follow the steps below to enable tracking method arguments using the Castle DynamicProxy library.

  1. Create an interceptor:

    public class MethodParamsInterceptor : IInterceptor {
        public void Intercept(IInvocation invocation) {
            try {
                LogifyAlert.Instance.ResetTrackArguments();
                invocation.Proceed();
                LogifyAlert.Instance.ResetTrackArguments();
            }
            catch (Exception ex) {
                LogifyAlert.Instance.TrackArguments(
                    ex,
                    CreateMethodCallInfo(invocation)
                );
                throw;
            }
        }
        MethodCallInfo CreateMethodCallInfo(IInvocation invocation) {
            MethodCallInfo result = new MethodCallInfo();
            result.Instance = invocation.Proxy;
            result.Method = invocation.Method;
            result.Arguments = invocation.Arguments;
            return result;
        }
    }

  2. Create a proxy object using the interceptor:

                    var proxy = generator.CreateClassProxy<CLASS_TO_PROXY>(
        new MethodParamsInterceptor()
    );
    proxy.DoWork("work");
    

This approach is useful if you already use Castle in your application. However, it has some limitations:

  • Only virtual methods and interfaces can be intercepted;
  • There are many Castle frames in the call stack.

PostSharp

Follow the steps below to enable tracking method arguments using the PostSharp extension.

  1. Implement a custom aspect. To do this, create a new class inherited from OnMethodBoudaryAspect and override the OnEntry, OnSuccess and OnException methods.

                    [AttributeUsage(AttributeTargets.Method |
                    AttributeTargets.Class |
                    AttributeTargets.Assembly |
                    AttributeTargets.Module)]
    [Serializable]
    public class CollectParamsAttribute : OnMethodBoundaryAspect {
        public override bool CompileTimeValidate(MethodBase method) {
            if (method.GetCustomAttribute(typeof(IgnoreCallTrackingAttribute)) != null ||
                method.Name == "Dispose") {
                return false;
            }
            return base.CompileTimeValidate(method);
        }
        public override void OnEntry(MethodExecutionArgs args) {
            base.OnEntry(args);
            LogifyAlert.Instance.ResetTrackArguments();
        }
        public override void OnSuccess(MethodExecutionArgs args) {
            LogifyAlert.Instance.ResetTrackArguments();
            base.OnSuccess(args);
        }
        [MethodImpl(MethodImplOptions.NoInlining)]
        public override void OnException(MethodExecutionArgs args) {
            if (args.Exception == null)
                return;
            if (args.Method != null && args.Arguments != null && args.Instance != this)
                LogifyAlert.Instance.TrackArguments(args.Exception,
                                                    CreateMethodCallInfo(args));
            base.OnException(args);
        }
        MethodCallInfo CreateMethodCallInfo(MethodExecutionArgs args) {
            MethodCallInfo result = new MethodCallInfo();
            result.Method = args.Method;
            result.Arguments = args.Arguments;
            result.Instance = args.Instance;
            return result;
        }
    }
                    

  2. Apply the created aspect to your application code. To do this, add the corresponding attribute to target members:

    • to particular methods for applying an aspect to the specified methods;

    • to classes for applying an aspect to all the specified classes' methods;

    • to an assembly for applying an aspect to all classes' methods.

      [assembly: CollectParams]

Terms of use Copyright © 2016-2019 Developer Express Inc.