2010-11-10 19 views
16

Estoy intentando usar System.Diagnostics para hacer un registro muy básico. Me imagino que utilizaría lo que está en la caja en lugar de asumir una dependencia adicional como Log4Net o EntLib.Desactivar el rastreo a través de la aplicación.config

Estoy listo, el trazado funciona a la perfección. Fragmento de código:

Trace.TraceInformation("Hello World") 

App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.diagnostics> 
    <trace autoflush="true" indentsize="4"> 
     <listeners> 
     <add name="TraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Trace.log" traceOutputOptions="DateTime" /> 
     <remove name="Default" /> 
     </listeners> 
    </trace> 
    </system.diagnostics> 
</configuration> 

y mi pequeña "Hello World", muestra muy bien en mi archivo trace.log. Pero ahora me gustaría desactivar el seguimiento, así que busco en MSDN y busco How to: Configure Trace Switches . Agrego el elemento <switches>, y ahora mi app.config se ve así:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.diagnostics> 
    <trace autoflush="true" indentsize="4"> 
     <listeners> 
     <add name="TraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Trace.log" traceOutputOptions="DateTime" /> 
     <remove name="Default" /> 
     </listeners> 
    </trace> 
    <switches> 
     <add name="Data" value="0" /> 
    </switches> 
    </system.diagnostics> 
</configuration> 

El value="0" debe desactivar el rastreo - al menos si luego sigue How to: Create and Initialize Trace Switches, que le dice a agregar esta línea de código:

Dim dataSwitch As New BooleanSwitch("Data", "DataAccess module") 

Eso no tiene sentido para mí: solo tengo que declarar una instancia de BooleanSwicth para poder gestionar (deshabilitar) el rastreo a través del archivo .config. ¿Me gustaría ... usar ... el objeto en alguna parte?

De todos modos, estoy seguro de que me perdí algo realmente obvio en alguna parte. Por favor ayuda.

¿Cómo desactivo el seguimiento en app.config?

Respuesta

32

estoy de acuerdo con la recomendación de @Alex Humphrey intentar usar TraceSources. Con TraceSources obtendrá más control sobre cómo se ejecutan sus instrucciones de registro/rastreo. Por ejemplo, usted podría tener un código como éste:

