1. 程式人生 > >基於Log4Net記錄日誌到SQLServer

基於Log4Net記錄日誌到SQLServer

本文記錄通過log4net將日誌資訊記錄到SQLServer資料庫中。

1、新建控制檯應用程式 Log4NetDemo;

2、通過NuGet安裝Log4Net (專案版本2.0.8);

3、專案根目錄下新增 log4net.config 配置檔案;

<?xml version="1.0"?>
<configuration>
  <!--宣告一個名為“log4net”的自定義配置節-->
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net
"/> </configSections> <!--log4net配置資訊--> <log4net> <logger name="WebLogger"> <level value="INFO"/><!--定義在這個級別之上的日誌才會被記錄--> <appender-ref ref="ADONetAppender" /><!--定義日誌物件使用的Appender物件--> </logger> <!--Appenders用來定義日誌的輸出方式 --> <!--name = “AdoNetAppender” sql資料庫--> <appender name="
ADONetAppender" type="log4net.Appender.ADONetAppender"> <!--緩衝區大小為10,快取10條記錄同時寫入資料庫,避免每次都去請求資料庫連線寫資料--> <bufferSize value="10"/> <!-- SQL資料來源 ,本地安裝SQL客戶端--> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
"/> <!-- SQL連線字串,修改為自己的--> <connectionString value="Data Source=ali.xsd.com;Initial Catalog=test;Integrated Security=false;User ID=admin;Password=123456;" /> <!-- 資料庫插入--> <commandText value="INSERT INTO AppOpLog ([ThreadId],[Level],[Message],[Exception],[LogTime],[UserPhone],[IP],[ControllerName],[ActionName],[ActionParam],[Url],[HttpHeader],[HttpMethod],[UserAgent],[StartTime],[EndTime],[RunTime]) VALUES ( @thread,@log_level, @message, @exception,@log_date, @UserPhone,@IP,@ControllerName,@ActionName,@ActionParam,@Url,@HttpHeader,@HttpMethod,@UserAgent,@StartTime,@EndTime,@RunTime)"/> <!--執行緒號--> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="100" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%t" /> </layout> </parameter> <!--日誌記錄時間,RawTimeStampLayout 為預設的時間輸出格式--> <parameter> <parameterName value="@log_date"/> <dbType value="DateTime"/> <layout type="log4net.Layout.RawTimeStampLayout"/> </parameter> <!--日誌等級--> <parameter> <parameterName value="@log_level"/> <dbType value="String"/> <size value="50"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level"/> </layout> </parameter> <!--異常 ExceptionLayout 預設的異常輸出格式--> <parameter> <parameterName value="@exception"/> <dbType value="String"/> <size value="2000"/> <layout type="log4net.Layout.ExceptionLayout"/> </parameter> <parameter> <parameterName value="@message"/> <dbType value="String"/> <size value="4000"/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message"/> </layout> </parameter> <!--自定義成員--> <parameter> <parameterName value="@UserPhone" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%UserPhone" /> </layout> </parameter> <parameter> <parameterName value="@IP" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%IP" /> </layout> </parameter> <parameter> <parameterName value="@StartTime" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%StartTime" /> </layout> </parameter> <parameter> <parameterName value="@EndTime" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%EndTime" /> </layout> </parameter> <parameter> <parameterName value="@RunTime" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%RunTime" /> </layout> </parameter> <parameter> <parameterName value="@ControllerName" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%ControllerName" /> </layout> </parameter> <parameter> <parameterName value="@ActionName" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%ActionName" /> </layout> </parameter> <parameter> <parameterName value="@ActionParam" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%ActionParam" /> </layout> </parameter> <parameter> <parameterName value="@Url" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%Url" /> </layout> </parameter> <parameter> <parameterName value="@HttpMethod" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%HttpMethod" /> </layout> </parameter> <parameter> <parameterName value="@HttpHeader" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%HttpHeader" /> </layout> </parameter> <parameter> <parameterName value="@UserAgent" /> <dbType value="String" /> <layout type="Log4NetDemo.CustomLayout"> <conversionPattern value="%UserAgent" /> </layout> </parameter> </appender> </log4net> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration>
View Code

4、日誌記錄中新增自定義欄位

public class CustomLayout : log4net.Layout.PatternLayout
    {
        public CustomLayout()
        {
            this.AddConverter("UserPhone", typeof(UserPhonePatternConverter));
            this.AddConverter("IP", typeof(IPPatternConverter));
            this.AddConverter("ControllerName", typeof(ControllerNamePatternConverter));
            this.AddConverter("ActionName", typeof(ActionNamePatternConverter));
            this.AddConverter("ActionParam", typeof(ActionParamPatternConverter));
            this.AddConverter("Url", typeof(UrlPatternConverter));
            this.AddConverter("HttpHeader", typeof(HttpHeaderPatternConverter));
            this.AddConverter("HttpMethod", typeof(HttpMethodPatternConverter));
            this.AddConverter("UserAgent", typeof(UserAgentPatternConverter));
            this.AddConverter("StartTime", typeof(StartTimePatternConverter));
            this.AddConverter("EndTime", typeof(EndTimePatternConverter));
            this.AddConverter("RunTime", typeof(RunTimePatternConverter));
        }
    }

    internal sealed class UserPhonePatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.UserPhone);
        }
    }

    internal sealed class IPPatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.IP);
        }
    }

    internal sealed class ControllerNamePatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.ControllerName);
        }
    }

    internal sealed class ActionNamePatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.ActionName);
        }
    }

    internal sealed class ActionParamPatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.ActionParam);
        }
    }

    internal sealed class UrlPatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.Url);
        }
    }

    internal sealed class HttpHeaderPatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.HttpHeader);
        }
    }

    internal sealed class HttpMethodPatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.HttpMethod);
        }
    }

    internal sealed class UserAgentPatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.UserAgent);
        }
    }

    internal sealed class StartTimePatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.StartTime);
        }
    }

    internal sealed class EndTimePatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.EndTime);
        }
    }

    internal sealed class RunTimePatternConverter : PatternLayoutConverter
    {
        override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
        {
            AppOpLog logMessage = loggingEvent.MessageObject as AppOpLog;

            if (logMessage != null)
                writer.Write(logMessage.RunTime);
        }
    }
