简体   繁体   English

通过app.config关闭跟踪

[英]Turning tracing off via app.config

I'm trying to use System.Diagnostics to do some very basic logging. 我正在尝试使用System.Diagnostics做一些非常基本的日志记录。 I figure I'd use what's in the box rather than taking on an extra dependency like Log4Net or EntLib. 我想我会使用框中的内容,而不是像Log4Net或EntLib那样使用额外的依赖。

I'm all set up, tracing is working wonderfully. 我已经全部成立,跟踪工作非常好。 Code snippet: 代码段:

Trace.TraceInformation("Hello World")

App.config: 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>

and my little "Hello World" shows nicely up in my Trace.log file. 而我的小“Hello World”在我的Trace.log文件中显示得很好。 But now I'd like to switch OFF tracing, so I dig into MSDN and find How to: Configure Trace Switches . 但现在我想关闭跟踪,所以我深入了解MSDN并找到如何:配置跟踪开关 I add the <switches> element, and now my app.config looks like this: 我添加<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>

The value="0" should turn off tracing - at least if you then follow How to: Create and Initialize Trace Switches , which tells you to add this line of code: value="0"应该关闭跟踪 - 至少如果你按照如何:创建和初始化跟踪开关 ,它告诉你添加这行代码:

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

That doesn't make sense to me: I just have to declare an instance of the BooleanSwicth to be able to manage (disable) tracing via the .config file? 这对我来说没有意义:我只需要声明一个BooleanSwicth实例,以便能够通过.config文件管理(禁用)跟踪? Should I like ... use ... the object somewhere? 我应该...在某处使用 ......对象?

Anyways, I'm sure I missed something really obvious somewhere. 无论如何,我确定我错过了一些非常明显的东西。 Please help. 请帮忙。

How do I switch OFF tracing in app.config? 如何在app.config中关闭跟踪?

I agree with @Alex Humphrey's recommendation to try using TraceSources. 我同意@Alex Humphrey建议尝试使用TraceSources。 With TraceSources you gain more control over how your logging/tracing statements execute. 使用TraceSources,您可以更好地控制日志记录/跟踪语句的执行方式。 For example, you could have code like this: 例如,您可以使用以下代码:

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

The TraceSource.TraceEvent call will automatically check the level of the message (TraceEventType.Information) against the configured level of the associated Switch and will determine whether or not the message should actually be written out. TraceSource.TraceEvent调用将根据关联的Switch的配置级别自动检查消息级别(TraceEventType.Information),并确定是否应该实际写出消息。

By using a differently named TraceSource for each type, you can control the logging from those classes individually. 通过为每种类型使用不同名称的TraceSource,您可以单独控制这些类的日志记录。 You could enable MyClass1 logging or you could disable it or you could enable it but have it log only if the level of the message (TraceEventType) is greater than a certain value (maybe only log "Warning" and higher). 您可以启用MyClass1日志记录,也可以禁用它,或者您可以启用它,但只有在消息级别(TraceEventType)大于某个值(可能只记录“警告”和更高级别)时才进行日志记录。 At the same time, you could turn logging in MyClass2 on or off or set to a level, completely independently of MyClass1. 同时,您可以打开或关闭MyClass2中的日志记录或设置为一个级别,完全独立于MyClass1。 All of this enabling/disabling/level stuff happens in the app.config file. 所有这些启用/禁用/级别的东西都发生在app.config文件中。

Using the app.config file, you could also control all TraceSources (or groups of TraceSources) in the same way. 使用app.config文件,您还可以以相同的方式控制所有TraceSource(或TraceSources组)。 So, you could configure so that MyClass1 and MyClass2 are both controlled by the same Switch. 因此,您可以进行配置,以便MyClass1和MyClass2都由同一个Switch控制。

If you don't want to have a differently named TraceSource for each type, you could just create the same TraceSource in every class: 如果您不希望每种类型都有不同名称的TraceSource,则可以在每个类中创建相同的TraceSource:

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

This way, you could make all logging within your application happen at the same level (or be turned off or go the same TraceListener, or whatever). 这样,您可以使应用程序中的所有日志记录发生在同一级别(或关闭或使用相同的TraceListener,或其他任何方式)。

You could also configure different parts of your application to be independently configurable without having to go the "trouble" of defining a unique TraceSource in each type: 您还可以将应用程序的不同部分配置为可独立配置,而无需在每种类型中定义唯一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);
  }
}

With your class instrumented this way, you could make the "DataAccess" part of your app log at one level while the "Analysis" part of your app logs at a different level (of course, either or both parts of your app could be configured so that logging is disabled). 通过这种方式对您的课程进行检测,您可以将应用程序日志中的“DataAccess”部分设置为一个级别,而应用程序的“分析”部分则在不同级别进行记录(当然,可以配置应用程序的任一部分或两个部分)以便禁用日志记录)。

Here is a part of an app.config file that configures TraceSources and TraceSwitches: 以下是配置TraceSources和TraceSwitches的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>

As you can see, you could configure a single TraceSource and a single Switch and all logging would occur with a single level of control (ie you could turn all logging off or make it log at a certain level). 如您所见,您可以配置单个TraceSource和单个Switch,并且所有日志记录都可以通过单一级别的控制进行(即您可以关闭所有日志记录或使其在特定级别进行日志记录)。

