30

行われているすべての呼び出しを見つけて、ログ ファイルにダンプしたい既存のプロジェクトがあります。

このスレッドを見ましたが、あまり役に立ちませんでした。私は PostSharp を試しましたが、例はそれを達成する方法を示しています。しかし、すべてのダーン メソッドに属性を追加する必要があります。既存のプロジェクトであり、実行可能なオプションではない多数の方法があります。

発信されたすべての通話をすばやく追跡できる他の手段はありますか?

4

3 に答える 3

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.
    }
 }
于 2013-02-13T20:40:03.570 に答える
6

プロファイラーをトレース モードで使用します。次に、すべてがどのようにお互いを呼び出し、どこで時間が費やされているかを確認します。商用プロファイラーの他に、無料のものもあります。マネージ コードには、非常に優れた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
于 2013-02-13T21:06:45.723 に答える
5

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 )]
于 2013-02-13T21:33:03.813 に答える