View Code 5、程式啟動時讀取配置檔案,控制檯程式在Main方法中新增
//註冊 log4net,注意這裡的路徑為絕對路徑
log4net.Config.XmlConfigurator.Configure(
        new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + "\\log4net.config")
);
View Code 6、記錄日誌,定義LogHelper.cs
    public class LogHelper
    {
        public static string LoggerName = "DbLogger";

        private static ILog log = LogManager.GetLogger(LoggerName);

        /// <summary>
        /// 記錄一般日誌
        /// </summary>
        public static void LogInfo(AppOpLog opLog)
        {
            if (log.IsInfoEnabled)
            {
                log.Info(opLog);
            }
        }

        /// <summary>
        /// 記錄錯誤
        /// </summary>
        public static void LogError(AppOpLog opLog, Exception ex)
        {
            if (log.IsErrorEnabled)
            {
                log.Error(opLog, ex);
            }
        }

        /// <summary>
        /// 記錄嚴重錯誤
        /// </summary>
        public static void LogFatal(AppOpLog opLog, Exception ex)
        {
            if (log.IsFatalEnabled)
            {
                log.Fatal(opLog, ex);
            }
        }

        /// <summary>
        /// 記錄警告
        /// </summary>
        public static void LogWarn(AppOpLog opLog)
        {
            if (log.IsWarnEnabled)
            {
                log.Warn(opLog);
            }
        }
    }
View Code

7、在程式中呼叫

        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure(
               new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + "\\log4net.config")
           );

            AppOpLog opLog = new AppOpLog();
            opLog.IP = "192.124.0.0";
            opLog.ActionName = "action";
            opLog.ControllerName = "controller";
            opLog.ActionParam = "param";
            opLog.Url = "url";
            opLog.HttpHeader = "header";
            opLog.HttpMethod = "get";
            opLog.UserAgent = "useragent";
            opLog.StartTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            opLog.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            opLog.RunTime = (Convert.ToDateTime(opLog.EndTime) - Convert.ToDateTime(opLog.StartTime)).TotalSeconds.ToString();

            LogHelper.LogError(opLog,new Exception("error"));//呼叫

            Console.ReadKey();
        }    
View Code

 8、結果

注意:控制檯程式除錯的時候需要將 log4net.config屬性設為始終複製;

附sql指令碼

CREATE TABLE [dbo].[AppOpLog](
       [IntId] [int] IDENTITY(1,1) NOT NULL,
       [UserCharId] [varchar](50) NULL,
       [UserPhone] [varchar](20) NULL,
       [LogTime] [datetime] NOT NULL,
       [IP] [varchar](20) NOT NULL,
       [ControllerName] [varchar](20) NOT NULL,
       [ActionName] [varchar](20) NOT NULL,
       [ActionParam] [varchar](max) NOT NULL,
       [Url] [varchar](max) NOT NULL,
       [HttpHeader] [varchar](max) NULL,
       [HttpMethod] [varchar](5) NULL,
       [UserAgent] [varchar](100) NULL,
       [StartTime] [datetime] NOT NULL,
       [EndTime] [datetime] NOT NULL,
       [RunTime] [varchar](50) NOT NULL,
       [Level] [varchar](10) NOT NULL,
       [ThreadId] [int] NOT NULL,
       [Message] [varchar](max) NULL,
       [CreateTime] [datetime] NULL
)
View Code

AppOpLog.cs

    public class AppOpLog
    {
        public string IP { get; set; }
        public string ControllerName { get; set; }
        public string ActionName { get; set; }
        public string ActionParam { get; set; }
        public string Url { get; set; }
        public string HttpHeader { get; set; }
        public string HttpMethod { get; set; }
        public string UserAgent { get; set; }
        public string StartTime { get; set; }
        public string EndTime { get; set; }
        public string RunTime { get; set; }
    }
View Code

log4net除錯:當log4net日誌插入失敗時,在Web.Config配置檔案裡新增可以檢視錯誤情況,這裡注意對應的目錄下要有寫檔案的許可權

<appSettings>
    <add key="log4net.Internal.Debug" value="true"/>
  </appSettings>
  <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add
            name="textWriterTraceListener"
            type="System.Diagnostics.TextWriterTraceListener"
            initializeData="C:\log4net.txt" />
      </listeners>
    </trace>
  </system.diagnostics>
View Code

測試Demo地址:https://github.com/zhrong92/Log4NetDemo