[netCore] Logging Framework

NetCore 2.0 內建Logging Famework,預設我們可以直接透過DI方式取得Logging物件,

這篇紀錄一下使用心得及如何整合Nlog。

Asp.net core預設不提供非同步的logging方法,因為處理過程應該是相當快速,所以不值得使用非同步方法,

Logging主要有三個介面,ILogger、ILoggerFactory和ILoggerProvider,

這些介面由兩個nuget package Microsoft.Extensions.Logging.AbstractionsMicrosoft.Extensions.Logging所提供,

過濾條件部分,也可以透過json file來設定,目前provider有以下六種

Console

Debug

EventLog

AzureAppServices

TraceSource

EventSource

基本上和其他第三方Library使用方式大同小異,我們可以很輕鬆在controller注入ILogger後並開始使用相關介面方法。

先在BuildWebHost加入configureLogging,這樣我們就能在controller簡單使用

Json file format

{
  "Logging": {
    "IncludeScopes": false,
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "LogLevel": {
      "Default": "Debug",
      "MyAPI": "Trace",
      "System": "Error",
      "Microsoft": "Error"
    }
  }
}

我為Debug設定一項最低層級=Information的過濾條件,針對Console provider設定四項,

最後一項適用所有provider,另外,Debug和trace Level不應該出現在正式環境,

避免量太多影響主要服務,但如果你真的需要這些資訊,

你可以透過分散式系統架構來隔離錯誤,同時達到降低系統相依性並提高可用性。

 

整合Nlog

NetCore現有Logging framework只提供六種provider,雖然你可以自行擴充其他provider,

但我們思考後決定使用Nlog成為我們系統主要的Logging framework,

整合過程也相當簡單,而且DI注入不可少。

@Install NLog and NLog.Web.AspNetCore packages

@create a nlog.config file

我這裡target設定了file,console和db

note:NetCore中,所有aspnet-request:serverVariable=xx並未實作,所以相關內容皆為空值。

reference: AspNetRequest layout renderer

<?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"
      internalLogFile="c:/aplog/internal-nlog.txt">

  <variable name="Layout"
            value="${longdate}|${level:uppercase=true}|${logger}|${message}"/>

  <!-- the targets to write to -->
  <targets>    
    <!-- write logs to file -->
    <target xsi:type="File"
            name="allfile"
            fileName="c:/aplog/nlog-all-${shortdate}.log"
            layout="[${longdate}][${machinename}][${level}] ${message} ${exception}" />
    <target name="logconsole" xsi:type="Console" />
    <!-- write to the void aka just remove -->
    <target xsi:type="Null" name="blackhole" />
    <target name="SQLServer" xsi:type="Database">
    <connectionString>Server=.;Database=DemoQueryStore;Trusted_Connection=True;</connectionString>
    <commandType>StoredProcedure</commandType> 
    <commandText>[dbo].[usp_AddLog]</commandText> 
    <parameter name="@machineName"    layout="${machinename}" />
    <parameter name="@siteName"       layout="${iis-site-name}" />
    <parameter name="@logged"         layout="${date}" />
    <parameter name="@level"          layout="${level}" />
    <parameter name="@username"       layout="${aspnet-user-identity}" />
    <parameter name="@message"        layout="${message}" />
    <parameter name="@logger"         layout="${logger}" />
    <parameter name="@properties"     layout="${all-event-properties:separator=|}" />
    <parameter name="@serverName"     layout="${aspnet-request-host}" />
    <parameter name="@port"           layout="${aspnet-request:serverVariable=SERVER_PORT}" />
    <parameter name="@url"            layout="${aspnet-request-url:IncludeHost=true:IncludePort=true:IncludeQueryString=true}" />
    <parameter name="@https"          layout="${when:inner=1:when='${aspnet-request:serverVariable=HTTPS}' == 'on'}${when:inner=0:when='${aspnet-request:serverVariable=HTTPS}' != 'on'}" />
    <parameter name="@serverAddress"  layout="${aspnet-request-host}" />
    <parameter name="@remoteAddress"  layout="${aspnet-request-ip}" />
    <parameter name="@callSite"       layout="${callsite}" />
    <parameter name="@exception"      layout="${exception:tostring}" />
    </target>
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Info" writeTo="allfile" />
    <logger name="*" minlevel="Trace" writeTo="logconsole" />
    <logger name="*" minlevel="Error" writeTo="SQLServer" />
    <!--Skip Microsoft logs and so log only own logs-->
    <logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
  </rules>
</nlog>

 

@update programe.cs

note:整合Nlog後,所有controller的code都無須異動。

結果

 

參考

Getting started with ASP.NET Core 2

Database target

logging/index.md

Microsoft.Extensions.Logging.AzureAppServices

Logging in ASP.NET Core

Configuration in ASP.NET Core

High-performance logging with LoggerMessage in ASP.NET Core

Creating a rolling file logging provider for ASP.NET Core 2.0

Logging Framework In ASP.NET Core 2.0