目录html
Install-Package log4net -Version 2.0.8
在项目(此处为Web项目)的配置文件Web.config中添加配置信息git
"<configSections>"节点必须配置在<configuration>以后的第一个位置,github
不然报错,提示:“只容许一个 <configSections> 元素。它必须是根 <configuration> 元素第一个子元素”sql
能够有多个" <appender name="XXXX"> </appender>",只要在"<root></root>"中添加相应的“<appender-ref ref="XXXX">”
便可以设置多个日志输出的形式,下面咱们是把日志以txt文件的形式保存在App_Data/Log文件夹中的数据库
在ASP .NET MVC项目中使用Log4Net,首先要在Global.asax.cs中初始化Log4Net,即添加log4net.Config.XmlConfigurator.Configure();
apache
<!-- ................为Log4Net添加的配置.....开始................--> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" /> </configSections> <log4net> <root> <level value="DEBUG" /><!--定义此记录器的日志记录级别。此记录器仅接受此级别(此处即DEBUG级别)或更高级别的事件--> <appender-ref ref="RollingFileTracer" /> </root> <appender name="RollingFileTracer" type="log4net.Appender.RollingFileAppender,log4net"> <param name="File" value="App_Data/Log/" /><!--日志文件的保存位置为:App_Data/Log/Log.txt--> <param name="AppendToFile" value="false" /><!--日志文件为后续内容附加到已有文件(如果false,则为后续覆盖向前的内存)--> <param name="RollingStyle" value="Composite" /><!--根据文件的大小和日期滚动文件--> <param name="MaxSizeRollBackups" value="10" /><!--备份文件的个数--> <param name="MaximumFileSize" value="1MB" /><!--若是咱们将最大文件大小设置为1MB并将maxSizeRollBackups设置为10 MB,那么根据日期或文件大小,它将只保留最后10MB的文件--> <param name="DatePattern" value=""Logs_"yyyyMMdd".txt"" /><!--日志文件名为Logs_20200114.txt的相似格式--> <param name="StaticLogFileName" value="false" /><!--日志文件名,是否固定不变--> <layout type="log4net.Layout.PatternLayout,log4net"> <!--日志记录的格式--> <!--<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />格式为:时间+[线程]+级别+项目.Controller -messsage+exception.innerMessage--> <param name="ConversionPattern" value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" /> <!--格式相似:记录时间:2020-01-15 20:34:37,946 线程ID:[6] 日志级别:DEBUG 出错类:_008Log4Net.Controllers.HomeController property:[(null)] - 错误描述:Hi I am log4net Debug Level--> </layout> </appender> </log4net> <!-- ................为Log4Net添加的配置.....结束................-->
<level value="DEBUG" />
安全
写入日记的级别:DEBUG以上级别(包含该级别)多线程
<param name="File" value="App_Data/Log/" />
app
日志的保存位置:App_Data/Log/
, 由于App_Data文件夹下的文件没法被用户下载,不但愿访问者下载的文件放到这里(若是是控制台项目是生成到 bin\Debug 下)框架
<param name="AppendToFile" value="false" />
日志文件为后续内容附加到已有文件(如果false,则为后续覆盖向前的内存)
<param name="RollingStyle" value="Composite" />
<layout type="log4net.Layout.PatternLayout,log4net">
日志写入文件时,不锁定文本文件,防止多线程时不能写Log,
官方说线程非安全,因此示例中没有写此配置,如果须要能够添加:
<param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
在Log4Net中日志的level: OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL
通常正式项目中只记录InFo以上
Undone:怎么区分级别(何时用什么等级)
Appenders用来定义日志的输出方式,能够保存为文件,能够保存到数据库,能够发送邮件,能够写到远程接收端。
Appender节点下能够配置Filters和Layout来实现日志的过滤和输出格式
在配置文件中配置以下:
<appender name="RollingFileTracer" type="log4net.Appender.RollingFileAppender,log4net">
其中的type属性能够设置日志保存的方式,具体的type参数值能够查阅 :很是完善的Log4net详细说明
经常使用的两种方式:
在配置的Layout节点中能够设置日记记录的格式
%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
%n(new line):换行
%d(datetime):输出当前语句运行的时刻
%r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
%t(thread id):当前语句所在的线程ID
%p(priority):等同于:%level 日志的当前优先级别,即DEBUG、INFO、WARN…等
%c(class):当前日志对象的名称
%f(file):输出语句所在的文件名。
%l(line):输出语句所在的行号。
%数字:表示该项的最小长度,若是不够,则用空格填充,如“%-5level”表示level的最小宽度是5个字符,若是实际长度不够5个字符则以空格填充。(由于日志的几个等级的单词长度不同,经过设置字符长度,能够示日志更加整齐)
上面的配置文件中的格式:
<!--日志记录的格式--> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern" value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" /> <!--格式相似:--> </layout>
按照上述布局,每一条日志的格式相似:
记录时间:2020-01-15 20:34:37,946 线程ID:[6] 日志级别:DEBUG 出错类:_008Log4Net.Controllers.HomeController property:[(null)] - 错误描述:Hi I am log4net Debug Level
<!--日志记录的格式--> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /> </layout>
按照上述布局,每一条日志的格式相似:
2020-01-15 21:09:17,362 [6] DEBUG _008Log4Net.Controllers.HomeController - Hi I am log4net Debug Level
<layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n出错类:%logger property: [%property{NDC}] - %n错误描述:%message%newline %n"/> </layout>
按照上述布局,每一条日志的格式相似:
记录时间:2020-01-15 22:51:44,106 线程ID:[7] 日志级别: ERROR 出错类:_008Log4Net.Controllers.HomeController property: [(null)] - 错误描述:Hi I am log4net Error Level System.NullReferenceException: 未将对象引用设置到对象的实例。 在 _008Log4Net.Controllers.HomeController.Index() 位置 F:\ForGit\ASP.NET MVC\008Log4Net\Controllers\HomeController.cs:行号 29
回滚方式即按照何种方式产生多个日志文件
<param name="RollingStyle" value="XXXX" />
按照何种方式产生多个日志文件,其中value参数的可选值:Date
(日期),Size
(文件大小), Composite
(混合)
<param name="RollingStyle" value="Composite" />
按照混合模式产生多个日志文件(即既考虑时间,也文件考虑大小)
上述示例中的选择使用混合模式生成日志文件,即必定时间内达到必定大小则生成新的一个日志文件
如下两个节点设置日志文件的大小和数量
<param name="MaxSizeRollBackups" value="10" />
最大变换数量,若是超过这个数量则从第一个文件开始复写(即最多保持10个日志文件)
<param name="MaximumFileSize" value="1MB" />
最大文件大小为1MB,支持KB,MB,GB
注意根据以上两个参数:咱们将最大文件大小设置为1MB并将文件变换数量设置为10,那么根据日期或文件大小,它将只保留最后(1*10)MB大小的日志文件。
具体根据项目必定时间内可能产生的日志大小,能够进行文件大小和文件数量的合理分配。
<rollingStyle value="Date"/>
(注意这种写法和<param name="RollingStyle" value="Date" />
等价)
示例:实现日志每一天一个文件夹,每一分钟一个文件
<!-- ................为Log4Net添加的配置.....开始................--> <!----> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" /> </configSections> <log4net> <root> <level value="ALL"/> <appender-ref ref="RollingLogFileAppender"/> </root> <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender,log4net"> <file value="App_Data/Log/"/> <appendToFile value="true"/> <rollingStyle value="Date"/><!--按照时间回滚 --> <!--<datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'"/>--><!--日志文件夹格式:2020/202001/20200117.txt--> <datePattern value="yyyyMMdd\\yyyyMMddhhmm'.txt'"/><!--日志文件夹格式:20200117/202001170307.txt--> <staticLogFileName value="false"/> <!--待研究:日志究竟是保留多少,怎么自动删除就日志--> <MaxSizeRollBackups value="3"/> <!--定义文件最大个数,超过按顺序删除--> <maximumFileSize value="6KB" /> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="ERROR" /> <levelMax value="FATAL" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n出错类:%logger property: [%property{NDC}] - %n错误描述:%message%newline %n"/> </layout> </appender> </log4net> <!-- ................为Log4Net添加的配置.....结束................-->
<param name="RollingStyle" value="Size" />
<param name="MaxSizeRollBackups" value="10" />
<param name="MaximumFileSize" value="1MB" />
示例:Undone
filter能够过滤不一样等级的日志
按照:OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL的顺序能够设置一个范围
实例:将不一样级别的日记记录在不一样的日志文件中
<!-- ................为Log4Net添加的配置.....开始................--> <!--实现日志分等级记录在不一样的日志文件中--> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" /> </configSections> <log4net> <root> <level value="ALL"/> <!--在root节点中设置为记录日记的全部等级--> <appender-ref ref="RollingFile"/> <appender-ref ref="RollingFileTracer"/> </root> <appender name="RollingFile" type="log4net.Appender.RollingFileAppender,log4net"> <param name="File" value="App_Data/Log/" /> <param name="AppendToFile" value="true" /> <param name="RollingStyle" value="Composite" /> <param name="MaxSizeRollBackups" value="10" /> <param name="MaximumFileSize" value="1MB" /> <param name="DatePattern" value=""Logs_"yyyyMMdd".txt"" /> <param name="StaticLogFileName" value="false" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="[%-5p %t] [%date{yyyy-MM-dd HH:mm:ss,fff}] %-5logger - %m%n"/> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <!--使用过滤器,过滤出WARN > INFO > DEBUG 等级并记录Logs_20200117.txt--> <levelMin value="DEBUG" /> <levelMax value="WARN" /> </filter> </appender> <appender name="RollingFileTracer" type="log4net.Appender.RollingFileAppender,log4net"> <param name="File" value="App_Data/Log/" /> <param name="AppendToFile" value="true" /> <param name="RollingStyle" value="Composite" /> <param name="MaxSizeRollBackups" value="10" /> <param name="MaximumFileSize" value="1MB" /> <param name="DatePattern" value=""Errors_"yyyyMMdd".txt"" /> <param name="StaticLogFileName" value="false" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="[%p] %m%n"/> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <!--使用过滤器,过滤出FATAL > ERROR等级并记录在Errors_20200117.txt(在程序中将抛异的日志记录为ERROR和FATAL等级)--> <levelMin value="ERROR" /> <levelMax value="FATAL" /> </filter> </appender> </log4net> <!--................为Log4Net添加的配置.....结束................-->
示例:将日记记录在MS SQL Server数据库中
在MS SQLServer中新建一个库,添加一个db_Log表,存放日记信息
建表SQL:
CREATE TABLE [dbo].[Log]( [Id] [int] IDENTITY(1,1) NOT NULL, [Date] [datetime] NOT NULL, [Thread] [varchar](255) NOT NULL, [Level] [varchar](50) NOT NULL, [Logger] [varchar](255) NOT NULL, [Message] [varchar](4000) NOT NULL, [Exception] [varchar](2000) NULL ) ON [PRIMARY]
配置信息:
<!-- ...................为Log4Net添加的配置.....开始...................--> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" /> </configSections> <!-- 数据库链接字符串 --> <connectionStrings> <add name="ConnectionStringLogging" connectionString="server=.;database=db_Tome1;uid=sa;pwd=shanzm" providerName="System.Data.SqlClient" /> </connectionStrings> <log4net> <root> <level value="ALL"></level> <appender-ref ref="AdoNetAppender"></appender-ref> </root> <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" /> <connectionStringName value="ConnectionStringLogging" /> <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> <!-- ...................为Log4Net添加的配置.....结束...................-->
按照以上方式配置,存放在数据库中的日志相似以下:
最后从网上找了一段写日志的原则,感受仍是很好的:
【写日志的原则】
.在catch后,把异常写入日志.
.在调用第三方控件的开始和结束处.
.在链接数据库的开始结束处.
.除非必要,不要在循环体中加入日志,不然一旦出问题可能致使日志暴增.
.在本身认为很重要的逻辑处写入日志.