public class MyClass1 
{ 
    private static readonly TraceSource ts = new TraceSource("MyClass1"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class MyClass2 
{ 
    private static readonly TraceSource ts = new TraceSource("MyClass2"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

La llamada TraceSource.TraceEvent comprobará automáticamente el nivel del mensaje (TraceEventType.Information) frente al nivel configurado del interruptor asociado y determinará si es o no el el mensaje debería escribirse.

Al usar un TraceSource de nombre diferente para cada tipo, puede controlar el registro de esas clases individualmente. Puede habilitar el registro de MyClass1 o puede deshabilitarlo o puede habilitarlo, pero haga que se registre solo si el nivel del mensaje (TraceEventType) es mayor que un cierto valor (tal vez solo inicie sesión "Advertencia" y más). Al mismo tiempo, podría activar o desactivar el inicio de sesión en MyClass2 o establecerlo en un nivel, independientemente de MyClass1. Todas estas cosas de habilitación/inhabilitación/nivel ocurren en el archivo app.config.

Utilizando el archivo app.config, también puede controlar todos los TraceSources (o grupos de fuentes Trace) de la misma manera. Entonces, podría configurar para que MyClass1 y MyClass2 sean controlados por el mismo Switch.

Si no quiere tener un TraceSource nombre diferente para cada tipo, usted podría crear el mismo TraceSource en cada clase:

public class MyClass1 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class MyClass2 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

De esta manera, se puede hacer todo el registro dentro de la aplicación suceda en el mismo nivel (o estar apagado o ir al mismo TraceListener, o lo que sea).

También puede configurar diferentes partes de la aplicación que permite una configuración independiente sin tener que pasar el "problema" de la definición de un TraceSource único en cada tipo:

public class Analysis1 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class Analysis2 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class DataAccess1 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

public class DataAccess2 
{ 
    private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess"); 

    public DoSomething(int x) 
    { 
    ts.TraceEvent(TraceEventType.Information, "In DoSomething. x = {0}", x); 
    } 
} 

Con su clase instrumentado esta manera, se pudo hacer que la parte "DataAccess" del registro de su aplicación esté en un nivel mientras que la parte "Análisis" de su aplicación se conecta a un nivel diferente (por supuesto, una o ambas partes de su aplicación podrían configurarse para que el registro esté deshabilitado).

Aquí es una parte de un archivo app.config que configura TraceSources y TraceSwitches:

<system.diagnostics> 
    <trace autoflush="true"></trace> 
    <sources> 
    <source name="MyClass1" switchName="switch1"> 
     <listeners> 
     <remove name="Default"></remove> 
     <add name="console"></add> 
     </listeners> 
    </source> 
    <source name="MyClass2" switchName="switch2"> 
     <listeners> 
     <remove name="Default"></remove> 
     <add name="console"></add> 
     </listeners> 
    </source> 
    </sources> 
    <switches> 
    <add name="switch1" value="Information"/> 
    <add name="switch2" value="Warning"/> 
    </switches> 
    <sharedListeners> 
    <add name="console" 
     type="System.Diagnostics.ConsoleTraceListener"> 
    </add> 
    <add name="file" 
     type="System.Diagnostics.TextWriterTraceListener" 
     initializeData="trace.txt"> 
    </add> 
    </sharedListeners> 
</system.diagnostics> 

Como se puede ver, se puede configurar un único TraceSource y un solo interruptor y todos los registros que ocurriría con una sola nivel de control (es decir, puede desactivar todo el inicio de sesión o hacer que se registre en un cierto nivel).

De forma alternativa, podría definir múltiples fuentes de traza (y hacer referencia a las fuentes de traza correspondientes en su código) y varios interruptores. Los Switches pueden ser compartidos (es decir, múltiples TraceSources pueden usar el mismo Switch).

En última instancia, realizando un poco más de esfuerzo ahora para usar TraceSources y para hacer referencia a TraceSources apropiadamente nombrados en su código (es decir, definir los nombres de TraceSource lógicamente para que pueda tener el grado de control deseado sobre el inicio de sesión en su aplicación). obtendrá una flexibilidad significativa a largo plazo.

Éstos son algunos enlaces que pueden ayudar con System.Diagnostics a medida que avanza hacia adelante:

.net Diagnostics best practices?

Logging best practices

What's the best approach to logging?

Does the .Net TraceSource/TraceListener framework have something similar to log4net's Formatters?

En los enlaces que publicado, a menudo se debate sobre la "mejor" tala marco de referencia. No estoy tratando de convencerte de que cambies de System.Diagnostics. Los enlaces también tienden a tener buena información sobre el uso de System.Diagnostics, es por eso que los publiqué.

Varios de los enlaces que publiqué contienen un enlace al Ukadc.Diagnostics. Esta es una biblioteca realmente genial para System.Diagnostics que agrega una gran capacidad de formateo, similar a lo que puede hacer con log4net y NLog. Esta biblioteca impone una dependencia de solo configuración en su aplicación, no un código o dependencia de referencia.

+0

Awesome answer. Gracias. :) –

+0

Funciona como un encanto. Falta un elemento '' en el archivo de ejemplo .config. –

+0

Agregué un para cerrar el nodo . – wageoghe

1

Está el atributo switchValue del nodo de origen:

<system.diagnostics> 
<sources> 
    <source name="System.ServiceModel" 
      switchValue="Off" 
      propagateActivity="true"> 
    <listeners> 
     <add name="traceListener" 
      type="System.Diagnostics.XmlWriterTraceListener" 
      initializeData= "somePath" /> 
    </listeners> 
    </source> 
</sources> 
<trace autoflush="true" /> 

+0

Intenté su muestra, desafortunadamente no funcionó. No se registró nada ... –

1

Compruebe el estado de dataSwitch cada vez que tienes que entrar, según:

http://msdn.microsoft.com/en-us/library/aa984285%28v=VS.71%29.aspx

Sin embargo , eso es bastante desagradable, tener que poner esos cheques en todas partes. ¿Es esta una razón por la que no desea simplemente eliminar el TraceListener de la colección de oyentes en app.config?

Aparte de eso, investigaría usando el rastreo .NET 2.0+ que incluye TraceSource. Las nuevas (er) cosas ofrecen un grado de configuración mucho más alto, y es posible que encuentre que es más adecuado.

http://msdn.microsoft.com/en-us/library/ms228993.aspx

3

No desactivas el rastreo globalmente de esta forma.

Tienes que
1) declarar un interruptor y establecer su valor:

<switches> 
    <add name="MySwitch" value="Information"/> 
</switches> 

2) asociar este interruptor con un TraceSource que utilice:

<sources> 
    <source name="MySource" switchName="MySwitch"/> 
</source> 

Por lo tanto, cualquier cosa que escriba a través TraceSource llamado "MySource" se filtra de acuerdo con el valor del conmutador.

Si utiliza métodos estáticos como Trace.Write, supongo que no puede usar interruptores en absoluto, porque no hay TraceSource para aplicar el filtro.
Si desea desactivar el rastreo por métodos estáticos, simplemente elimine todos los oyentes: <listeners> <clear/> </listeners>.

1

Late unirse con una nota rápida sobre el app.config, en caso de que esto ahorra un par de días de la vida de alguien por ahí:

Suponga que tiene la puesta en marcha (.exe) que contiene ProjectA classA que hace uso de projectB (.dll) que contiene claseB.

A su vez, ClassB hace uso de una nueva instancia de TraceSource ("clase B"). Para configurarlo necesitas modificar el app.config o projectA. Ajustar el app.config de projectB no llevará a ningún lado.

También tenga en cuenta que la colocación de la Sección

<system.diagnostics> 

dentro app.config parece estar causando problemas si se coloca antes de la sección:

<configSections> 

o después de la sección:

<userSettings> 

Al menos en mi caso, estaba recibiendo errores cuando intenté ubicarlo en estos lugares en e app.config de mi proyecto. El diseño que funcionó para mí fue:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
     ...config sections here if any... 
    </configSections> 
    <system.diagnostics> 
     <trace autoflush="true"/> 
     <sources> 
      <source name="classB" 
       switchName="mySwitch" 
       switchType="System.Diagnostics.SourceSwitch" > 
       <listeners> 
        <clear/> 
        <add name="textwriterListener" 
         type="System.Diagnostics.TextWriterTraceListener" 
         initializeData="ClassBLog.txt" 
         traceOutputOptions="DateTime" /> 
       </listeners> 
      </source> 
      </sources> 
      <switches> 
      <add name="mySwitch" value="Verbose" /> 
      </switches> 
    </system.diagnostics> 
    <runtime> 
     ...runtime sections here if any... 
    </runtime> 
    <userSettings> 
     ...usersettings sections here if any... 
    </userSettings> 
</configuration> 
Cuestiones relacionadas