1. 程式人生 > >使用Nlog記錄日誌到資料庫

使用Nlog記錄日誌到資料庫

Nlog是一個很不錯的.NET日誌記錄元件,它可以將日誌輸出到控制元件臺,儲存到文字,也可以很方便的記錄到資料庫中。

可以在這裡下載Nlog:http://nlog-project.org/

這裡分享一下如何配置Nlog,可以使其日誌記錄到資料庫中(這裡我用的是SQL server 2008).

新建一個控制元件臺專案:NlogSample,再通過NuGet加入Nlog程式集,如果沒有裝NuGet也可以在Nlog官網上下載,如圖:

安裝好以後,在專案中就有了Nlog程式集和Nlog.config檔案

開啟Nlog.config檔案,在target節點中,增加對資料庫的配置。

<target type="Database" name="database" connectionstring="Data Source=.;Initial Catalog=ReportServerTempDB;Integrated Security=True">
      <commandText>
        insert into MyLog ([CreateDate], [Origin], [LogLevel], [Message], [StackTrace]) 
        values (@createDate, @origin, @logLevel, @message, @stackTrace);
      </commandText>
      <parameter name="@createDate" layout="${longdate}"/>
      <!--日誌發生時間-->
      <parameter name="@origin" layout="${callsite}"/>
      <!--日誌來源-->
      <parameter name="@logLevel" layout="${level}"/>
      <!--日誌等級-->
      <parameter name="@message" layout="${message}"/>
      <!--日誌資訊-->
      <parameter name="@stackTrace" layout="${stacktrace}"/>
      <!--堆疊資訊-->
</target>

  其中:connectionstring是資料庫連線串,commandText是插入的SQL語句,parameter 是引數資訊。當然在記錄之前我們要先在資料庫中建好相應的表。
在Nlog.config中的rule中增加日誌記錄規則

<rules>
    <!-- add your logging rules here -->
    <logger name="*" writeTo="database"/>
    <!--
    <logger name="*" minlevel="Trace" writeTo="f" />
    -->
 </rules>

  這樣,我們的Nlog.config就設定好了。在Main方法中寫幾句程式碼測試一下: 

  class Program
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        static void Main(string[] args)
        {
            logger.Fatal("發生致命錯誤");
        }
    }

  執行成功,資料庫中已經增加一條日誌記錄了

LigID    CreateDate    Origin    LogLevel    Message    Exception    StackTrace
20    2012-10-18 15:49:16.4114    NlogSample.Program.Main    Fatal    發生致命錯誤    NULL    
AppDomain.ExecuteAssembly => AppDomain._nExecuteAssembly => Program.Main

  我們也可以將日誌等級比較低的記錄到文字,只將比較嚴重的日誌記錄到資料庫中,相應的Nlog.config如下:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      throwExceptions="true" internalLogFile="c:\nlog.txt" internalLogLevel="Debug">

  <!-- 
  See http://nlog-project.org/wiki/Configuration_file 
  for information on customizing logging rules and outputs.
   -->
  <!--<nlog throwExceptions="true" internalLogFile="c:\nlog.txt" internalLogLevel="Debug" />-->
  <targets>
    <!-- add your targets here -->
    <target name="file" xsi:type="File" fileName="${basedir}/logs/Log ${shortdate}.txt" layout="${longdate} ${callsite} ${level}: ${message} ${event-context:item=exception} ${stacktrace}" />
    <target type="Database" name="database" connectionstring="Data Source=.;Initial Catalog=ReportServerTempDB;Integrated Security=True">
      <commandText>
        insert into MyLog ([CreateDate], [Origin], [LogLevel], [Message], [StackTrace]) values (@createDate, @origin, @logLevel, @message, @stackTrace);
      </commandText>
      <parameter name="@createDate" layout="${longdate}"/><!--日誌發生時間-->
      <parameter name="@origin" layout="${callsite}"/><!--日誌發生時間-->
      <parameter name="@logLevel" layout="${level}"/><!--日誌等級-->
      <parameter name="@message" layout="${message}"/><!--日誌資訊-->
      <parameter name="@stackTrace" layout="${stacktrace}"/><!--日誌發生時間-->
    </target>
    <!--
    <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}" />
    -->
  </targets>

  <rules>
    <!-- add your logging rules here -->
    <logger name="*"  writeTo="file"/>
    <logger name="*" minlevel="Error" appendTo="database"/>
    <!--
    <logger name="*" minlevel="Trace" writeTo="f" />
    -->
  </rules>
