C# 如何跟踪调用的每个方法
我有一个现有的项目,我想找出所有正在进行的调用,也许转储到一个日志文件 我看了一眼,但帮不了什么忙。 我尝试了PostSharp,示例展示了如何实现它。但我需要为每个该死的方法添加一个属性。作为一个现有的项目,有许多方法是不可行的 是否有其他方法可以快速跟踪所有拨打的电话?您可以使用 看这个。本文使用属性,但下面的代码示例使用依赖项注入系统(对接口进行编码)来设置拦截 如果您想记录C# 如何跟踪调用的每个方法,c#,logging,trace,C#,Logging,Trace,我有一个现有的项目,我想找出所有正在进行的调用,也许转储到一个日志文件 我看了一眼,但帮不了什么忙。 我尝试了PostSharp,示例展示了如何实现它。但我需要为每个该死的方法添加一个属性。作为一个现有的项目,有许多方法是不可行的 是否有其他方法可以快速跟踪所有拨打的电话?您可以使用 看这个。本文使用属性,但下面的代码示例使用依赖项注入系统(对接口进行编码)来设置拦截 如果您想记录MyClass,它是这样的: 创建一个包含MyClass=>IMyClass 您可以设置InterfaceInter
MyClass
,它是这样的:
MyClass
=>IMyClass
IMatchingRule
匹配的所有方法李>
//您将使用如下代码:
MyContainer容器=新的MyContainer();
//设置此类型的侦听。。
container.SetupForInteception(typeof(IMyClass));
//这里发生的是得到一个代理类
//它拦截每个方法调用。
IMyClass cls=container.Resolve();
//要使其工作,您需要以下各项:
公共类MyContainer:UnityContainer
{
公共MyContainer()
{
this.AddNewExtension();
这个.RegisterType(typeof(ICallHandler),
类型(LogCallHandler),“MyCallHandler”);
这个.RegisterType(typeof(IMatchingRule),
类型(AnyMatchingRule),“AnyMatchingRule”);
this.RegisterType();
}
//显然有一种新的方法来做这部分
// http://msdn.microsoft.com/en-us/library/ff660911%28PandP.20%29.aspx
公共void SetupForInteception(t型)
{
这是Configure()
.SetInterceptorFor(t,新接口interceptor())
.AddPolicy(“日志策略”)
.AddMatchingRule(“任何MatchingRule”)
.AddCallHandler(“MyCallHandler”);
}
}
//这将匹配要记录的方法。
公共类AnyMatchingRule:IMatchingRule
{
公共布尔匹配(MethodBase成员)
{
return true;//这将记录所有方法。
}
}
公共类LogCallHandler:ICallHandler
{
公测
调用(i方法调用输入,GetNextHandlerElegate getNext)
{
//所有方法调用都将首先在此处进行调用。
//iMethodInviation有一个exception属性,它会让您知道
//如果在方法调用期间发生异常。
}
}
在跟踪模式下使用探查器。然后你会看到每件事都是如何相互调用的,以及在哪里花费时间。除了商业剖析器,还有免费的。
对于托管代码,有一种非常好的方法
如果您想更深入地了解,可以使用,它会提供所有线程的完整信息,以及如果您想了解,它们之间如何相互作用。唯一的区别是,您得到的堆栈范围从内核到托管帧
如果这还不够,您可以使用跟踪库(自动使用PostSharp,…)或手动或使用宏为每个源文件插入代码。
我已经制作了一个小的跟踪库,它非常快速并且高度可配置。看见作为独特的功能,它可以自动跟踪任何抛出的异常
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
18:57:46.665 03064/05180 ApiChange.IntegrationTests.Diagnostics.TracingTests.somethod
18:57:46.668 03064/05180 ApiChange.IntegrationTests.Diagnostics.TracingTests.SomeOtherMethod
18:57:46.670 03064/05180<}}
PostSharp当然提供了一种方法,可以将一个方面应用于多个目标,而无需显式地用属性修饰它们。看
开发(多播)特性时,必须指定其用法:
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)]
[AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = true)]
[Serializable]
public class TraceAttribute : MethodInterceptionAspect
{
// Details skipped.
}
然后以涵盖您的用例的方式应用方面(例如AdventureWorks.BusinessLayer命名空间中的所有公共成员):
你看了吗?我忍不住想知道你为什么要看。如果出现异常,您可以查看stacktrace。但是为什么你想要所有方法调用的日志呢?有一个bug,我们可以跟踪到某个点,然后控制转到不是我们的应用程序的父应用程序-因此没有源代码(在此之后,应用程序停止响应)。为了找出我们的应用程序中的调用,我们正在尝试PostSharp中的multicastatAttribute?我认为他试图做到这一点,但没有为每个方法/类添加属性(这与示例不同),听起来好像需要为每个类创建一个接口;在我看来,这比属性更重要。@BrianBall是的,这是真的。但是如果你打算使用依赖注入(这是一件好事),那么这是一个很好的方法。尽管这项技术很好,但它对我来说毫无用处。我不能修改1000个或更多的类。@ShaQ.Blogs啊太糟糕了!!我发布它是因为我做了几个月的认真研究,并为我的公司实现了这一点。在我的搜索中,我没有
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)]
[AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = true)]
[Serializable]
public class TraceAttribute : MethodInterceptionAspect
{
// Details skipped.
}
[assembly: Trace( AttributeTargetTypes="AdventureWorks.BusinessLayer.*", AttributeTargetMemberAttributes = MulticastAttributes.Public )]