水平有限, 将就着看吧
官方英文原文
将日志请求插入应用程序代码需要相当多的计划和工作。观察表明,大约4%的代码用于日志记录。因此,即使是中等大小的应用程序也会在代码中嵌入数千条日志语句。考虑到这些日志语句的数量,就必须管理这些日志语句,而无需手动修改它们。
log4net环境是完全可编程配置的。但是,使用配置文件配置log4net要灵活得多。目前,配置文件是用XML编写的。
让我们来看看这是如何完成的, 我们通过一个虚拟的使用log4net的应用程序MyApp应用程序。
using Com.Foo;
// Import log4net classes.
using log4net;
using log4net.Config;
public class MyApp
{
// Define a static logger variable so that it references the
// Logger instance named "MyApp".
private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
static void Main(string[] args)
{
// Set up a simple configuration that logs on the console.
BasicConfigurator.Configure();
log.Info("Entering application.");
Bar bar = new Bar();
bar.DoIt();
log.Info("Exiting application.");
}
}
MyApp从导入Log4NET相关类开始。它之后定义了一个静态记录器变量,名为”MyAPP”,恰好是类的完全限定名。
MyApp使用下面的 Bar 类
// Import log4net classes.
using log4net;
namespace Com.Foo
{
public class Bar
{
private static readonly ILog log = LogManager.GetLogger(typeof(Bar));
public void DoIt()
{
log.Debug("Did it again!");
}
}
}
The output will be formatted using a PatternLayout set to the pattern
BasicConfigurator.Configure()方法创建了一个相当简单的 log4net 安装程序。此方法是硬件连接到根日志记录器中的。输出将使用 PatternLayout 设置模式。
“%-4timestamp [%thread] %-5level %logger %ndc - %message%newline”.
请注意,默认情况下,根记录器是被设置为 Level.DEBUG 。
MyApp 的输出如下:
00 [main] INFO MyApp - Entering application.
36 [main] DEBUG Com.Foo.Bar - Did it again!
51 [main] INFO MyApp - Exiting application.
顺便提一下,在log4net中,子记录器只链接到他们存在的父级。上例中名为”Com.Foo.Bar”的记录器直接链接到 root 记录器,从而避免未使用的记录器Com 或 Com.Foo。这大大提高了性能,减少了log4net的内存占用。
该MyApp类通过调用BasicConfigurator.Config()方法。其他类只需导入log4net命名空间,检索他们希望使用的记录器,然后注销。
前面的示例总是输出相同的日志信息。幸运的是MyApp修改起来很容易。可以在运行时控制日志输出.下面是一个稍微修改过的版本。
using Com.Foo;
// Import log4net classes.
using log4net;
using log4net.Config;
public class MyApp
{
private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
static void Main(string[] args)
{
// BasicConfigurator replaced with XmlConfigurator.
XmlConfigurator.Configure(new System.IO.FileInfo(args[0]));
log.Info("Entering application.");
Bar bar = new Bar();
bar.DoIt();
log.Info("Exiting application.");
}
}
此版本的 MyApp 指定 XmlConfigurator 解析配置文件并相应地设置日志记录。配置文件的路径是通过命令行指定的。
这里是一个示例配置文件,其结果与前面的基于Basic配置器的示例完全相同。
<log4net>
<appender name="A1" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline" />
layout>
appender>
<root>
<level value="DEBUG" />
<appender-ref ref="A1" />
root>
log4net>
[译者注] ndc : Nested Diagnostic Contexts
假设我们对看到属于Com.Foo包的任何组件的输出不再感兴趣。下面的配置文件显示了实现这一点的一种可能方式。
<log4net>
<appender name="A1" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
layout>
appender>
<root>
<level value="DEBUG" />
<appender-ref ref="A1" />
root>
<logger name="Com.Foo">
<level value="WARN" />
logger>
log4net>
用这个文件配置的MyApp的输出如下所示。
2000-09-07 14:07:41,508 [main] INFO MyApp - Entering application.
2000-09-07 14:07:41,529 [main] INFO MyApp - Exiting application.
由于Logger-Com.Foo.Bar没有指定的级别,所以它继承了Com.Foo的级别,它被设置为配置文件中的WARN。来自Bar.DoIt方法的日志语句具有级别DEBUG,低于日志记录级别WARN。因此,DoIt()方法的日志请求被抑制。
这是另一个使用多个appenders的配置文件。
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
layout>
appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="example.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level %thread %logger - %message%newline" />
layout>
appender>
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
root>
log4net>
Calling the enhanced MyApp with the this configuration file will output the following on the console.
使用此配置文件改善过的MyApp将在控制台上输出以下内容。
INFO [main] (MyApp.cs:16) - Entering application.
DEBUG [main] (Bar.cs:12) - Doing it again!
INFO [main] (MyApp.cs:19) - Exiting application.
此外,当根记录器已经设置了第二个appender时,输出也将指向example.log文件。当文件达到100KB时,该文件将被翻滚。当翻滚发生时,旧版本的example.log会自动移动到 example.log.1。
注意,为了获得这些不同的日志记录行为,我们不需要重新编译代码。我们可以轻松地登录到电子邮件地址,将所有Com.Foo 输出重定向到NT事件记录器,或者将日志记录事件转发到远程 log4net 服务器,服务器将根据本地服务器策略进行日志记录。
有关使用 XmlConfigurator 配置 appenders 的更多示例,请参见Example Appender 配置文档。
log4net 配置可以使用程序集级别(assembly-level)属性而不是以编程方式指定。
log4net.Config.XmlConfiguratorAttribute 允许使用以下属性配置 XmlConfigurator :
如果指定,则值是要与XmlConfigurator一起使用的配置文件的文件名。此文件路径是应用程序基础目录(AppDomain.CurrentDomain.BaseDirectory)的相对路径。
此属性不能与ConfigFileExtension展属性一起使用。
如果指定,值是配置文件的扩展名。程序集文件名用作基本名并追加指定的扩展名。例如,如果程序集是从文件TestApp.exe 加载的,并且ConfigFileExtension属性设置为log4net,那么配置文件名是TestApp.exe.log4net。这相当于将ConfigFile 属性设置为 TestApp.exe.log4net.
通过使用应用程序基础目录(AppDomain.CurrentDomain.BaseDirectory)、程序集文件名和配置文件扩展名来构建配置文件的路径。
此属性不能与ConfigFile属性一起使用。
如果此标志被指定并设置为true,则该框架将监视配置文件,并在每次修改文件时重新加载配置。
如果既未指定ConfigFile 也没指定 ConfigFileExtension 属性,则应用程序配置文件(如 TestApp.exe.config)将用作log4net 的配置文件。
示例用法:
// Configure log4net using the .config file
[assembly: log4net.Config.XmlConfigurator(Watch=true)]
// This will cause log4net to look for a configuration file
// called TestApp.exe.config in the application base
// directory (i.e. the directory containing TestApp.exe)
// The config file will be watched for changes.
// Configure log4net using the .log4net file
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net",Watch=true)]
// This will cause log4net to look for a configuration file
// called TestApp.exe.log4net in the application base
// directory (i.e. the directory containing TestApp.exe)
// The config file will be watched for changes.
此属性只能在每个程序集上使用一次
使用属性可以更清楚地定义应用程序的配置将从何处加载。然而,值得注意的是,属性纯粹是被动的。它们只是信息而已。因此,如果使用配置属性,则必须调用 log4net 以允许其读取属性。对 LogManager.GetLogger 的简单调用将导致调用程序集上的属性被读取和处理。因此,在应用程序启动时尽可能早地进行日志调用,并且在加载和调用任何外部程序集之前都必须进行日志调用。
如果使用属性来配置log4net, “appSettings” 的两个设置可以用来重写程序集属性中给出的值。
带有“log4net.Config”键的设置重写配置文件名(并且被认为是相对于应用程序的基本目录)
使用“log4net.Config.Watch”键的设置确定是否应监视文件的更改。即通过assembly属性
[assembly: log4net.Config.XmlConfigurator(Watch=false)]
would configure your application to use a configuration file “TestApp.exe.config” and not monitor it for changes you can override this to use the file “log4net.config” and monitor it instead by adding
将配置你的应用程序使用一个配置文件“TestApp.exe.config”,而不监视它的变化,你可以重写它来使用文件“log4net.config”,并通过添加来监视它。
(这个翻译不明白了, 理解是可以用APP.exe.config文件中使用下面的代码块来设置一个新的配置文件, 在新的配置文件中覆盖原APP.exe.config中的配置, 原理就是添加Watch属性为True来监视新配置文件)
<appSettings>
<add key="log4net.Config" value="log4net.config"/>
<add key="log4net.Config.Watch" value="True"/>
appSettings>
通常,使用文件来指定log4net配置。可以用两种方式之一读取该文件:
该System.Configuration只有当配置数据位于应用程序的配置文件中时,API才可用;MyApp.exe.config或Web.config。因为System.Configuration API不支持重新加载配置文件,无法使用log4net.Config.XmlConfigurator.ConfigureAndWatch方法。使用System.Configuration的API读取配置数据的主要优点在于比直接访问配置文件需要更少的权限。
使用 System.Configuration APIs 配置应用程序的唯一方法是调用log4net.Config.XmlConfigurator.Configure() 方法或log4net.Config.XmlConfigurator.Configure(ILoggerRepository)方法。
为了将配置数据嵌入到.config文件中,必须使用一个configSections元素, 将section的name指定给.NET配置文件解析器。该节必须指定将用于解析配置节的log4net.Config.Log4NetConfigurationSectionHandler处理程序。此类型必须完全限定程序集,因为它是由.NET config文件解析器加载的,而不是由log4net加载的。必须为log4net程序集指定正确的程序集名称。
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
configSections>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
layout>
appender>
<root>
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
root>
log4net>
configuration>
在上面的示例中,log4net指定程序集。此程序集必须位于.NET运行时可以找到它的位置。例如,它可以位于与应用程序相同的目录中。如果log4net程序集存储在GAC中,则必须指定完全限定的程序集名称,包括区域性、版本和公钥。
当使用.config文件指定配置时,节名和XML元素名必须是”log4net”.
XmlConfigurator可以直接读取任何XML文件并使用它配置log4net。这包括应用程序的.config文件;名为MyApp.exe.config或Web.config。不直接读取配置文件的唯一原因是,如果应用程序没有足够的权限读取该文件,则必须使用.NET 的configuration API加载配置(请参阅上文)。
从中读取配置数据的文件, 可以使用log4net.Config.XmlConfigurator任何一个多态方法来接受System.IO.FileInfo对象。因为可以监视文件系统的文件更改通知,所以ConfigreAndWatch方法可用于监视配置文件进行修改,并自动重新配置log4net。
此外,log4net.Config.XmlConfiguratorAttribute可用于指定要从其中读取配置的文件。
配置数据是从文件中的log4net元素读取的。在文件中只能有一个”log4net”元素被指定,但它可以位于XML层次结构中的任何位置。例如,它可能是根元素:
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
layout>
appender>
<root>
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
root>
log4net>
或者它可以嵌套在其他元素中:
<configuration>
<configSections>
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
configSections>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
layout>
appender>
<root>
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
root>
log4net>
configuration>
上面的示例展示了如何将配置数据嵌入到.config文件中,即使是被log4net直接读取的。一个重要的注意事项是,如果.NET 的配置文件解析器找到一个未注册的配置节元素, 它会抛出一个异常。因此,在上面的示例中,log4net节名称已注册,但指定处理节的类型为System.Configuration.IgnoreSectionHandler。这是一个内建类,表示将使用另一种读取配置部分的函数。
log4net包括一个用来解析XML DOM的配置读取器,log4net.Config.XmlConfigurator。本节定义了配置器接受的语法。
这是一个有效XML配置的示例。根元素必须是。请注意,这并不意味着该元素不能嵌入到另一个XML文档中。见上文关于配置文件有关如何在配置文件中嵌入XmlConfigurator XML的详细信息。
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
layout>
appender>
<root>
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
root>
log4net>
该元素支持以下属性:
debug 可选属性. 值必须是true或false。默认值是false。若要为此配置启用内部log4net调试, 可将此属性设置为true.
update 可选属性. 值必须是Merge或Overwrite。默认值是Merge。, 若要在应用此配置之前重置正在配置的存储库的配置, 可将此属性设置为Overwrite.
threshold 可选属性. 值必须是在存储库中注册的级别的名称。默认值是ALL。设置此属性以限制记录在整个存储库中的消息,而不管该消息被记录到哪个记录器。
该元素支持以下子元素:
Appenders只能定义为的子元素。每个appender都必须有唯一的名称。必须指定appender的实现类型。
这个例子演示了一个类型为log4net.Appender.ConsoleAppender正在被定义。这个附录将被称为ConsoleAppender.
"ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
"log4net.Layout.PatternLayout">
"%date [%thread] %-5level %logger [%ndc] - %message%newline" />
</layout>
>
该元素支持以下属性:
For examples of configuring appenders see the Example Appender Configuration document.
有关配置appenders 的示例,请参阅Appender Configuration文档。
该元素支持以下子元素:
有关配置appenders的示例,请参阅Appender Configuration文档。
Filters只能定义为的子元素。
元素支持以下属性:
元素支持以下子元素:
过滤器形成事件必须通过的链。沿途的任何筛选器都可以接受事件并停止处理,拒绝事件并停止处理,或者允许事件进入下一个筛选器。如果该事件到达筛选链的末尾而未被拒绝,则将隐式接受并记录该事件。
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
filter>
此筛选器将拒绝级别低于INFO或高于FATAL。之间的所有事件INFO和FATAL都会被记录下来。
如果我们只允许消息通过具有特定子字符串(例如“database”)的消息,那么我们需要指定以下过滤器:
type="log4net.Filter.StringMatchFilter">
value="database" />
type="log4net.Filter.DenyAllFilter" />
第一个过滤器将在事件的消息文本中查找子字符串“Database”。如果找到文本,过滤器将接受消息,过滤处理将停止,消息将被记录下来。如果没有找到子字符串,则事件将传递给要处理的下一个筛选器。如果没有下一个筛选器,则事件将被隐式接受并记录下来。但是,因为我们不希望记录不匹配的事件,所以我们需要使用log4net.Filter.DenyAllFilter这只会否认所有到达它的事件。此过滤器仅在筛选链的末尾有用。
如果我们希望允许消息文本中包含“database库”或“ldap”的事件,我们可以使用以下筛选器:
type="log4net.Filter.StringMatchFilter">
value="database"/>
type="log4net.Filter.StringMatchFilter">
value="ldap"/>
type="log4net.Filter.DenyAllFilter" />
Layouts只能定义为的子元素。
元素支持以下属性:
元素支持以下子元素:
此示例演示如何配置使用log4net.Layout.PatternLayout.
"log4net.Layout.PatternLayout">
"%date [%thread] %-5level %logger [%ndc] - %message%newline" />
</layout>
只能定义一个根记录器元素,它必须是的子元素。根记录器是记录器层次结构的根。所有记录器最终都继承了这个记录器。
<root>
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
root>
该元素不支持任何属性。
该元素支持以下子元素:
Loggers元素只能定义为子元素。
一个例子记录器:
<logger name="LoggerName">
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
logger>
该元素支持以下属性。
该元素支持以下子元素:
呈现器元素只能定义为元素。
一个示例渲染器:
<renderer renderingClass="MyClass.MyRenderer" renderedClass="MyClass.MyFunkyObject" />
该元素支持以下属性。
该元素不支持子元素。
Parameters元素可能是许多元素的子元素。有关详细信息,请参阅上面的特定元素。
一个例子Param:
"ConversionPattern" value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
该元素支持以下属性。
该元素支持以下子元素:
配置参数直接映射到对象上的可写属性。可用属性取决于所配置对象的实际类型。log4net SDK 文档包含log4net程序集中包含的所有组件的API引用。
有关第三方组件,请参阅其相关API参考资料,以了解可用属性的详细信息。
可以使用参数名作为元素名称交替地指定所有参数,而不是使用 param 元素和 name 属性。
例如一个参数
<param name="evaluator" type="log4net.spi.LevelEvaluator">
<param name="Threshold" value="WARN"/>
<param>
可以写成:
<evaluator type="log4net.spi.LevelEvaluator">
<threshold value="WARN"/>
<evaluator>