原文:http://logging.apache.org/log4net/release/manual/configuration.html
Configuration
插入到应用程序代码的日志请求需要相当数量的规划和努力。观测表明,约百分之四的代码是专门记录日志。甚至中等规模的应用程序将有成千上万的记录日志语句嵌入到代码中。出于日志记录语句数量之大,有必要管理这些语句而不必手动修改它。
log4net的环境是完全可配置编程。但是,它更加灵活地配置使用配置文件来配置log4net的。目前,配置文件被写入到XML中。
让我们使用一个假想的应用项目MyApp来尝试一下如何使用og4net。
1: using Com.Foo;
2:
3: // Import log4net classes.
4: using log4net;
5: using log4net.Config;
6:
7: public class MyApp
8: {
9: // Define a static logger variable so that it references the
10: // Logger instance named "MyApp".
11: private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
12:
13: static void Main(string[] args)
14: {
15: // Set up a simple configuration that logs on the console.
16: BasicConfigurator.Configure();
17:
18: log.Info("Entering application.");
19: Bar bar = new Bar();
20: bar.DoIt();
21: log.Info("Exiting application.");
22: }
23: }
首先导入log4net相关类。然后通过类名MyApp(类的完全限定名)定义一个静态的logger变量.
MyApp使用了下面的Bar类。
1: // Import log4net classes.
2: using log4net;
3:
4: namespace Com.Foo
5: {
6: public class Bar
7: {
8: private static readonly ILog log = LogManager.GetLogger(typeof(Bar));
9:
10: public void DoIt()
11: {
12: log.Debug("Did it again!");
13: }
14: }
15: }
BasicConfigurator.Configure()方法调用创建了一个相当简单的log4net的设置。这个方法是硬添加到根日志记录器一个ConsoleAppender。日志输出格式使用"%-4timestamp [%thread] %-5level %logger %ndc - %message%newline"模式格式化。
注意:在默认情况下,根记录器被被指定为Level.DEBUG。
MyApp在控制台输出日志如下:
1: 0 [main] INFO MyApp - Entering application.
2: 36 [main] DEBUG Com.Foo.Bar - Did it again!
3: 51 [main] INFO MyApp - Exiting application.
特别说明下,log4net中的子记录器只会连接祖先记录器。特别是,Com.Foo.Bar的记录器直接与根记录器相关联。从而规避未使用的Com或Com.Foo的记录器,这显着提高性能和降低log4net的内存消耗。
MyApp类通过调用BasicConfigurator.Configure()进行配置。其它的类只需要导入log4net命名空间,检索需要使用的记录器,就可以使用日志记录。
前面的示例一直输出同样的信息。幸运的是,在运行时可以很容易修改MyApp的日志输出格式,这里就是一个轻量级的版本。
1: using Com.Foo;
2:
3: // Import log4net classes.
4: using log4net;
5: using log4net.Config;
6:
7: public class MyApp
8: {
9: private static readonly ILog log = LogManager.GetLogger(typeof(MyApp));
10:
11: static void Main(string[] args)
12: {
13: // BasicConfigurator replaced with XmlConfigurator.
14: XmlConfigurator.Configure(new System.IO.FileInfo(args[0]));
15:
16: log.Info("Entering application.");
17: Bar bar = new Bar();
18: bar.DoIt();
19: log.Info("Exiting application.");
20: }
21: }
此版本的MyApp指示XmlConfigurator解析一个配置文件,并设置相关配置。配置文件的在命令行里指定。
这个示例配置文件,日志输出结果与通过BasicConfigurator配置完全一样。
1: <log4net>
2: <!-- A1 is set to be a ConsoleAppender -->
3: <appender name="A1" type="log4net.Appender.ConsoleAppender">
4:
5: <!-- A1 uses PatternLayout -->
6: <layout type="log4net.Layout.PatternLayout">
7: <conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline" />
8: </layout>
9: </appender>
10:
11: <!-- Set root logger level to DEBUG and its only appender to A1 -->
12: <root>
13: <level value="DEBUG" />
14: <appender-ref ref="A1" />
15: </root>
16: </log4net>
假设我们对封装Com.Foo下的任何组件的输出不再感兴趣。下面的配置文件可以实现这一目标。
1: <log4net>
2: <!-- A1 is set to be a ConsoleAppender -->
3: <appender name="A1" type="log4net.Appender.ConsoleAppender">
4:
5: <!-- A1 uses PatternLayout -->
6: <layout type="log4net.Layout.PatternLayout">
7: <!-- Print the date in ISO 8601 format -->
8: <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
9: </layout>
10: </appender>
11:
12: <!-- Set root logger level to DEBUG and its only appender to A1 -->
13: <root>
14: <level value="DEBUG" />
15: <appender-ref ref="A1" />
16: </root>
17:
18: <!-- Print only messages of level WARN or above in the package Com.Foo -->
19: <logger name="Com.Foo">
20: <level value="WARN" />
21: </logger>
22: </log4net>
这个配置的MyApp输出如下所示(注:Bar的日志未输出)
1: 2000-09-07 14:07:41,508 [main] INFO MyApp - Entering application.
2: 2000-09-07 14:07:41,529 [main] INFO MyApp - Exiting application.
由于记录器Com.Foo.Bar没有一个分配的等级,它继承了Com.Foo(在上面的配置文件中已设置为”WARN”)等级。Bar.DoIt方法中的日志记录语句具有DEBUG等级,低于WARN等级。因此,DoIt()方法的日志请求被阻止。
下面是一个配置了多个附着器(appender)的配置文件示例
1: <log4net>
2: <appender name="Console" type="log4net.Appender.ConsoleAppender">
3: <layout type="log4net.Layout.PatternLayout">
4: <!-- Pattern to output the caller's file name and line number -->
5: <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
6: </layout>
7: </appender>
8:
9: <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
10: <file value="example.log" />
11: <appendToFile value="true" />
12: <maximumFileSize value="100KB" />
13: <maxSizeRollBackups value="2" />
14:
15: <layout type="log4net.Layout.PatternLayout">
16: <conversionPattern value="%level %thread %logger - %message%newline" />
17: </layout>
18: </appender>
19:
20: <root>
21: <level value="DEBUG" />
22: <appender-ref ref="Console" />
23: <appender-ref ref="RollingFile" />
24: </root>
25: </log4net>
调用此配置文件的MyApp将加强在控制台上输出。
1: INFO [main] (MyApp.cs:16) - Entering application.
2: DEBUG [main] (Bar.cs:12) - Doing it again!
3: INFO [main] (MyApp.cs:19) - Exiting application.
此外,根记录器已被分配了第二Appender,输出也将被引导到example.log文件中,此文件如果大小达到了100KB以后,将会展开滚动。当展开滚动时,旧版的example.og自动移到example.log.1。
请注意,要获得这些不同的记录的行为,我们并不需要重新编译代码。我们可以很容易地将日志发送到电子邮箱里,或所有Com.Foo重定向输出到一个NT事件记录器,或者根据当地的日志服务器策略,将记录事件或转发到远程log4net的服务器。
更多的使用XmlConfigurator配置appenders示例请参照“Example Appender Configuration” 文档。
Configuration Attributes
log4net的配置可以配置使用程序集级别的特性,而不是指定的编程。
- XmlConfiguratorAttribute :log4net.Config.XmlConfiguratorAttribute允许以下特性配置XmlConfigurator
ConfigFile 如果指定,XmlConfigurator将使用该配置文件,文件的路径是相对应用项目的根目录(AppDomain.CurrentDomain.BaseDirectory),也可以是绝对路径。该属性不能与“ConfigFileExtension”属性一起使用。
ConfigFileExtension 如果指定,将对配置文件进行扩展。程序集的名字将追加到扩展文件名里,作为基本的名字。例如,如果程序集是从TestApp.exe文件中加载,并且log4net设置了ConfigFileExtension属性,则配置文件的名字是“TestApp.exe.log4net”,这相当于给TestApp.exe.log4net设置了ConfigFile属性。
配置文件将编译输出到项目根目录(AppDomain.CurrentDomain.BaseDirectory),程序集名和配置文件扩展名就是该配置的名字。
这个属性不能与ConfigFile属性一起使用。
Watch 如果指定并设置为“True”,那么框架将监视配置文件,每次配置修改将重新加载。
如果既没有指定ConfigFile, 也没有指定ConfigFileExtension,项目默认配置文件(例如:TestApp.exe.config)将作为log4net的配置文件。
示例:
1: // Configure log4net using the .config file
2: [assembly: log4net.Config.XmlConfigurator(Watch=true)]
3: // This will cause log4net to look for a configuration file
4: // called TestApp.exe.config in the application base
5: // directory (i.e. the directory containing TestApp.exe)
6: // The config file will be watched for changes.
1: // Configure log4net using the .log4net file
2: [assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net",Watch=true)]
3: // This will cause log4net to look for a configuration file
4: // called TestApp.exe.log4net in the application base
5: // directory (i.e. the directory containing TestApp.exe)
6: // The config file will be watched for changes.
这些特性在每个程序集中只能使用一次。
使用属性,将使得方法定义从哪里加载项目的配置变得更清晰。但值得注意的是,特性是纯粹的被动特性。它们只有被通知。因此如果你使用了配置特性,你必须请求Log4et允许读取特性。调用LogManager.GetLogger方法,将读取和处理程序集特性。因此在应用程序启动时尽可能早的启动记录,并且在任何外部组件已加载并调用前。
Configuration Files
通常情况下,log4net的配置指定使用文件。此文件用两种方法读取:
- 使用.NET System.Configuration API
- 直接读取文件内容
.config Files
System.Configuration API只有在配置数据是在项目配置文件中才可以使用;文件名一般是MyApp.exe.config 或 Web.config,因System.Configuration API不支持重新加载配置文件,所有og4net.Config.XmlConfigurator.ConfigureAndWatch无法监视配置的更改。使用System.Configuration API的优势就是可以直接访问配置文件,而不需要设置什么权限。通过log4net.Config.XmlConfigurator.Configure()和log4net.Config.XmlConfigurator.Configure()方法使用System.Configuration API。
为了把配置数据嵌入到.config文件中,必须使用configSections元素给.Net config文件分析器确定日志处理节点。节点必须指定为log4net.Config.Log4NetConfigurationSectionHandler来处理分析配置。这个节点分析处理类型必须用完全限定名指定,因为它是通过.NET config文件分析器来加载而不是Log4net. 正确的程序集名log4net必须被指定。下面的配置示例指定了section处理器处理log4ne5节点。
1: <?xml version="1.0" encoding="utf-8" ?>
2: <configuration>
3: <configSections>
4: <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
5: </configSections>
6: <log4net>
7: <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
8: <layout type="log4net.Layout.PatternLayout">
9: <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
10: </layout>
11: </appender>
12: <root>
13: <level value="INFO" />
14: <appender-ref ref="ConsoleAppender" />
15: </root>
16: </log4net>
17: </configuration>
上面的示例指定了log4net程序集。该程序集在.NET运行时被加载,例如它可能放置在根目录下。如果log4net存储了GAC信息,那么程序集的完全限定名必须包含culture, version 和 public key。
配置文件中,通过使用log4net元素来配置。
Reading Files Directly
XmlConfigurator可以直接读取任何的XML文件并通过它来配置log4net, 这包括应用程序的.config文件(MyApp.exe.config 或 Web.config.),不能直接读取配置文件的唯一原因就是没有足够的权限来读取该文件,而配置必须通过.NET configuration APIs来加载。
log4net.Config.XmlConfigurator有多个重载方法读取配置文件,其中就可以接受ystem.IO.FileInfo对象参数。因为文件系统是可以被监视更改通知的,使用ConfigureAndWatch方法用来监视配置文件的更改,并自动的重新配置log4net。
除此之外,log4net.Config.XmlConfiguratorAttribute用来指定从哪里读取配置。
配置文件从log4net开始读起,只有log4net元素在文件中指定,但是它可以在放在XML层次结构中的任何地方。如下示例log4net就是根元素
1: <?xml version="1.0" encoding="utf-8" ?>
2: <log4net>
3: <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
4: <layout type="log4net.Layout.PatternLayout">
5: <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
6: </layout>
7: </appender>
8: <root>
9: <level value="INFO" />
10: <appender-ref ref="ConsoleAppender" />
11: </root>
12: </log4net>
也可以内嵌在其他元素中
1: <?xml version="1.0" encoding="utf-8" ?>
2: <log4net>
3: <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
4: <layout type="log4net.Layout.PatternLayout">
5: <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
6: </layout>
7: </appender>
8: <root>
9: <level value="INFO" />
10: <appender-ref ref="ConsoleAppender" />
11: </root>
12: </log4net>
Configuration Syntax
log4net包含一个配置读取器来分析XML文档,log4net.Config.XmlConfigurator,本小节定义配置器接受的语法。
下面是一个有效的XML配置,根节点必须是<log4net>,注意这并不是意味着这个元素不能嵌入到其他XML文档中。参照上一节。
1: <log4net>
2: <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
3: <layout type="log4net.Layout.PatternLayout">
4: <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
5: </layout>
6: </appender>
7: <root>
8: <level value="INFO" />
9: <appender-ref ref="ConsoleAppender" />
10: </root>
11: </log4net>
<log4net>元素支持以下属性:
元素 | 描述 |
debug | 可选属性,属性值为“True”或“False”,默认值为“False”,如果设置为“Ture”,log4net将启用内部调试功能。 |
update | 可选属性,属性值为“Merge”或“Overwrite”,默认值为“Merge”,如果值为“Overwrite”,在应用这些配置前重新设置 |
threshold | 可选属性,值必须是在repository注册的等级。默认值是ALL。该值设置repository全部纪录器的等级,不管调用什么等级的记录 |
<log4net>支持以下子元素
元素 | 描述 |
appender | 无或者多个,定义一个appender |
logger | 无或者多个,配置一个记录器 |
renderer | 无或者多个,定义一个renderer |
root | 可选元素,最多只能一个。定义根记录器 |
param | 无或者多个,Repository 具体参数 |
Appenders
Appender只能定义为<log4net>元素的子元素。每个appender名字必须是唯一的,且必须指定实现类型。
下面的示例定义log4net.Appender.ConsoleAppender类型的Appender,appender的类型是ConsoleAppender.
1: <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
2: <layout type="log4net.Layout.PatternLayout">
3: <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
4: </layout>
5: </appender>
appender支持以下属性
属性 | 描述 |
name | 必须属性。命名appender,名字在所有定义的appender中必须是唯一的。Logger记录器可以通过<appender-ref>指定appender名字来引用一个appender. |
type | 必要属性,值是Appender类型名.如果Appender未在log4net程序集中定义,则必须是完全限定名。 |
<appender>元素支持以下子元素
元素 | 描述 |
appender-ref | 无或多个,允许appender引用另一个appender。 |
filter | 无或多个,定义filter |
layout | 可选元素,最多一个,定义展示格式 |
param | 无或多个,appender指定参数 |
Filters
filtes元素只能定义为Appender的子元素
该元素支持以下属性
属性 | 描述 |
type | 必要属性,值是filter类型名。如果该filter不是在log4net中定义的,则必须指定完全限定的名。 |
<filte>元素支持以下子元素
元素 | 属性 |
param | 无或者多个,filter指定参数 |
filters 形成一个过滤器链,事件都必须通过它。任何filter都可以接受事件并停止工作,否认该事件并停止处理,或者允许到下一个过滤器事件。如果该事件已经到了过滤器的链的末端没有被拒绝接受,它将被隐式地记录。
1: <filter type="log4net.Filter.LevelRangeFilter">
2: <levelMin value="INFO" />
3: <levelMax value="FATAL" />
4: </filter>
filter将否认低于INFO级别和高于FATAL的事件,所有在这两个级别间的事件都将被记录。
如果只想包含某指定的子字符串的信息通过(比如:“database”), 我们需要指定以下过滤器:
1: <filter type="log4net.Filter.StringMatchFilter">
2: <stringToMatch value="database" />
3: </filter>
4: <filter type="log4net.Filter.DenyAllFilter" />
第一个过滤器在事情信息中查找”database”字符。如果文本找到了,过滤器将接受信息和过滤处理将停止,消息将记录。如果文本未找到,事件将传递给下一个过滤器处理。如果已经无过滤器了,事情将隐式地接受和记录。但是,因为我们不希望不匹配的事件记录,我们需要使用一个log4net.Filter.DenyAllFilter处理所有被否认后到达它的事件。这个过滤器在过滤器处理链中末端非常有用。
如果我们想接受事件文本中包含'database' 或 'ldap'的事件,可以如下配置:
1: <filter type="log4net.Filter.StringMatchFilter">
2: <stringToMatch value="database"/>
3: </filter>
4: <filter type="log4net.Filter.StringMatchFilter">
5: <stringToMatch value="ldap"/>
6: </filter>
7: <filter type="log4net.Filter.DenyAllFilter" />
Layouts
Layout元素只能定义为<appender>的子元素,支持以下属性
属性 | 描述 |
type | 必要属性。值是layout类型名。如果layout没有在log4net中定义,则必须指定完全限定名。 |
支持以下子元素
元素 | 描述 |
param | 无或者多个。layout指定参数 |
下面的示例使用了log4net.Layout.PatternLayout类型的layout。
1: <layout type="log4net.Layout.PatternLayout">
2: <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
3: </layout>
Root Logger
只能有一个Root 记录器定义为<log4net>的子元素。根日志记录器是记录器层次结构的根。所有记录器最终继承这个记录器。
示例:
1: <root>
2: <level value="INFO" />
3: <appender-ref ref="ConsoleAppender" />
4: </root>
<root> 元素没有属性,但可以包含以下子元素
元素 | 描述 |
appender-ref | 无或者多个。允许logger通过名字引用appender。 |
level | 可选,最多只能一个。定义记录器的记录等级。记录器将只接受在大于等于这个等级的事件。 |
param | 无或者多个。logger指定参数 |
Loggers
logger元素只能定义<log4net>元素的子元素
示例:
1: <logger name="LoggerName">
2: <level value="DEBUG" />
3: <appender-ref ref="ConsoleAppender" />
4: </logger>
支持以下属性
属性 | 描述 |
name | 必要属性。定义logger名字 |
additivity | 可选属性,值为“true”或“False”,默认为”true”,如果为 “false”,则不继承父类logger中定义的Appender. |
支持以下子元素
元素 | 描述 |
appender-ref | 无或者多个。通过名字引用Appendes |
level | 可选元素,最多只能一个。定义记录器的记录等级。记录器将只接受大于等于该等级的事件。 |
param | 无或者多个,logger指定参数 |
Renderers
renderer定义为<log4net>的子元素
示例:
1: <renderer renderingClass="MyClass.MyRenderer" renderedClass="MyClass.MyFunkyObject" />
支持以下属性
属性 | 描述 |
renderingClass | 必要属性,值为renderer的类型名。如果该类型不是在log4net程序集中定义的,则必须指定完全限定名。 |
renderedClass | 必需属性。值必须是renderer的目标对象类型。如果该类型不是在log4net程序集中定义的,则必须指定完全限定名。 |
无子元素
Parameters
Parameter元素可以是很多元素的子元素。参照上面详细内容。
示例:
1: <param name="ConversionPattern" value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
支持以下属性
属性 | 描述 |
name | 必要属性,值必须是该参数的名称上设置的父对象 |
value | 可选。value或type属性其中之一必须指定。value属性是一个可转换为参数的值字符串。 |
type | 可选。value或type属性其中之一必须指定。如果type未在log4net程序集中定义,则必须指定完全限定名。 |
支持以下子元素
元素 | 描述 |
param | 无或者多个,指定参数 |
示例:
1: <param name="evaluator" type="log4net.spi.LevelEvaluator">
2: <param name="Threshold" value="WARN"/>
3: <param>