五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現在的位置: 365建站網 > 365文章 > .Net日志庫Nlog的配置與調試記錄日志的方法

.Net日志庫Nlog的配置與調試記錄日志的方法

文章來源:365jz.com     點擊數:714    更新時間:2018-06-24 12:29   參與評論

NLog是一個簡單靈活的.NET日志記錄類庫,NLog的API非常類似于log4net,且配置方式非常簡單。通過使用NLog,我們可以在任何一種.NET語言中輸出帶有上下文的調試信息,根據項目需求配置署出格式和輸出目標的規(guī)則。

NLog使用路由進行配置,但log4net卻使用層次性的appender配置,這樣就讓NLog的配置文件非常容易閱讀,并便于今后維護。

支持多種形式輸出日志:文本文件 系統(tǒng)日志 數據庫 控制臺 郵箱 等

下載

通過Nuget安裝NLog,你也可以同時安裝NLog.Config,它會在項目目錄下幫你建立一個配置文件NLog.config,不過不需要,我們直接手動建立一個,你也可以將配置的信息寫入到 App.config/Web.config,我比較喜歡獨立出來,不與其它配置摻和在一起。

 

配置

在項目根目錄下新建一個NLog.config,基本目錄結構:targets下面配置日志輸出目標及相關參數,rules下面配置目標輸出規(guī)則。

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" ?>
<nlog>
    <targets>
        <target></target>
        <target></target>
    </targets>
    <rules>
        <logger></logger>
        <logger></logger>
    </rules>
</nlog>

記得在NLog.config的屬性中設置 Copy to Output Directory: Copy always

 

現在我們要將日志輸出到文本文件,數據庫,VS調試窗口,完整配置文件如下:

<?xml version="1.0" ?><!--<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Trace"
      internalLogFile="D:\work\log.txt">--><nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true">
  
  <targets>
    
    <!-- Log in a separate thread, possibly queueing up to
        5000 messages. When the queue overflows, discard any
        extra messages-->

    <!-- write logs to file -->
    <target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
      <target xsi:type="File" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} ${level:uppercase=true} ${event-context:item=Action} ${message} ${event-context:item=Amount} ${stacktrace}" />      
    </target>

    <!-- write log message to database -->
    <target name="db" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
      <target type="Database" dbProvider="mssql" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=EFinance;Persist Security Info=True;User ID=sa;Password=123456;">

        <commandText>
          INSERT INTO Log(Timestamp,Level,Message,Action,Amount,StackTrace) VALUES(@time_stamp, @level, @message, @action, @amount, @stacktrace);        </commandText>

        <!-- database connection parameters -->
        <parameter name="@time_stamp" layout="${date}" />
        <parameter name="@level" layout="${level:uppercase=true}" />
        <parameter name="@message" layout="${message}" />
        <parameter name="@action" layout="${event-context:item=Action}" />
        <parameter name="@amount" layout="${event-context:item=Amount}" />
        <parameter name="@stacktrace" layout="${stacktrace}" />
      </target>
    </target>

    <!--write log message to Visual Studio Output-->
    <target name="debugger" xsi:type="Debugger" layout="NLog: ${date:format=HH\:mm\:ss} | ${level:uppercase=true:padding=-5} | ${message}" />
  </targets>

  <rules>
    <!--TRACE,DEBUG,INFO,WARN,ERROR,FATAL-->
    <logger name="*" minlevel="Trace" writeTo="debugger" />
    <!--INFO,WARN,ERROR,FATAL-->
    <logger name="*" minlevel="Info" writeTo="db" />
    <!--DEBUG,INFO,WARN,ERROR,FATAL-->
    <logger name="*" minlevel="Debug" writeTo="file" />    
  </rules></nlog>


  • 如在根節(jié)點(nlog)配置 internalLogLevel, internalLogFile,可以查看NLog輸出日志時的內部信息,比如你配置文件有錯誤,很有幫助,不過項目發(fā)布后還是關閉比較好,以免影響效率;

  • 在target外面罩了一個 <target>并且xsi:type為 AsyncWrapper,即表示這條 target 將異步輸出,這里我將文件和數據庫日志異步輸出;

  • db target內指定了數據庫連接字符串 connectionString,SQL語句,SQL參數,還可以指定數據庫/表創(chuàng)建和刪除的腳本(推薦看NLog源碼示例,這里不介紹),同時我們自定義了2個參數 action和amount;

  • target參數里有些是NLog內置參數,比如message,level,date,longdate,exception,stacktrace等,NLog在輸出時會自動賦值;

  • layout設置了每條日志的格式;

  • 在rules節(jié)點,我們分別指定了三個target輸出日志的級別,NLog用于輸出日志的級別包括:Trace,Debug,Info,Warn,Error,Fatal,可以設置 minlevel設置最小級別,也可以用 levels定義你所有需要的級別(多個用逗號分隔)。

 

封裝

簡單兩句就可以使用NLog了:

NLog.Logger logger = Nlog.LogManager.GetCurrentClassLogger();
logger.Fatal("發(fā)生致命錯誤");
logger.Warn("警告信息");

 

但是這樣只能記錄了NLog的內置字段,我們定義的 Amount, Action都不能寫入,接下來我們來封裝一個Logger:


