Подтвердить что ты не робот

Как отслеживать каждый метод, называемый

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

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

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

4b9b3361

Ответ 1

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

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

Если вы хотите войти в журнал MyClass, это будет выглядеть примерно так:

  • Создайте интерфейс, содержащий все методы в MyClass = > IMyClass
  • Вы настраиваете InterfaceInterception (например, я сделал это ниже) ИЛИ есть несколько других способов его настройки. См. здесь для всех параметров.
  • Вы настроите политику для перехвата всех методов, которые соответствуют IMatchingRule.
  • Теперь все вызовы будут перехвачены с помощью 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.
    }
 }

Ответ 2

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 )]

Ответ 3

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

Если вы хотите углубиться, вы можете использовать Performance 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