Come tracciare ogni metodo chiamato

Ho un progetto esistente in cui mi piacerebbe scoprire tutte le chiamate effettuate e magari eseguire il dump in un file di registro.

Ho dato un’occhiata a questo thread , ma non ha aiutato molto. Ho provato PostSharp e l’esempio mostra come ottenerlo. Ma ho bisogno di aggiungere un attributo a ogni metodo darn. Essere un progetto esistente, con metodi in-numerosi che non è un’opzione fattibile.

C’è qualche altro mezzo con cui posso tracciare rapidamente tutte le chiamate fatte?

Puoi farlo con Unity Intercetttion

Vedi questo articolo per un campione . L’articolo usa gli attributi, ma il mio esempio di codice qui sotto usa il sistema di dipendenza da dipendenza (codifica su un’interfaccia) per impostare l’intercettazione.

Se vuoi registrare MyClass , va qualcosa del genere:

  1. Crea un’interfaccia che contenga tutti i metodi in MyClass => IMyClass
  2. Configura InterfaceInterception (come ho fatto di seguito) O ci sono altri modi in cui puoi configurarlo. Vedi qui per tutte le opzioni .
  3. Imposterai una politica per intercettare tutti i metodi che corrispondono a IMatchingRule .
  4. Tutte le chiamate verranno ora intercettate dall’implementazione di ICallHandler .

Codice:

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

PostSharp offre certamente un modo per applicare un aspetto a più obiettivi senza decorarli esplicitamente. Vedi attributi multicast .

Quando si sviluppa un aspetto (multicast) è necessario specificarne l’utilizzo:

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

E poi applica l’aspetto in un modo che copra il tuo caso d’uso (ad esempio tutti i membri pubblici nello spazio dei nomi AdventureWorks.BusinessLayer):

 [assembly: Trace( AttributeTargetTypes="AdventureWorks.BusinessLayer.*", AttributeTargetMemberAttributes = MulticastAttributes.Public )] 

Utilizzare un profiler nella modalità di tracciamento. Quindi vedrai come tutto si chiama e dove viene speso il tempo. Oltre agli profiler commerciali ci sono anche quelli gratuiti. Per il codice gestito c’è NP Profiler che è abbastanza buono.

Se vuoi approfondire, puoi utilizzare Windows Performance Toolkit che ti fornisce informazioni complete su tutti i thread e su come interagire tra loro, se vuoi sapere. L’unica differenza è che ottieni stack che vanno dal kernel fino ai frame gestiti.

Se questo non è abbastanza, puoi strumentare il tuo codice con una libreria di tracciamento (automaticamente con PostSharp, ….) o manualmente o con una macro per ogni file sorgente. Ho creato una piccola libreria di tracciamento che è abbastanza veloce e altamente configurabile. Vedi qui Come caratteristica unica può tracciare automaticamente ogni eccezione generata.

 private void SomeOtherMethod() { using (Tracer t = new Tracer(myType, "SomeOtherMethod")) { FaultyMethod(); } } private void FaultyMethod() { throw new NotImplementedException("Hi this a fault"); } 

Ecco l’output:

  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