關於Log4Net的使用及配置方式

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

0.簡介

  • Log4Net庫是Apache log4j框架在 .NET平臺下的實現,其開源免費。它能夠將日誌分不一樣的等級,以不一樣的格式,輸出到不一樣的媒介。
  • 官網地址:http://logging.apache.org/log4net/index.html
  • Log4Net開源地址:https://github.com/apache/logging-log4net/




1.安裝程序包

  • NuGet:Install-Package log4net -Version 2.0.8
  • 我發現網上一些關於Log4Net的配置的文章中的配置在個人項目中沒法運行,因此如下關於Log4Net的使用是在基於 .net 4.6.1的 ASP .NET MVC項目中,開發工具VS2015。




2.配置文件示例

在項目(此處爲Web項目)的配置文件Web.config中添加配置信息git

2.1注意事項:
  • "<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

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

    日誌的保存位置:App_Data/Log/, 由於App_Data文件夾下的文件沒法被用戶下載,不但願訪問者下載的文件放到這裏(若是是控制檯項目是生成到 bin\Debug 下)框架

  • <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:\ForGit\ASP.NET MVC\008Log4Net\Controllers\HomeController.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.完整的案例源碼

下載地址

相關文章
相關標籤/搜索