zoukankan      html  css  js  c++  java
  • 关于Log4Net的使用及配置方式

    志铭-2020年1月17日 23:18:37

    0.简介



    1.安装程序包

    • NuGet:Install-Package log4net -Version 2.0.8
    • 我发现网上一些关于Log4Net的配置的文章中的配置在我的项目中无法运行,所以以下关于Log4Net的使用是在基于 .net 4.6.1的 ASP .NET MVC项目中,开发工具VS2015。


    2.配置文件示例

    在项目(此处为Web项目)的配置文件Web.config中添加配置信息

    2.1注意事项:

    • "<configSections>"节点必须配置在<configuration>之后的第一个位置,

      否则报错,提示:“只允许一个 <configSections> 元素。它必须是根 <configuration> 元素第一个子元素”

    • 可以有多个" <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();

    2.2示例

      <!-- ................为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="&quot;Logs_&quot;yyyyMMdd&quot;.txt&quot;" /><!--日志文件名为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添加的配置.....结束................-->
    
    

    2.3配置细节说明

    • <level value="DEBUG" />

      写入日记的级别:DEBUG以上级别(包含该级别)

    • <param name="File" value="App_Data/Log/" />

      日志的保存位置:App_Data/Log/, 因为App_Data文件夹下的文件无法被用户下载,不希望访问者下载的文件放到这里(如果是控制台项目是生成到 binDebug 下)

    • <param name="AppendToFile" value="false" />

      日志文件为后续内容附加到已有文件(若是false,则为后续覆盖向前的内存)

    • <param name="RollingStyle" value="Composite" />

      6.日志文件变换方式(回滚方式):RollingStyle

    • <layout type="log4net.Layout.PatternLayout,log4net">

      5.2格式示例1

    • 日志写入文件时,不锁定文本文件,防止多线程时不能写Log,
      官方说线程非安全,所以示例中没有写此配置,若是需要可以添加:
      <param name="lockingModel" type="log4net.Appender.FileAppender+MinimalLock" />



    3.日记的级别:Level

    • 在Log4Net中日志的level: OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL

    • 一般正式项目中只记录InFo以上

    • Undone:怎么区分级别(什么时候用什么等级)



    4.日志的输出源:Appenders

    Appenders用来定义日志的输出方式,可以保存为文件,可以保存到数据库,可以发送邮件,可以写到远程接收端。

    Appender节点下可以配置Filters和Layout来实现日志的过滤和输出格式

    在配置文件中配置如下:

    <appender name="RollingFileTracer" type="log4net.Appender.RollingFileAppender,log4net">

    其中的type属性可以设置日志保存的方式,具体的type参数值可以查阅 :非常完善的Log4net详细说明

    常用的两种方式:

    • type="log4net.Appender.RollingFileAppender" 表示将日志以回滚文件的形式写到文件中。
    • type="log4net.Appender.AdoNetAppender"表示将日志记录到数据库中。


    5.日志格式:Layout

    在配置的Layout节点中可以设置日记记录的格式

    5.1设置格式的参数

    %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个字符则以空格填充。(因为日志的几个等级的单词长度不一样,通过设置字符长度,可以示日志更加整齐

    5.2格式示例1

    上面的配置文件中的格式:

    <!--日志记录的格式-->
    <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
    

    5.3格式示例2

    <!--日志记录的格式-->
    <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
    

    5.4格式示例3

    <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:ForGitASP.NET MVC08Log4NetControllersHomeController.cs:行号 29
       
    



    6.日志文件变换方式(回滚方式):RollingStyle

    6.1 三种日志回滚方式

    回滚方式即按照何种方式产生多个日志文件

    • <param name="RollingStyle" value="XXXX" />

      按照何种方式产生多个日志文件,其中value参数的可选值:Date(日期),Size(文件大小), Composite(混合)

    6.2 按照混合模式回滚

    • <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大小的日志文件。
      具体根据项目一定时间内可能产生的日志大小,可以进行文件大小和文件数量的合理分配。

    6.3 按照时间回滚

    <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添加的配置.....结束................-->
    

    6.4 按照文件大小回滚

    <param name="RollingStyle" value="Size" />

    <param name="MaxSizeRollBackups" value="10" />

    <param name="MaximumFileSize" value="1MB" />

    示例:Undone



    7.日志的过滤器:Filter

    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="&quot;Logs_&quot;yyyyMMdd&quot;.txt&quot;" />
          <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="&quot;Errors_&quot;yyyyMMdd&quot;.txt&quot;" />
          <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添加的配置.....结束................-->
    
    


    8.将日志记录在数据库中

    示例:将日记记录在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添加的配置.....结束...................-->
    

    按照以上方式配置,存放在数据库中的日志类似如下:

    数据库中日志



    9.记入日志的原则

    最后从网上找了一段写日志的原则:

    .在catch后,把异常写入日志.

    .在调用第三方控件的开始和结束处.

    .在连接数据库的开始结束处.

    .除非必要,不要在循环体中加入日志,否则一旦出问题可能导致日志暴增.

    .在自己认为很重要的逻辑处写入日志.



    10.参考



    11.完整的案例源码

    点击下载

  • 相关阅读:
    六大关系整理
    pthread_create多线程执行顺序诡异现象
    WinForm中 事件 委托 多线程的应用
    伪ajax上传文件
    Webx小应用的实现整理与分析
    IL反编译的实用工具
    MVC4+WebApi+Redis Session共享练习(上)
    虚拟化平台cloudstack新版本的调试
    【c++】指针参数是如何传递内存的
    NPinyin 中文转换拼音代码
  • 原文地址:https://www.cnblogs.com/shanzhiming/p/12207896.html
Copyright © 2011-2022 走看看