Alternatively, you could define multiple TraceSources (and reference the corresponding TraceSources in your code) and multiple Switches. 或者,您可以定义多个TraceSource(并在代码中引用相应的TraceSource)和多个Switch。 The Switches may be shared (ie multiple TraceSources can use the same Switch). 可以共享交换机(即,多个TraceSource可以使用相同的交换机)。

Ultimately, by putting in a little more effort now to use TraceSources and to reference appropriately named TraceSources in your code (ie define the TraceSource names logically so that you can have the desired degree of control over logging in your app), you will gain significant flexibility in the long run. 最后,通过现在花费更多努力来使用TraceSources并在代码中引用适当命名的TraceSources(即逻辑定义TraceSource名称以便您可以对应用程序中的日志记录进行所需程度的控制),您将获得显着的收益从长远来看具有灵活性。

Here are a few links that might help you with System.Diagnostics as you go forward: 以下是一些可能会帮助您使用System.Diagnostics的链接:

.net Diagnostics best practices? .net Diagnostics最佳实践?

Logging best practices 记录最佳实践

What's the best approach to logging? 记录的最佳方法是什么?

Does the .Net TraceSource/TraceListener framework have something similar to log4net's Formatters? .Net TraceSource / TraceListener框架是否具有与log4net的Formatters类似的东西?

In the links I posted, there is often discussion of the "best" logging framework. 在我发布的链接中,经常讨论“最佳”日志框架。 I am not trying to convince you to change from System.Diagnostics. 我并不想说服您从System.Diagnostics更改。 The links also tend to have good information about using System.Diagnostics, that is why I posted them. 链接也往往有关于使用System.Diagnostics的良好信息,这就是我发布它们的原因。

Several of the links I posted contain a link to Ukadc.Diagnostics . 我发布的一些链接包含指向Ukadc.Diagnostics的链接。 This is a really cool add on library for System.Diagnostics that adds rich formatting capability, similar to what you can do with log4net and NLog. 这是System.Diagnostics的一个非常酷的库添加库,它增加了丰富的格式化功能,类似于你可以用log4net和NLog做的。 This library imposes a config-only dependency on your app, not a code or reference dependency. 此库对您的应用程序施加仅配置依赖项,而不是代码或引用依赖项。

You don't turn off tracing globally this way. 您不会以这种方式全局关闭跟踪。

You have to 你必须
1) declare a switch and set its value: 1)声明一个开关并设置其值:

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

2) associate this switch with a TraceSource you use: 2)将此开关与您使用的TraceSource相关联:

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

So, whatever you write via TraceSource named "MySource" is filtered according to the switch value. 因此,无论您通过名为“MySource”的TraceSource写入什么,都会根据开关值进行过滤。

If you use static methods like Trace.Write , I suppose, you cannot use switches at all, because there is no TraceSource to apply the filter. 如果你使用像Trace.Write这样的静态方法,我猜你根本不能使用开关,因为没有TraceSource来应用过滤器。
If you want to turn off tracing by static methods, just remove all the listeners: <listeners> <clear/> </listeners> . 如果要通过静态方法关闭跟踪,只需删除所有侦听器: <listeners> <clear/> </listeners>

Late joining with a quick footnote about the app.config, in case this saves a couple of days from the life of someone out there: 迟到加入关于app.config的快速脚注,以防万一从那里的人的生命中节省了几天:

Assume you have the startup (.exe) projectA containing classA which makes use of projectB (.dll) containing classB. 假设您有包含classA的启动(.exe)projectA,它使用包含classB的projectB(.dll)。

ClassB in turn makes use of a new TraceSource("classB") instance. ClassB又使用了一个新的TraceSource(“classB”)实例。 In order to configure it you need to modify the app.config or projectA. 要进行配置,您需要修改app.config或projectA。 Tweaking the app.config of projectB won't lead anywhere. 调整projectB的app.config不会导致任何问题。

Also note that the placement of the 还要注意放置的

<system.diagnostics>

Section inside app.config seems to be causing problems if placed before the section: 如果放在该部分之前,app.config中的部分似乎会导致问题:

<configSections>

or after the section: 或在以下部分之后:

<userSettings>

At least in my case, I was getting errors when I attempted to place it in these locations in the app.config of my project. 至少在我的情况下,当我试图将它放在我项目的app.config中的这些位置时,我遇到了错误。 The layout that worked for me was: 适合我的布局是:

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

It´s the switchValue attribute of source node: 它是源节点的switchValue属性:

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

Check the state of dataSwitch whenever you need to log, as per: 根据需要,在需要登录时检查dataSwitch的状态:

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

However, that is pretty nasty, having to put those checks everywhere. 然而,这是非常讨厌的,不得不把这些检查放在各处。 Is their a reason you don't want to simply remove the TraceListener from the listeners collection in app.config? 他们是不是只想从app.config中的侦听器集合中删除TraceListener的原因?

Apart from that, I'd investigate using the .NET 2.0+ trace stuff which includes TraceSource . 除此之外,我还将研究使用包含TraceSource的.NET 2.0+跟踪内容。 The new(er) stuff offers a much higher degree of configuration, and you might find it's more suitable. 新的(呃)东西提供了更高程度的配置,你可能会发现它更合适。

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

Try this simple solution. 试试这个简单的解决方 In example below, "SomeNoisyLibrary" is littering the log with many useless entries. 在下面的示例中,“SomeNoisyLibrary”使用许多无用的条目乱丢日志。 We filter them with "when condition" 我们用“条件时”过滤它们

https://github.com/NLog/NLog/wiki/When-Filter 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM