c# - trace listener write




Cómo rastrear cada método llamado (3)

Tengo un proyecto existente en el que me gustaría conocer todas las llamadas que se están realizando y tal vez verter un archivo de registro.

Eché un vistazo a este hilo , pero no ayudé mucho. Probé PostSharp, y el ejemplo muestra cómo lograrlo. Pero necesito agregar un atributo a cada maldito método. Al ser un proyecto existente, con numerosos métodos, no es una opción viable.

¿Hay algún otro medio por el cual pueda rastrear rápidamente todas las llamadas realizadas?

https://code.i-harness.com


PostSharp ciertamente ofrece una manera de aplicar un aspecto a varios objetivos sin decorarlos con atributos explícitamente. Ver doc.sharpcrafters.com/postsharp-2.1/##PostSharp-2.1.chm/html/… .

Al desarrollar (multicast) aspecto debe especificar su uso:

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

Y luego aplique el aspecto de una manera que cubra su caso de uso (por ejemplo, todos los miembros públicos en el espacio de nombres AdventureWorks.BusinessLayer):

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

Puedes hacer esto con Unity Interception.

Vea este artículo para una muestra . El artículo usa atributos, pero mi ejemplo de código a continuación usa el sistema de inyección de dependencias (codificación a una interfaz) para configurar la intercepción.

Si quieres registrar MyClass , es algo como esto:

  1. Cree una interfaz que contenga todos los métodos en MyClass => IMyClass
  2. Usted configura InterfaceInterception (como lo he hecho a continuación) O hay algunas otras formas en que puede configurarlo. Vea aquí para todas las opciones .
  3. Configurará una política para interceptar todos los métodos que coincidan con IMatchingRule .
  4. Todas las llamadas serán ahora interceptadas por su implementación de ICallHandler .

Código:

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

Utilice un Perfilador en el modo de seguimiento. Luego verás cómo todo se llama y dónde se gasta el tiempo. Además de perfiladores comerciales también hay gratuitos. Para el código administrado hay NP Profiler que es bastante bueno.

Si desea profundizar, puede usar el Kit de herramientas de rendimiento de Windows, que le brinda información completa en todos los subprocesos y cómo interactúan entre sí, si desea saberlo. La única diferencia es que obtiene pilas que van desde el núcleo hasta los marcos administrados.

Si esto no es suficiente, puede instrumentar su código con una biblioteca de rastreo (ya sea automáticamente con PostSharp, ....) o manualmente o con una macro para cada archivo fuente. He hecho una pequeña biblioteca de rastreo que es bastante rápida y altamente configurable. Ver here Como característica única puede rastrear cualquier excepción lanzada automáticamente.

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

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

Aquí viene la salida:

    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




trace