2013-02-13 14 views
18

Mam istniejący projekt, w którym chciałbym znaleźć wszystkie wywoływane połączenia i być może zrzucić do pliku dziennika.Jak prześledzić każdą metodę o nazwie

Miałem wygląd at this thread, ale nie wiele pomóc. Próbowałem PostSharp, a przykład pokazuje, jak to osiągnąć. Ale muszę dodać atrybut do każdej metody darn. Bycie istniejącym projektem, z wieloma metodami, co nie jest wykonalną opcją.

Czy istnieją inne sposoby, dzięki którym mogę szybko prześledzić wszystkie wykonane połączenia?

+0

Czy przyjrzał się http://stackoverflow.com/questions/171970/how-can-i-find-the-method-that-called-the-current-method –

+0

nie mogę pomóc ale zastanawiaj się, dlaczego byś tego chciał. W przypadku wyjątku możesz wyświetlić stacktrace. Ale dlaczego chcesz mieć dziennik wszystkich wywołań metod? – comecme

+0

Istnieje błąd, który możemy prześledzić do pewnego momentu, a następnie kontrola przechodzi do aplikacji nadrzędnej, która nie jest naszą aplikacją - więc nie ma kodu źródłowego (gdzieś po tym aplikacja przestaje odpowiadać). Aby dowiedzieć się, co jest wywoływane w naszej aplikacji, próbujemy tego. –

Odpowiedz

9

Można to zrobić z Unity Interception

Zobacz ten article for a sample. W artykule zastosowano atrybuty, ale poniższy przykład kodu używa systemu wtrysku zależności (kodowanie do interfejsu) w celu skonfigurowania przechwytywania.

Jeśli chcesz się zalogować MyClass, to idzie tak:

  1. Złóż interfejs, który zawiera wszystkie metody w MyClass =>IMyClass
  2. możliwość konfiguracji InterfaceInterception (jak zrobiłem poniżej) LUB istnieje kilka innych sposobów konfiguracji. Zobacz here for all options.
  3. Skonfiguruj strategię przechwytywania wszystkich metod zgodnych z IMatchingRule.
  4. Wszystkie połączenia będą teraz przechwytywane przez implementację ICallHandler.

Kod:

//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. 
    } 
} 
+0

Myślę, że próbuje to zrobić bez dodawania atrybutu do każdego metoda/klasa (która różni się od próbki) – eyossi

+0

Ale Mój kod nie potrzebuje żadnych atrybutów. – gideon

+0

Wygląda na to, że trzeba utworzyć interfejs dla każdej klasy; to według mnie jeszcze więcej pracy niż atrybutów. –

4

Użyj Profiler w trybie śledzenia. Wtedy zobaczysz, jak wszystko dzwoni do siebie i gdzie spędza się czas. Oprócz komercyjnych profilerów są też darmowe. Kod zarządzany to NP Profiler, który jest całkiem niezły.

Jeśli chcesz zagłębić się, możesz użyć funkcji Windows Performance Toolkit, która zapewnia pełne informacje we wszystkich wątkach i sposób interakcji ze sobą, jeśli chcesz się dowiedzieć. Jedyna różnica polega na tym, że dostajesz stosy od jądra aż do twoich zarządzanych ramek.

Jeśli to nie wystarczy, możesz przydzielić swój kod za pomocą biblioteki śledzenia (automatycznie za pomocą PostSharp, ....) lub ręcznie lub za pomocą makra dla każdego pliku źródłowego. Zrobiłem małą bibliotekę śledzenia, która jest dość szybka i wysoce konfigurowalna. Zobacz here. Jako unikalna funkcja może automatycznie śledzić każdy zgłoszony wyjątek.

private void SomeOtherMethod() 
{ 
    using (Tracer t = new Tracer(myType, "SomeOtherMethod")) 
    { 
     FaultyMethod(); 
    } 
} 

private void FaultyMethod() 
{ 
    throw new NotImplementedException("Hi this a fault"); 
} 

Nadchodzi wyjście:

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 
5

PostSharp pewnością oferuje możliwość ubiegania aspekt do kilku celów bez zdobienia ich atrybutów w sposób jawny. Zobacz Multicast attributes.

Przy opracowywaniu (multicast) aspekt należy określić jego wykorzystania:

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

a następnie zastosować aspekt w sposób, który obejmuje sprawy zastosowanie (np Wszyscy członkowie publiczne w przestrzeni nazw AdventureWorks.BusinessLayer.):

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