我正在尝试使用System.Diagnostics做一些非常基本的日志记录。我想我会使用框中的内容,而不是像Log4Net或EntLib那样使用额外的依赖。
我已经全部成立,追踪工作非常好。代码段:
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>
我的小“Hello World”很好地显示在我的Trace.log文件中。但现在我想关闭跟踪,所以我深入了解MSDN并找到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")
这对我没有意义:我只需要通过.config文件声明BooleanSwicth
的实例能够管理(禁用)跟踪?我应该喜欢...... 使用 ...某个地方的对象?
无论如何,我确信我错过了一些非常明显的东西。请帮忙。
如何在app.config中关闭跟踪?
答案 0 :(得分:34)
我同意@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调用将根据相关Switch的配置级别自动检查消息级别(TraceEventType.Information),并确定是否应该实际写出消息。
通过为每种类型使用不同名称的TraceSource,您可以单独控制这些类的日志记录。您可以启用MyClass1日志记录,也可以禁用它,或者您可以启用它,但只有在消息级别(TraceEventType)大于某个值(可能只记录“警告”和更高级别)时才进行日志记录。同时,您可以打开或关闭MyClass2中的日志记录或设置为一个级别,完全独立于MyClass1。所有这些启用/禁用/级别的东西都发生在app.config文件中。
使用app.config文件,您也可以以相同的方式控制所有TraceSource(或TraceSources组)。因此,您可以进行配置,以便MyClass1和MyClass2都由同一个Switch控制。
如果您不希望每种类型都有不同名称的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);
}
}
这样,您可以使应用程序中的所有日志记录发生在同一级别(或者关闭或使用相同的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”部分设置为一个级别,而应用程序的“分析”部分则在不同级别(当然,应用程序的任一部分或两部分)可以配置,以便禁用日志记录。)
以下是配置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>
正如您所看到的,您可以配置单个TraceSource和单个Switch,并且所有日志记录都可以通过单一级别的控制进行(即您可以关闭所有日志记录或使其在特定级别进行日志记录)。
或者,您可以定义多个TraceSource(并在代码中引用相应的TraceSource)和多个Switch。可以共享交换机(即多个TraceSource可以使用相同的交换机)。
最后,通过现在花费更多精力来使用TraceSources并在代码中引用适当命名的TraceSources(即逻辑定义TraceSource名称,以便您可以对应用程序中的日志记录进行所需的控制程度),从长远来看,将获得显着的灵活性。
以下是一些可能会帮助您使用System.Diagnostics的链接:
.net Diagnostics 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做的。此库对您的应用程序施加仅限配置依赖性,而不是代码或引用依赖项。
答案 1 :(得分:3)
您不会以这种方式全局关闭跟踪。
你必须 1)声明一个开关并设置其值:
<switches>
<add name="MySwitch" value="Information"/>
</switches>
2)将此开关与您使用的TraceSource相关联:
<sources>
<source name="MySource" switchName="MySwitch"/>
</source>
因此,无论您通过名为“MySource”的TraceSource写入的内容都会根据切换值进行过滤。
如果您使用Trace.Write
之类的静态方法,我想,根本不能使用开关,因为没有TraceSource来应用过滤器。
如果要通过静态方法关闭跟踪,只需删除所有侦听器:<listeners> <clear/> </listeners>
。
答案 2 :(得分:1)
是源节点的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" />
答案 3 :(得分:1)
根据需要,在需要登录时检查dataSwitch的状态:
http://msdn.microsoft.com/en-us/library/aa984285%28v=VS.71%29.aspx
然而,这是非常讨厌的,不得不把这些检查放在任何地方。他们是不是只想从app.config中的侦听器集合中删除TraceListener
的原因?
除此之外,我还会调查使用包含TraceSource
的.NET 2.0+跟踪内容。新的(呃)东西提供了更高程度的配置,你可能会发现它更合适。
答案 4 :(得分:1)
最近加入了一个关于app.config的快速脚注,如果这样可以节省几天人员的生命:
假设你有一个包含classA的启动(.exe)projectA,它使用包含classB的projectB(.dll)。
ClassB又使用了一个新的TraceSource(“classB”)实例。要进行配置,您需要修改app.config或projectA。调整projectB的app.config不会导致任何问题。
还要注意
的位置<system.diagnostics>
app.config中的部分如果放在部分之前似乎会导致问题:
<configSections>
或在以下部分之后:
<userSettings>
至少在我的情况下,当我试图将它放在我项目的app.config中的这些位置时,我遇到了错误。适合我的布局是:
<?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>
答案 5 :(得分:0)
尝试这个简单的解决方案。在下面的示例中,“ SomeNoisyLibrary”在日志中堆满了许多无用的条目。我们用“条件成立”
对其进行过滤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>