行われているすべての呼び出しを見つけて、ログ ファイルにダンプしたい既存のプロジェクトがあります。
このスレッドを見ましたが、あまり役に立ちませんでした。私は PostSharp を試しましたが、例はそれを達成する方法を示しています。しかし、すべてのダーン メソッドに属性を追加する必要があります。既存のプロジェクトであり、実行可能なオプションではない多数の方法があります。
発信されたすべての通話をすばやく追跡できる他の手段はありますか?
Unity Interceptionでこれを行うことができます
サンプルについては、この記事を参照してください。この記事では属性を使用していますが、以下のコード サンプルでは、依存性注入システム (インターフェイスへのコーディング) を使用してインターセプトを設定しています。
をログに記録する場合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.
}
}
プロファイラーをトレース モードで使用します。次に、すべてがどのようにお互いを呼び出し、どこで時間が費やされているかを確認します。商用プロファイラーの他に、無料のものもあります。マネージ コードには、非常に優れたNP Profilerがあります。
さらに詳しく知りたい場合は、 Windows Performance Toolkitを使用できます。これにより、すべてのスレッドに関する完全な情報と、知りたい場合に相互に対話する方法が得られます。唯一の違いは、カーネルからマネージド フレームまでの範囲のスタックを取得することです。
これでは不十分な場合は、トレース ライブラリ (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
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名前空間のすべてのパブリックメンバー)。
[assembly: Trace( AttributeTargetTypes="AdventureWorks.BusinessLayer.*", AttributeTargetMemberAttributes = MulticastAttributes.Public )]