Log4Net学习【三】
Log4Net配置详解
配置方式一
在相应的应用程序的配置文件中配置,(WinForm对应的是*.exe.config,WebForm对应的是*.config),本实例是Web应用程序,以Web.config为例子讲解。
第一步
添加并应用Log4net.dll。然后在Web.config文件中添加下面的配置
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net-net-1.0"/>
</configSections>
第二步
在Web.config的Configuration节点下新增log4net节点,如下:
<log4net debug="true"> <!--RootLog实例,子Log会继承其特性--> <root> <level value="INFO" /> <!--启用按日期分割--> <appender-ref ref="LogFileAppenderByDate" /> <!--启用按容量分割--> <appender-ref ref="LogFileAppenderBySize" /> <!--启用保存到数据库--> <appender-ref ref="AdoNetAppender" /> </root> <logger name="testApp.Logging"> <!--设置testApp.Logging日志级别为DEBUG--> <level value="DEBUG"/> </logger> <!--按日期分割日志文件 一天一个--> <appender name="LogFileAppenderByDate" type="log4net.Appender.RollingFileAppender" > <!--是否续写--> <param name="AppendToFile" value="true" /> <!--最小锁定模型以允许多个进程可以写入同一个文件--> <param name="LockingModel" value="log4net.Appender.FileAppender.MinimalLock" /> <param name="StaticLogFileName" value="true" /> <!--保存路径--> <param name="File" value="d:\Log\\" /> <!--可以按天、小时、分钟为Log命名--> <param name="DatePattern" value="yyyy-MM-dd-HH-mm.LOG" /> <param name="StaticLogFileName" value="false" /> <param name="RollingStyle" value="Date" /> <!--最多保留的几天的日志、这里我没有验证--> <param name="MaxBackupIndex" value="3" /> <!--日志输出格式--> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="时间:%d %n级别:%level %n类名:%c%n文件:%F 第%L行%n日志内容:%m%n-----------------------------------------%n%n" /> </layout> </appender> <!--按日志容量分割日志文件 10KB一个--> <appender name="LogFileAppenderBySize" type="log4net.Appender.RollingFileAppender" > <!--是否续写--> <param name="AppendToFile" value="true" /> <!--最小锁定模型以允许多个进程可以写入同一个文件--> <param name="LockingModel" value="log4net.Appender.FileAppender.MinimalLock" /> <param name="StaticLogFileName" value="true" /> <!--按照文件的大小进行变换日志文件--> <param name="RollingStyle" value="Size" /> <param name="File" value="log.txt" /> <!--单个文件最大数量 好像只有在 按Size分割时有效--> <param name="MaximumFileSize" value="200KB"/> <!--保留的log文件数量 超过此数量后 自动删除之前的 好像只有在 按Size分割时有效--> <param name="MaxSizeRollBackups" value="2" /> <param name="StaticLogFileName" value="false" /> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="发生时间:%d %n事件级别:%level %n相关类名:%c%n程序文件:%F 第%L行%n日志内容:%m%n-----------------------------------------%n%n" /> </layout> </appender> <!--记录日志到数据库--> <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"> <bufferSize value="1" /> <!--缓冲大小--> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <connectionString value="Data Source=DST56711\SEVEN;Initial Catalog=Log4Net;Persist Security Info=True;User ID=sa;Password=seven_123456" /> <commandText value="INSERT INTO Log([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> </log4net>
第三步
在Web项目下找到AssemblyInfo.cs文件【Properties->AssemblyInfo.cs】加入如下代码:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
第四步
在相应的位置写入记录日志的代码:
ILog log= LogManager.GetLogger("testApp.Logging");
log.Debug("DebugMvc");
第五步
查看相应的日志记录效果:
我们上面的root节点中配置了三个Append,分别是按日期分割写日志到文件中【在D:\Log文件夹中】、按容量分割写入的项目的更目录的log.text文件中、保存到数据库。
1、打开我的D盘Log文件夹(没有会自动生成,生成格式按照 <param name="DatePattern" value="yyyy-MM-dd-HH-mm.LOG" />格式生成)
2、在项目的根目录生成log.txt(已经生成,就不截图了,这两个日志文件的内容格式是一样的,如下:)
3、数据库中也正常的插入了我们想要的数据
结论
看到上面的结果,不知道你是否有一些疑问,比如:
1、如果把配置写在web.config中会让web.config比较乱,是否可以单独建立一个文件来配置log4net
2、我们上面提到了 在Web项目下找到AssemblyInfo.cs文件【Properties->AssemblyInfo.cs】加入如下代码:[assembly: log4net.Config.XmlConfigurator(Watch = true)],这个是干嘛用的?
3、如果我们配置不正确,改如何调试log4net呢?(我在学习的时候是配到了,不论怎么样也写不到数据库,也没有日志信息,很是头疼(这里也可以体现冲日志的重要性了))
如果你读过我的前两篇文章,你应该很容易看懂上面的配置,也自然知道Log4Net不依赖任何配置【我们不做任何配置,直接引入log4net.dll就可以】,使用配置是为了方便和更好的统一管理,所以完全可以不放在web.config中,新建一个Log4Net.config来配置。
对于AssemblyInfo.cs的作用纯粹是用来初始化的,没有任何神奇的地方,用AssemblyInfo.cs来初始化是.Net4.0新加的功能,我们完全可以放在Global.asax.cs文件中来实现。对于初始化功能,Fish Li 的 如何在Asp.Net应用程序中初始化 讲的比较清楚。
对于调试log4Net,我在下文会有介绍,现在我们带着前两个问题的答案去用另外的一种方式配置log4net,看看效果如何:
配置方式二
第一步
在web项目根目录下新建一个文件夹Config【用来存放自定义的配置文件】,然后再Config文件夹中建立一个文件叫LogNet.config
第二步
配置Log4Net.config文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <log4net debug="true"> <!--RootLog实例,子Log会继承其特性--> <root> <level value="INFO" /> <!--启用按日期分割--> <appender-ref ref="LogFileAppenderByDate" /> <!--启用按容量分割--> <appender-ref ref="LogFileAppenderBySize" /> <!--启用保存到数据库--> <appender-ref ref="AdoNetAppender" /> </root> <logger name="testApp.Logging"> <!--设置testApp.Logging日志级别为DEBUG--> <level value="DEBUG"/> </logger> <!--按日期分割日志文件 一天一个--> <appender name="LogFileAppenderByDate" type="log4net.Appender.RollingFileAppender" > <!--是否续写--> <param name="AppendToFile" value="true" /> <!--最小锁定模型以允许多个进程可以写入同一个文件--> <param name="LockingModel" value="log4net.Appender.FileAppender.MinimalLock" /> <param name="StaticLogFileName" value="true" /> <!--保存路径--> <param name="File" value="d:\Log\\" /> <!--可以按天、小时、分钟为Log命名--> <param name="DatePattern" value="yyyy-MM-dd-HH-mm.LOG" /> <param name="StaticLogFileName" value="false" /> <param name="RollingStyle" value="Date" /> <!--最多保留的几天的日志、这里我没有验证--> <param name="MaxBackupIndex" value="3" /> <!--日志输出格式--> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="时间:%d %n级别:%level %n类名:%c%n文件:%F 第%L行%n日志内容:%m%n-----------------------------------------%n%n" /> </layout> </appender> <!--按日志容量分割日志文件 10KB一个--> <appender name="LogFileAppenderBySize" type="log4net.Appender.RollingFileAppender" > <!--是否续写--> <param name="AppendToFile" value="true" /> <!--最小锁定模型以允许多个进程可以写入同一个文件--> <param name="LockingModel" value="log4net.Appender.FileAppender.MinimalLock" /> <param name="StaticLogFileName" value="true" /> <!--按照文件的大小进行变换日志文件--> <param name="RollingStyle" value="Size" /> <param name="File" value="log.txt" /> <!--单个文件最大数量 好像只有在 按Size分割时有效--> <param name="MaximumFileSize" value="200KB"/> <!--保留的log文件数量 超过此数量后 自动删除之前的 好像只有在 按Size分割时有效--> <param name="MaxSizeRollBackups" value="2" /> <param name="StaticLogFileName" value="false" /> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="发生时间:%d %n事件级别:%level %n相关类名:%c%n程序文件:%F 第%L行%n日志内容:%m%n-----------------------------------------%n%n" /> </layout> </appender> <!--记录日志到数据库--> <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"> <bufferSize value="1" /> <!--缓冲大小--> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <connectionString value="Data Source=DST56711\SEVEN;Initial Catalog=Log4Net;Persist Security Info=True;User ID=sa;Password=seven_123456" /> <commandText value="INSERT INTO Log([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> </log4net>
第三步
在Global.asax中加入如下代码
protected void Application_Start()
{
//..........其它初始化代码
//Log4Net初始化代码
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Server.MapPath("Config/Log4Net.config")));
}
第四步
在相应的位置写入记录日志的代码:
ILog log= LogManager.GetLogger("testApp.Logging");
log.Debug("DebugMvc");
第五步
观察结果,结果和上面配置一种的结果一样,这里就不截图展示了。
结论
写到这里我想大家大概已经明白了,这次我们没有在web.config中做任何配置,也没有在AssemblyInfo.cs文件中做任何改动,一样可以按照我们需要的方式记录日志。
这就证明了配置其实就是为了方便和高效的管理日志,不是log4net必须的(不过一般我们项目使用中都需要用配置来管理)而AssemblyInfo只是为了让项目启动是加载log4net的配置,在任何可以初始化的地方都可以做,现在我们在Global中实现。
关于log4net出现问题如何调试,我们在下篇文章中讲解,如果对上面的有疑惑,请参考下面两篇文章。