log4net配置自定義字段存入數據庫

 

前言

以bs項目中引入log4net爲例。log4net存入數據庫提供了基本的(時間、線程、等級、message)字段。 但是實際日誌場景中可能需要統計IP、用戶ID或者其他業務相關的信息記入日誌。 需要重寫log4net的部分方法來實現。本文展示使用log4net從0開始到記錄自定義字段入庫的過程。

關鍵代碼在第三步

一. 數據庫表

隨便創建一個測試的表,有test1和test2兩個字段,後續用log4net存入數據。

二. log4net基礎配置

1.nuget搜索log4net並安裝。

2.Global.asax全局配置

   在Global.asax中添加  log4net.Config.XmlConfigurator.Configure();這句。如圖。

三.創建自定義類

1.創建一個自己數據庫裏日誌表的實體,方便傳值、添加數據等。

我這裏命名爲BaseLog.cs, 字段爲test1和test2 ,和數據庫表對應

using System;
using System.ComponentModel;

namespace DataStatisticsApi.Log
{
    /// <summary>
    /// 日誌基礎類
    /// </summary>
    [Serializable]
    public class BaseLog
    {
        public BaseLog()
        {
        }

        ///<summary>
        ///唯一標識符
        ///</summary>
        [Description("測試1")]
        public string test1
        {
            get; set;
        }
        ///<summary>
        ///請求時間
        ///</summary>
        [Description("測試2")]
        public string test2
        {
            get; set;
        }
    }
}

2.增加數據庫連接字符串屬性

創建一個類,繼承log4net的AdoNetAppender類。


using log4net.Appender;
using System.Configuration;
namespace DataStatisticsApi.Log
{

    public class CustomAdoNetAppender : AdoNetAppender
    {
        /// <summary>
        /// Á¬½Ó×Ö·û´®Ãû³Æ
        /// </summary>
        public new string ConnectionStringName
        {
            set
            {
                this.ConnectionString = ConfigurationManager.ConnectionStrings[value].ConnectionString;
            }
        }

    }
}

3.增加一個自定義的日誌類

創建一個類,作爲一個自定義的日誌。我這裏叫DataLogAdoAppender, 同樣繼承自log4net的AdoNetAppender類。

在該類中寫自己插入表的語句和參數,並在最後調用log4net的ActivateOptions方法初始化加載log4net配置。


using System;

using log4net.Appender;
using System.Data;
using log4net.Layout;
namespace DataStatisticsApi.Log
{
    public class DataLogAdoAppender : CustomAdoNetAppender
    {
        public DataLogAdoAppender()
        {
            //System.Data.SqlClient
            Type t = typeof(System.Data.SqlClient.SqlConnection);
            string s = t.Assembly.FullName.ToString();
            //數據連接類型
            this.ConnectionType = $"System.Data.SqlClient.SqlConnection, {s}";

            base.UseTransactions = false;
            this.CommandType = CommandType.Text;
            //sql語句
            this.CommandText = @"INSERT INTO [dbo].[testLog]
                                       ([test1]
                                       ,[test2])
                                      
                                 VALUES
                                       (@test1
                                       ,@test2
                                       )";
            //填充參數
            string parameterName = "test1";
            this.AddParameter(new AdoNetAppenderParameter() { ParameterName = "@" + parameterName, DbType = DbType.String, Size = 50, Layout = new Layout2RawLayoutAdapter(new LogLayout("%" + parameterName)) });
            parameterName = "test2";
            this.AddParameter(new AdoNetAppenderParameter() { ParameterName = "@" + parameterName, DbType = DbType.String, Size = 200, Layout = new Layout2RawLayoutAdapter(new LogLayout("%" + parameterName)) });

            base.ActivateOptions();
        }
    }
}

4.增加一個自定義的轉換類

 創建一個自定義轉換類,把log4net對象轉換成自定義日誌類的字段屬性。繼承log4net的PatternLayout類,並重寫ActivateOptions方法。

using System.IO;

using log4net.Core;
using log4net.Layout;
using log4net.Layout.Pattern;

namespace DataStatisticsApi.Log
{
    public class LogLayout : PatternLayout
    {
        public LogLayout(string pattern)
            : base(pattern)
        {

        }
        public override void ActivateOptions()
        {
            this.AddConverter("test1", typeof(test1Converter));

            this.AddConverter("test2", typeof(test2Converter));

            base.ActivateOptions();
        }
    }

    #region 轉換
    internal sealed class test1Converter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            BaseLog log = (BaseLog)loggingEvent.MessageObject;
            if (log != null)
                writer.Write(log.test1);
        }
    }

    internal sealed class test2Converter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            BaseLog log = (BaseLog)loggingEvent.MessageObject;
            if (log != null)
                writer.Write(log.test2);
        }
    }

    #endregion


}

 

 

四.log4net存庫配置

在web.config中添加<log4net>節點

<log4net>
  <!-- 業務日誌-“數據庫”記錄器 -->
  <appender name="DataLogAdoAppender" type="DataStatisticsApi.Log.DataLogAdoAppender">
    <!-- 依賴的數據庫鏈接名稱 -->
    <connectionStringName value="ConnectionString"/>
    <!-- 緩存條數,到達value值時批量插入,1爲每次都插入。實際環境根據日誌量設置500或者更多-->
    <bufferSize value="1"/>
  </appender>
  <root>
    <level value="DEBUG" />
  </root>
  <!-- 自定義記錄日誌-->
  <logger name="DataLogAdoAppenderLogger">
    <!--信息級別僅限(FATAL)-->
    <level value="INFO" />
    <!--日誌配置,ref對應appender配置-->
    <appender-ref ref="DataLogAdoAppender" />
  </logger>
</log4net>

在web.config中添加<connectionStrings>節點(數據庫連接字符串)

<connectionStrings>
 <add name="ConnectionString" connectionString="Data Source=1.1.1.3,1355; User ID=xxx; Password=xxx; Initial Catalog=dbName" providerName="System.Data.SqlClient" />
 </connectionStrings>

五.Api測試

測試訪問,日誌數據成功入庫

 

詳細代碼見github(後續上傳)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章