如何跟踪每个调用的方法

Sha*_*ogs 25 c# logging trace

我有一个现有项目,我想找出所有正在进行的调用,并可能转储到日志文件中.

我看了一下这个帖子,但没多大帮助.我试过PostSharp,这个例子展示了如何实现它.但我需要为每个darn方法添加一个属性.作为一个现有的项目,有许多方法,这是不可行的选择.

有没有其他方法可以快速跟踪所有拨打的电话?

gid*_*eon 10

您可以使用Unity Interception执行此操作

有关示例,请参阅此文章.本文使用属性,但下面的代码示例使用依赖注入系统(编码到接口)来设置拦截.

如果你想记录MyClass,它会是这样的:

  1. 创建一个包含MyClass=> 中所有方法的接口IMyClass
  2. 您设置了InterfaceInterception(就像我在下面所做的那样)或者您可以通过其他几种方式进行设置.请参阅此处了解所有选项.
  3. 您将设置一个策略来拦截所有匹配的方法IMatchingRule.
  4. 现在,您的ICallHandler实现将拦截所有呼叫.

码:

//You  will use the code like this:
MyContainer container = new MyContainer();
//setup interception for this type..
container.SetupForInteception(typeof(IMyClass));
 //what happens here is you get a proxy class 
 //that intercepts every method call.
IMyClass cls = container.Resolve<IMyClass>();

 //You need the following for it to work:   
public class MyContainer: UnityContainer
{
    public MyContainer()
    {
        this.AddNewExtension<Interception>();
        this.RegisterType(typeof(ICallHandler), 
                    typeof(LogCallHandler), "MyCallHandler");
        this.RegisterType(typeof(IMatchingRule), 
                       typeof(AnyMatchingRule), "AnyMatchingRule");

        this.RegisterType<IMyClass, MyClass>();
    }
    //apparently there is a new way to do this part
    // http://msdn.microsoft.com/en-us/library/ff660911%28PandP.20%29.aspx

    public void SetupForInteception(Type t)
    {
        this.Configure<Interception>()
        .SetInterceptorFor(t, new InterfaceInterceptor())
        .AddPolicy("LoggingPolicy")
        .AddMatchingRule("AnyMatchingRule")
        .AddCallHandler("MyCallHandler");

    }
}
//THIS will match which methods to log.
public class AnyMatchingRule : IMatchingRule
{
    public bool Matches(MethodBase member)
    {
        return true;//this ends up loggin ALL methods.
    }
}
public class LogCallHandler : ICallHandler
{
    public IMethodReturn 
             Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
      //All method calls will result in a call here FIRST.
      //IMethodInvocation has an exception property which will let you know
      //if an exception occurred during the method call.
    }
 }
Run Code Online (Sandbox Code Playgroud)

  • 好吧,为什么倒票?任何特殊原因? (4认同)

Alo*_*aus 6

在跟踪模式下使用Profiler.然后你会看到一切都是如何相互呼唤以及花费的时间.除商业剖析外,还有免费的.对于托管代码,NP Profiler非常好.

如果您想深入了解,可以使用Windows性能工具包,它可以为您提供所有线程的完整信息,以及如果您想知道如何相互交互.唯一的区别是你得到的堆栈范围从内核到托管框架.

如果这还不够,您可以使用跟踪库(自动使用PostSharp,....)或手动或使用宏来为每个源文件检测代码.我创建了一个非常快速且高度可配置的跟踪库.看到这里.作为独特功能,它可以自动跟踪任何抛出的异常.

private void SomeOtherMethod()
{
  using (Tracer t = new Tracer(myType, "SomeOtherMethod"))
  {
      FaultyMethod();
  }
}

private void FaultyMethod()
{
   throw new NotImplementedException("Hi this a fault");
}
Run Code Online (Sandbox Code Playgroud)

输出结果如下:

    18:57:46.665  03064/05180 <{{         > ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod  
    18:57:46.668  03064/05180 <{{         > ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod  
    18:57:46.670  03064/05180 <         }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod Exception thrown: System.NotImplementedException: Hi this a fault    
at ApiChange.IntegrationTests.Diagnostics.TracingTests.FaultyMethod()  
at ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod()  
at ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod()    
at ApiChange.IntegrationTests.Diagnostics.TracingTests.Demo_Show_Leaving_Trace_With_Exception() 

18:57:46.670  03064/05180 <         }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod Duration 2ms 18:57:46.689  03064/05180 <         }}< ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeMethod Duration 24ms
Run Code Online (Sandbox Code Playgroud)


Gor*_*ran 5

PostSharp肯定提供了一种方法,可以将方面应用于多个目标,而无需明确地使用属性进行装饰.请参阅多播属性.

在开发(多播)方面时,您必须指定其用法:

[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)]
[AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = true)]
[Serializable]
public class TraceAttribute : MethodInterceptionAspect
{
// Details skipped.
}
Run Code Online (Sandbox Code Playgroud)

然后以涵盖用例的方式应用方面(例如,AdventureWorks.BusinessLayer命名空间中的所有公共成员):

[assembly: Trace( AttributeTargetTypes="AdventureWorks.BusinessLayer.*", AttributeTargetMemberAttributes = MulticastAttributes.Public )]
Run Code Online (Sandbox Code Playgroud)