一、log4net简介:
1. Log4net的优点:
几乎所有的大型应用都会有自己的用于跟踪调试的API。因为一旦程序被部署以后,就不太可能再利用专门的调试工具了。然而一个管理员可能需要有一套强大的日志系统来诊断和修复配置上的问题。
经验表明,日志记录往往是软件开发周期中的重要组成部分。它具有以下几个优点:它可以提供应用程序运行时的精确环境,可供开发人员尽快找到应用程序中的Bug;一旦在程序中加入了Log 输出代码,程序运行过程中就能生成并输出日志信息而无需人工干预。另外,日志信息可以输出到不同的地方(控制台,文件等)以备以后研究之用。
Log4net就是为这样一个目的设计的,用于.NET开发环境的日志记录包。
2. Log4net的结构
log4net 有四种主要的组件,分别是Logger(记录器), Repository(库), Appender(附着器)以及 Layout(布局).
3.安装log4net并配置
打开VS 然后 Tools -> NuGet Package Manager -> Manager NuGet Packages for Solution...
右击项目新建一个config类型文件,取名为log4net (log4net 的配置信息单独的写在一个config文件里比较好管理,与其他代码分离清楚)
创建完毕后,右击log4net.config 文件选择属性 。Directory 下拉框选择最后一个Copy if newer 。
编写log4net.config 文件内容:
<configuration>
<configSections>
<!-- log4net的定义 -->
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net>
<logger name="logerror">
<level value="ERROR" />
<appender-ref ref="ErrorAppender" />
</logger>
<logger name="loginfo">
<level value="INFO" />
<appender-ref ref="InfoAppender" />
</logger>
<appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Log\\LogError\\" />
<param name="AppendToFile" value="true" />
<param name="MaxSizeRollBackups" value="100" />
<param name="MaxFileSize" value="10240" />
<param name="StaticLogFileName" value="false" />
<param name="DatePattern" value="yyyyMMdd'.txt'" />
<param name="RollingStyle" value="Date" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%n异常时间:%d %n异常级别:%-5p%n异常内容:%m%n" />
</layout>
<!--< > = <> %n = 回车-->
</appender>
<appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Log\\LogInfo\\" />
<param name="AppendToFile" value="true" />
<param name="MaxFileSize" value="10240" />
<param name="MaxSizeRollBackups" value="100" />
<param name="StaticLogFileName" value="false" />
<param name="DatePattern" value="yyyyMMdd'.txt'" />
<param name="RollingStyle" value="Date" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="日志时间:%d %n日志级别:%-5p %n日志内容:%m%n%n" />
</layout>
</appender>
</log4net>
</configuration>
编写 App.config 文件引用 log4net.config 代码:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net configSource="log4net.config" />
配置 AssemblyInfo.cs:
[assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
4. 测试
附注:
示例解析:
<param name="ConversionPattern" value="%n异常时间:%d %n异常级别:%-5p%n异常内容:%m%n" />
这段代码是另一种日志格式的配置,看起来像是针对 Log4j 或类似的日志框架。让我来解释一下其中的参数:
<param name="ConversionPattern" value="...">
: 这是用来设置日志格式的参数,ConversionPattern
是指定格式的名称。
%n
: 这个占位符表示换行符,每个 %n
将会在对应位置产生一个新的空行。
%d
: 这个占位符会被替换为日志事件的日期和时间。
%-5p
: 这个占位符会被替换为日志事件的级别,左对齐到5个字符的宽度。
%m
: 这个占位符会被替换为实际的日志消息。
因此,这个日志格式的配置会输出异常的日期、异常级别和异常内容,每个字段之间用空行隔开。
PatterLayout格式化字符表:
转换字符 | 效果 |
a | 等价于appdomain |
appdomain | 引发日志事件的应用程序域的友好名称。(使用中一般是可执行文件的名字。) |
c | 等价于 logger |
C | 等价于 type |
class | 等价于 type |
d | 等价于 date |
date | 发生日志事件的本地时间。 使用 DE>%utcdate 输出UTC时间。date后面还可以跟一个日期格式,用大括号括起来。DE>例如:%date{HH:mm:ss,fff}或者%date{dd MMM yyyy HH:mm:ss,fff}。如果date后面什么也不跟,将使用ISO8601 格式 。 日期格式和.Net中DateTime类的ToString方法中使用的格式是一样。 另外log4net还有3个自己的格式Formatter。 它们是 "ABSOLUTE", "DATE"和"ISO8601"分别代表 AbsoluteTimeDateFormatter, DateTimeDateFormatter和Iso8601DateFormatter。例如:%date{ISO8601}或%date{ABSOLUTE}。 它们的性能要好于ToString。 |
exception | 异常信息 日志事件中必须存了一个异常对象,如果日志事件不包含没有异常对象,将什么也不输出。异常输出完毕后会跟一个换行。一般会在输出异常前加一个换行,并将异常放在最后。 |
F | 等价于 file |
file | 发生日志请求的源代码文件的名字。 警告:只在调试的时候有效。调用本地信息会影响性能。 |
identity | 当前活动用户的名字(Principal.Identity.Name). 警告:会影响性能。(我测试的时候%identity返回都是空的。) |
l | 等价于 location |
L | 等价于 line |
location | 引发日志事件的方法(包括命名空间和类名),以及所在的源文件和行号。 警告:会影响性能。没有pdb文件的话,只有方法名,没有源文件名和行号。 |
level | 日志事件等级 |
line | 引发日志事件的行号 警告:会影响性能。 |
logger | 记录日志事件的Logger对象的名字。 可以使用精度说明符控制Logger的名字的输出层级,默认输出全名。 注意,精度符的控制是从右开始的。例如:logger 名为 "a.b.c", 输出模型为%logger{2} ,将输出"b.c"。 |
m | 等价于 message |
M | 等价于 method |
message | 由应用程序提供给日志事件的消息。 |
mdc | MDC (旧为:ThreadContext.Properties) 现在是事件属性的一部分。 保留它是为了兼容性,它等价于 property。 |
method | 发生日志请求的方法名(只有方法名而已)。 警告:会影响性能。 |
n | 等价于 newline |
newline | 换行符 |
ndc | NDC (nested diagnostic context) |
p | 等价于 level |
P | 等价于 property |
properties | 等价于 property |
property | 输出事件的特殊属性。例如: %property{user} 输出user属性。属性是由loggers或appenders添加到时间中的。 有一个默认的属性"DE>log4net:HostName"总是会有。DE> %property将输出所有的属性 。 (扩展后可以使用) |
r | 等价于 timestamp |
t | 等价于 thread |
timestamp | 从程序启动到事件发生所经过的毫秒数。 |
thread | 引发日志事件的线程,如果没有线程名就使用线程号。 |
type | 引发日志请求的类的全名。. 可以使用精度控制符。例如: 类名是 "log4net.Layout.PatternLayout", 格式模型是%type{1} 将输出"PatternLayout"。(也是从右开始的。) 警告:会影响性能。 |
u | 等价于 identity |
username | 当前用户的WindowsIdentity。(类似:HostName/Username) 警告:会影响性能。 |
utcdate | 发生日志事件的UTC时间。DE>后面还可以跟一个日期格式,用大括号括起来。DE>例如:%utcdate{HH:mm:ss,fff}或者%utcdate{dd MMM yyyy HH:mm:ss,fff}。如果utcdate后面什么也不跟,将使用ISO8601 格式 。 日期格式和.Net中DateTime类的ToString方法中使用的格式是一样。 另外log4net还有3个自己的格式Formatter。 它们是 "ABSOLUTE", "DATE"和"ISO8601"分别代表 AbsoluteTimeDateFormatter, DateTimeDateFormatter和Iso8601DateFormatter。例如:%date{ISO8601}或%date{ABSOLUTE}。 它们的性能要好于ToString。 |
w | 等价于 username |
x | 等价于 ndc |
X | 等价于 mdc |
% | %%输出一个百分号 |
关于调用本地信息(caller location information)的说明:
%type %file %line %method %location %class %C %F %L %l %M 都会调用本地信息。这样做会影响性能。本地信息使用System.Diagnostics.StackTrace得到。.Net 1.0 不支持System.Diagnostics.StackTrace 类。
本地信息在调试模式下可以正常获取,在非调试模式下可能获取不到,或只能获取一部分。(根据我的测试,其实是需要有一个程序数据库(.pdb)文件。)
%property属性要用代码来设置才能使用(也就是扩展一下),
默认属性log4net:HostName不用设置。
转义字符的修饰符:
Format modifier | left justify | minimum width | maximum width | comment |
%20logger | false | 20 | none | 如果logger名不足20个字符,就在左边补空格。 |
%-20logger | true | 20 | none | 如果logger名不足20个字符,就在右边补空格。 |
%.30logger | NA | none | 30 | 超过30个字符将截断。 |
%20.30logger | false | 20 | 30 | logger名要在20到30之间,少了在左边补空格,多了截断。 |
%-20.30logger | true | 20 | 30 | logger名要在20到30之间,少了在右边补空格,多了截断。 |