</nlog>

    在根結點上設定:throwExceptions="true" internalLogFile="c:\nlog.txt" internalLogLevel="Debug" ,可以讓我們看到Nlog的內部錯誤,對除錯有很大的幫助。

這裡也許有人要問,上面日誌表中的引數${longdate},${level} 等都是Nlog內部恰好有提供的,要是我要記錄的資訊Nlog沒有怎麼辦?沒問題,我們完全可以自己定義日誌

表的資料結構。

重新配置Nlog.Config如下:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      throwExceptions="true" internalLogFile="c:\nlog1.txt" internalLogLevel="Debug">

  <!-- 
  See http://nlog-project.org/wiki/Configuration_file 
  for information on customizing logging rules and outputs.
   -->
  <targets>
    <!-- add your targets here -->
    <target name="file" xsi:type="File" fileName="D:\ProcLogs/${event-context:item=appName}/${event-context:item=moduleName}/${event-context:item=procName}/${event-context:item=logTitle}/${shortdate}-${level}.txt"
            layout="${longdate} ${level}:${event-context:item=logMessage}" />
    <target name="fi" xsi:type="File" fileName="${basedir}/logs/Log ${shortdate}.txt"
           layout="${longdate} ${level}:${message} ${stacktrace}" />
    <target type="Database" name="database" connectionstring="Data Source=.;Initial Catalog=ReportServerTempDB;Integrated Security=True">
      <commandText>
        insert into DevLog ([AppName],[ModuleName],[ProcName],[LogLevel],[LogTitle],[LogMessage],[LogDate],[StackTrace]) values (@appName, @moduleName, @procName, @logLevel, @logTitle, @logMessage,@logDate,@stackTrace);
      </commandText>
      <parameter name="@appName" layout="${event-context:item=appName}"/>
      <parameter name="@moduleName" layout="${event-context:item=moduleName}"/>
      <parameter name="@procName" layout="${event-context:item=procName}"/>
      <parameter name="@logLevel" layout="${event-context:item=logLevel}"/>
      <parameter name="@logTitle" layout="${event-context:item=logTitle}"/>
      <parameter name="@logMessage" layout="${event-context:item=logMessage}"/>
      <parameter name="@logDate" layout="${longdate}"/>
      <parameter name="@stackTrace" layout="${stacktrace}"/>
    </target>
    <!--
    <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}" />
    -->
  </targets>

  <rules>
    <!-- add your logging rules here -->
    <logger name="Log"  writeTo="file"/>
    <logger name="L"  writeTo="fi"/>
    <!--<logger name="Log" minlevel="Info" appendTo="database"/>-->
    <!--
    <logger name="*" minlevel="Trace" writeTo="f" />
    -->
  </rules>
</nlog>

  類似<parameter name="@appName" layout="${event-context:item=appName}"/> ,我們就可以定義自己的引數。

然後在寫日誌的時候,可以通過LogEventInfo 類給我們的引數賦值,程式碼如下:

void WriteLog(LogLevel levle, string appName, string moduleName, string procName, string logLevel, string logTitle, string logMessage)
 {
         LogEventInfo ei = new LogEventInfo(levle, "", "");
         ei.Properties["appName"] = appName;
         ei.Properties["moduleName"] = moduleName;
         ei.Properties["procName"] = procName;
         ei.Properties["logLevel"] = logLevel.ToUpper();
         ei.Properties["logTitle"] = logTitle;
         ei.Properties["logMessage"] = logMessage;
         logger.Log(ei);
 }

 注意,設定資料庫時,時間要為字串型別。