2013-02-13 3 views
18

У меня есть существующий проект, где я бы хотел узнать все сделанные вызовы и, возможно, выгрузить в файл журнала.Как прослеживать каждый метод под названием

Я посмотрел at this thread, но не очень помог. Я пробовал PostSharp, и пример показывает, как его достичь. Но мне нужно добавить атрибут для каждого метода darn. Быть существующим проектом, используя многочисленные методы, которые не являются возможным вариантом.

Есть ли другие способы, с помощью которых я могу быстро отслеживать все сделанные звонки?

+0

вы взглянули на http://stackoverflow.com/questions/171970/how-can-i-find-the-method-that-called-the-current-method –

+0

я не могу помочь но задайтесь вопросом, зачем вам это нужно. В случае исключения вы можете просмотреть стек. Но зачем вам вести журнал всех вызовов методов? – comecme

+0

Есть ошибка, с которой мы можем отслеживать до определенного момента, и после этого элемент управления переходит к родительскому приложению, которое не является нашим приложением, поэтому никакого исходного кода (где-то после этого приложение перестает отвечать). Чтобы узнать, что называется в нашем приложении, мы пытаемся это сделать. –

ответ

9

Вы можете сделать это с Unity Interception

article for a sample Смотреть это. В статье используются атрибуты, но в моем примере кода ниже используется система впрыска зависимостей (кодирование с интерфейсом) для настройки перехвата.

Если вы хотите войти MyClass, это звучит примерно так:

  1. сделать интерфейс, который содержит все методы в MyClass =>IMyClass
  2. Вы установки InterfaceInterception (как я сделал ниже) ИЛИ есть несколько других способов, которые вы можете настроить. См. here for all options.
  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. 
    } 
} 
+0

Я думаю, что он пытается это сделать, не добавляя атрибут для каждого метод/класс (который отличается от образца) – eyossi

+0

Но мой код не нуждается ни в каких атрибутах. – gideon

+0

Похоже, вам требуется создать интерфейс для каждого класса; это, по-моему, еще больше, чем атрибуты. –

4

Используйте Profiler в режиме трассировки. Затем вы увидите, как все называет друг друга и где тратится время. Помимо коммерческих профайлеров есть и бесплатные. Для управляемого кода есть NP Profiler, что довольно хорошо.

Если вы хотите углубиться, вы можете использовать Windows Performance Toolkit, который дает вам полную информацию по всем темам и как взаимодействовать друг с другом, если вы хотите знать. Единственное различие заключается в том, что вы получаете стеки от ядра до ваших управляемых кадров.

Если этого недостаточно, вы можете привязать свой код к библиотеке трассировки (автоматически с помощью PostSharp, ....) или вручную или с помощью макроса для каждого исходного файла. Я создал небольшую библиотеку трассировки, которая довольно быстрая и настраиваемая. См. here. В качестве уникальной функции он может автоматически отслеживать любое исключенное исключение.

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 
5

PostSharp, безусловно, предлагает способ применить аспект к нескольким целям без украшая их атрибутов в явном виде. См. Multicast attributes.

При разработке (групповой) аспект необходимо указать его использование:

[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)] 
Смежные вопросы