代码之家  ›  专栏  ›  技术社区  ›  Jakob Gade

通过app.config关闭跟踪

  •  18
  • Jakob Gade  · 技术社区  · 14 年前

    我准备好了,追踪工作做得很好。代码段:

    Trace.TraceInformation("Hello World")
    

    <?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>
    

    How to: Configure Trace Switches . 我加上 <switches> 元素,现在我的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>
        <switches>
          <add name="Data" value="0" />
        </switches>
      </system.diagnostics>
    </configuration>
    

    value="0" 应该关闭跟踪-至少如果你跟着 How to: Create and Initialize Trace Switches ,它告诉您添加这行代码:

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

    这对我来说没有意义:我只需要声明 BooleanSwicth 使用 ... 某处的物体?

    不管怎样,我肯定我漏掉了一些很明显的东西。请帮忙。

    如何关闭app.config中的跟踪?

    5 回复  |  直到 14 年前
        1
  •  35
  •   Community CDub    8 年前

    我同意@Alex Humphrey关于尝试使用TraceSources的建议。使用TraceSources,您可以更好地控制日志/跟踪语句的执行方式。例如,您可以使用这样的代码:

    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);
      }
    }
    

    TraceSource.TraceEvent调用将根据关联交换机的配置级别自动检查消息的级别(TraceEventType.Information),并确定是否应实际写出消息。

    通过对每种类型使用不同名称的TraceSource,可以分别控制这些类的日志记录。您可以启用MyClass1日志记录,也可以禁用它,或者您可以启用它,但只有当消息级别(TraceEventType)大于某个值(可能只记录“Warning”或更高的值)时,才将其记录下来。同时,您可以打开或关闭MyClass2中的日志记录,或者将其设置为完全独立于MyClass1的级别。所有这些启用/禁用/级别的操作都发生在app.config文件中。

    使用app.config文件,您还可以用相同的方式控制所有tracesource(或tracesource组)。所以,您可以配置为MyClass1和MyClass2都由同一个开关控制。

    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);
      }
    }
    

    这样,您就可以使应用程序中的所有日志记录在同一级别上进行(或者关闭或转到同一个TraceListener,或者其他什么)。

    您还可以将应用程序的不同部分配置为可独立配置,而无需在每种类型中定义唯一的TraceSource:

    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);
      }
    }
    

    通过这种方式检测类,您可以将应用程序日志的“DataAccess”部分设置为一个级别,而将应用程序日志的“Analysis”部分设置为另一个级别(当然,可以将应用程序的任何一个或两个部分配置为禁用日志记录)。

    以下是配置TraceSources和traceswitch的app.config文件的一部分:

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

    或者,可以定义多个tracesource(并引用代码中相应的tracesource)和多个开关。交换机可以共享(即多个tracesource可以使用同一个交换机)。

    以下是一些可能有助于您进行系统诊断的链接:

    .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?

    在我发布的链接中,经常有关于“最佳”日志框架的讨论。我不是想说服你从System.Diagnostics改变。这些链接还倾向于提供有关使用System.Diagnostics的良好信息,这就是我发布它们的原因。

    Ukadc.Diagnostics . 这是一个非常酷的System.Diagnostics附加库,它添加了丰富的格式化功能,类似于使用log4net和NLog。此库对您的应用程序施加仅配置依赖项,而不是代码或引用依赖项。

        2
  •  3
  •   VladV    14 年前

    你不能用这种方式关闭全局跟踪。

    你必须

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

    2) 将此开关与您使用的跟踪源关联:

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

    如果使用静态方法 Trace.Write ,我想,您根本不能使用开关,因为没有应用筛选器的TraceSource。
    如果要通过静态方法关闭跟踪,只需删除所有侦听器: <listeners> <clear/> </listeners> .

        3
  •  2
  •   Alex Humphrey    14 年前

    需要记录时,请检查数据开关的状态,如下所示:

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

    然而,这是相当恶劣的,必须把这些支票到处。是你不想简单地删除 TraceListener

    除此之外,我还将研究使用.NET 2.0+跟踪工具,其中包括 TraceSource . 新的(er)产品提供了更高的配置级别,您可能会发现它更适合。

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

        4
  •  1
  •   tucaz    14 年前

    <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" />
    

        5
  •  1
  •   XDS    12 年前

    晚些时候加入app.config的快速脚注,以防这会让某些人少活几天:

    假设您有包含classA的启动(.exe)projectA,它使用包含classB的projectB(.dll)。

    ClassB反过来使用一个新的TraceSource(“ClassB”)实例。要配置它,您需要修改app.config或projectA。调整projectB的app.config不会有任何效果。

    <system.diagnostics>
    

    app.config中的节如果放在节之前,似乎会导致问题:

    <configSections>
    

    或在章节之后:

    <userSettings>
    

    <?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>
    
        6
  •  0
  •   user3761555    6 年前

    试试这个简单的解决方案。在下面的例子中,“somenoiselibrary”在日志中乱扔许多无用的条目。我们用 “当条件”

    https://github.com/NLog/NLog/wiki/When-Filter

    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            internalLogFile="../log/MyApplication.log"
            autoReload="true" throwExceptions="true">
    
      <targets async="true">
        <target xsi:type="File" 
                name="file"
                layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message} ${exception:format=ToString}"
                fileName="../log/MyApplication.${processid}.${shortdate}.log" keepFileOpen="false"
                maxArchiveFiles="10"
                archiveAboveSize="10024000"
                archiveEvery="Day"
                />
        <target xsi:type="ColoredConsole" 
                name="console" 
                layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message}${exception:format=ToString}" />
      </targets>
    
      <rules>
        <logger name="*" minlevel="Info" writeTo="file,console">
          <filters defaultAction='Log'>
            <when condition="equals('${logger}','SomeNoisyLibrary')" action="Ignore" />
          </filters>
        </logger>
      </rules>
    </nlog>