我有一个现有项目,我想查找所有正在进行的调用,并可能转储到日志文件中。
我看了at this thread,但没多大帮助。 我试过PostSharp,这个例子展示了如何实现它。但我需要为每个darn方法添加一个属性。作为一个现有的项目,有许多方法是不可行的选择。
有没有其他方法可以快速追踪所有来电?
答案 0 :(得分:10)
您可以使用Unity Interception
执行此操作见article for a sample。本文使用属性,但下面的代码示例使用依赖注入系统(编码到接口)来设置拦截。
如果你想记录MyClass
,它会是这样的:
MyClass
=>中所有方法的界面IMyClass
IMatchingRule
匹配的所有方法。 代码:
//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.
}
}
答案 1 :(得分:5)
在跟踪模式下使用Profiler。然后你会看到一切都是如何相互呼唤以及花费的时间。除商业剖析外,还有免费的。 对于托管代码,NP Profiler非常好。
如果你想深入一点,你可以使用Windows Performance Toolkit,它可以为你提供所有线程的完整信息,以及如果你想知道如何互相交流。唯一的区别是你得到的堆栈范围从内核到托管框架。
如果这还不够,您可以使用跟踪库(自动使用PostSharp,......)或手动或使用宏来为每个源文件检测代码。 我创建了一个非常快速且高度可配置的跟踪库。见here。作为独特功能,它可以自动跟踪任何抛出的异常。
private void SomeOtherMethod()
{
using (Tracer t = new Tracer(myType, "SomeOtherMethod"))
{
FaultyMethod();
}
}
private void FaultyMethod()
{
throw new NotImplementedException("Hi this a fault");
}
输出结果如下:
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
答案 2 :(得分:5)
PostSharp肯定提供了一种方法,可以将一个方面应用于多个目标,而无需明确地使用属性进行修饰。请参阅Multicast attributes。
开发(多播)方面时,必须指定其用法:
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)]
[AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = true)]
[Serializable]
public class TraceAttribute : MethodInterceptionAspect
{
// Details skipped.
}
然后以涵盖用例的方式应用方面(例如,AdventureWorks.BusinessLayer命名空间中的所有公共成员):
[assembly: Trace( AttributeTargetTypes="AdventureWorks.BusinessLayer.*", AttributeTargetMemberAttributes = MulticastAttributes.Public )]