2018年7月8日 星期日

ASP.NET Core 使用 NLog 將 Log 寫到 Elasticsearch

前一篇「Docker-Compose 建立 Elasticsearch 與 Kibana 服務」說明了使用 Docker-Compose 建立了 Elasticsearch 和 Kibana 以及相關的服務,這一篇接續說明在 ASP.NET Core 網站裡使用 NLog 將 Log 寫到 Elasticsearch。



建立專案

在 Visual Studio 2017 裡建立 ASP.NET Core MVC 網站服務(這邊是使用 .NET Core 2.1.1)

.NET Downloads for Windows – Download .NET Core 2.1 SDK

image

image

安裝 NuGet Packages

在專案裡安裝以下幾個 NuGet Packages

NLog.Web.AspNetCore
NLog.Extensions.Logging
NLog.Targets.ElasticSearch
Elasticsearch.Net

image

新增 NLog.config

這邊的設定會將系統執行時的 Log 寫到文字檔與 Elasticsearch 中,Log 寫到 Elasticsearch 是透過 NLog.targets.ElasticSearch 這個套件

<?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"
      autoReload="true"
      internalLogLevel="Warn"
      internalLogFile="internal-nlog.txt">

  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
    <add assembly="NLog.Targets.ElasticSearch"/>
  </extensions>

  <targets async="true">
    <!-- local log file -->
    <target xsi:type="File" name="File"
            fileName="${basedir}/logs/${date:format=yyyy-MM-dd}.log"
            archiveAboveSize="20000000"
            archiveNumbering="Rolling"
            encoding="UTF-8"
            enableFileDelete="true"
            maxArchiveFiles="5"
            layout="[${date:format=yyyy-MM-dd HH\:mm\:ss}][${level}] ${logger} ${message} ${exception:format=toString}" />

    <!-- ElasticSearch -->
    <target name="ElasticSearch"
            xsi:type="ElasticSearch"
            ConnectionStringName="ElasticSearchServerAddress"
            index="dotnetcore-nlog-elk-${date:format=yyyy.MM.dd}"
            documentType="logevent"
            includeAllProperties="true"
            layout="[${date:format=yyyy-MM-dd HH\:mm\:ss}][${level}] ${logger} ${message} ${exception:format=toString}">
      <field name="MachineName" layout="${machinename}" />
      <field name="Time" layout="${longdate}" />
      <field name="level" layout="${level:uppercase=true}" />
      <field name="logger" layout=" ${logger}" />
      <field name="message" layout=" ${message}" />
      <field name="exception" layout=" ${exception:format=toString}" />
      <field name="processid" layout=" ${processid}" />
      <field name="threadname" layout=" ${threadname}" />
      <field name="stacktrace" layout=" ${stacktrace}" />
      <field name="Properties" layout="${machinename} ${longdate} ${level:uppercase=true} ${logger} ${message} ${exception}|${processid}|${stacktrace}|${threadname}" />
    </target>

  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="File" />
    <logger name="*" minlevel="Trace" writeTo="ElasticSearch" />
  </rules>
</nlog>

記得要修改 NLog.config 檔案屬性,將「複製到輸出目錄」修改為「永遠複製

image

修改 appsettings.Development.json

在 NLog.config 的 ElasticSearch target 並不是將 elasticsearch 服務的位置寫在裡面,而是提供一個連接字串名稱,實際的 elasticsearch 服務位置則是寫在 appsettings 裡。這麼一來就可以依據執行環境切轉使用不同的環境的 elasticsearch 服務。

image

修改 Program.cs

image

修改 Startup.cs

Configure 方法簽章增加 ILoggerFactory,並且在方法裡使用 AddNLog ( enable NLog as logging provider in .NET Core )

image

HomeController 加入 Logger

這邊不是直接使用 NLog 的 LogManager 產生 logger,而是使用注入的方式,而且 logger 的型別為 Microsoft.Extensions.Logging 的 ILogger 泛型類別

image

在 Index, About, Contact 方法裡加入寫 log 的處理

image

執行程式並觀察 Log

首先開啟專案的 bin\Debug\netcoreapp2.1\logs 資料夾,如果依照上面的設定都正常無誤的話,可以看到有產生 log 檔案,開啟檔案就可以看到 log 內容

image

接著開啟 cerebro 服務( http://localhost:9900 ),連接 http://elasticsearch:9200

在 rest 功能頁面裡,使用 rest 指令「dotnetcore-nlog-elk-2018.07.08/logevent/_search」並執行,就可以看到剛才系統執行時所寫入的 log

image

image



現在已經確認把 log 寫到文字檔與 Elasticsearch 裡面了,但是光靠 cerebro 就不是那麼好查詢與檢視,下一篇再來說明如何在 Kibana 裡查看 log。


參考連結

https://github.com/ReactiveMarkets/NLog.Targets.ElasticSearch/wiki

ASP.NET Core logging with NLog and Elasticsearch | Software Engineering


以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。