public class Logger
    {
        NLog.Logger _logger;        private Logger(NLog.Logger logger)
        {
            _logger = logger;
        }        public Logger(string name) : this(LogManager.GetLogger(name))
        {

        }        public static Logger Default { get; private set; }        static Logger()
        {
            Default = new Logger(NLog.LogManager.GetCurrentClassLogger());
        }        #region Debug        public void Debug(string msg, params object[] args)
        {
            _logger.Debug(msg, args);
        }        

        public void Debug(string msg, Exception err)
        {
            _logger.Debug(err, msg);
        }        
        #endregion

        #region Info        public void Info(string msg, params object[] args)
        {
            _logger.Info(msg, args);
        }        public void Info(string msg, Exception err)
        {
            _logger.Info(err, msg);
        }        #endregion

        #region Warn        public void Warn(string msg, params object[] args)
        {
            _logger.Warn(msg, args);
        }        public void Warn(string msg, Exception err)
        {
            _logger.Warn(err, msg);
        }        #endregion

        #region Trace        public void Trace(string msg, params object[] args)
        {
            _logger.Trace(msg, args);
        }        public void Trace(string msg, Exception err)
        {
            _logger.Trace(err, msg);
        }        #endregion

        #region Error        public void Error(string msg, params object[] args)
        {
            _logger.Error(msg, args);
        }        public void Error(string msg, Exception err)
        {
            _logger.Error(err, msg);
        }        #endregion

        #region Fatal        public void Fatal(string msg, params object[] args)
        {
            _logger.Fatal(msg, args);
        }        public void Fatal(string msg, Exception err)
        {
            _logger.Fatal(err, msg);
        }        #endregion

        #region Custom        public void Process(Models.Log log)
        {            var level = LogLevel.Info;            if (log.Level == Models.EFLogLevel.Trace)
                level = LogLevel.Trace;            else if (log.Level == Models.EFLogLevel.Debug)
                level = LogLevel.Debug;            else if (log.Level == Models.EFLogLevel.Info)
                level = LogLevel.Info;            else if (log.Level == Models.EFLogLevel.Warn)
                level = LogLevel.Warn;            else if (log.Level == Models.EFLogLevel.Error)
                level = LogLevel.Error;            else if (log.Level == Models.EFLogLevel.Fatal)
                level = LogLevel.Fatal;            var ei = new MyLogEventInfo(level, _logger.Name, log.Message);
            ei.TimeStamp = log.Timestamp;
            ei.Properties["Action"] = log.Action;
            ei.Properties["Amount"] = log.Amount;

            _logger.Log(level, ei);
        }        #endregion

        /// <summary>
        /// Flush any pending log messages (in case of asynchronous targets).        /// </summary>
        /// <param name="timeoutMilliseconds">Maximum time to allow for the flush. Any messages after that time will be discarded.</param>
        public void Flush(int? timeoutMilliseconds = null)
        {            if (timeoutMilliseconds != null)
                NLog.LogManager.Flush(timeoutMilliseconds.Value);

            NLog.LogManager.Flush();
        }
    }    public class MyLogEventInfo : LogEventInfo
    {        public MyLogEventInfo() { }        public MyLogEventInfo(LogLevel level, string loggerName, string message) : base(level, loggerName, message)
        { }        public override string ToString()
        {            //Message format            //Log Event: Logger='XXX' Level=Info Message='XXX' SequenceID=5
            return FormattedMessage;
        }
    }



public class Log : IEntityBase<long>
    {        public long Id { get; set; }        /// <summary>
        /// 日志級別 Trace|Debug|Info|Warn|Error|Fatal        /// </summary>
        public string Level { get; set; }        
        public string Message { get; set; }
        public string Action { get; set; }
        public string Amount { get; set; }        public string StackTrace { get; set; }
        public DateTime Timestamp { get; set; }        private Log() { }        public Log(string level, string message, string action = null, string amount = null)
        {            this.Level = level;            this.Message = message;            this.Action = action;            
            this.Amount = amount;
        }
    }


  • Models.Log是我們項目里的日志對象,它對應一個數據表Log,NLog將日志數據寫入到這個表;

  • Process(Models.Log)是我們處理自定義對象的日志方法,用LogEventInfo來寫入;

  • 重寫 LogEventInfo.ToString() 是因為 LogEventInfo的Message格式是“Log Event: Logger='XXX' Level=Info Message='XXX' SequenceID=5”,不便于查閱,我們只需要我們設置的Message。

 

使用:

下面是測試方法,我們一共輸出9條日志,這9條日志將輸出到哪個目標,由配置文件中的Rules/logger決定


Logger.Default.Trace("Hello World! Trace");
Logger.Default.Info("Hello World! Info");
Logger.Default.Warn("Hello World! Warn");
Logger.Default.Debug("Hello World! Debug");
Logger.Default.Error("Hello World! Error");
Logger.Default.Fatal("Hello World! Fatal");

Logger.Default.Process(new Models.Log(Models.EFLogLevel.Info, "Hello World! Info", "TEST", "100.00"));
Logger.Default.Process(new Models.Log(Models.EFLogLevel.Debug, "Hello World! Debug", "TEST", "100.00"));
Logger.Default.Process(new Models.Log(Models.EFLogLevel.Error, "Hello World! Error", "TEST", "100.00"));
Logger.Default.Flush();


因為我們在Target中設置了異步,所以如果我們想當場看到輸出結果,就需要使用Flush()方法,實際輸出日志時就不需要了。

 

結果:

查看日志記錄:


如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網友會為你解答!! 點擊進入論壇

發(fā)表評論 (714人查看,0條評論)
請自覺遵守互聯(lián)網相關的政策法規(guī),嚴禁發(fā)布色情、暴力、反動的言論。
昵稱:
最新評論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學習

業(yè)務咨詢

· 技術支持
· 服務時間:9:00-18:00
365建站網二維碼

Powered by 365建站網 RSS地圖 HTML地圖

copyright © 2013-2024 版權所有 鄂ICP備17013400號