nlog

ASP.NET Core 5 EP 5:使用NLog紀錄程式的日誌與事件

Log的重要性

專案建立後,我們需要一系列的前置工作讓一切都完整,其中最重要的就是導入Log紀錄的機制,不論在開發過程、測試階段或是正式營運時都能記錄下事件資訊,當出錯需要查詢時,才能有跡可循。

選擇NLog

NLog是一個老牌的Logging第三方套件,基本支援所有.Net Frameworks、.NET Core以及mono等非官方的.Net生態系,並且可以輕易的將事件資訊存放到檔案、資料庫、Console或是直接以E-Mail發出。

程式方面,其導入簡單,只要短短幾行程式碼即可完成;客製化程度高,讓使用者自由設計屬於自己的Log格式;再者NLog很輕巧,幾乎不影響程式原本執行的效能;在這些優點之下,在此選擇NLog作為事件紀錄的套件。

官方網站:https://nlog-project.org/

安裝及設定NLog

步驟1:編輯CookbookApi.csproj,在ItemGroup段落加入NLog主要的套件,包含NLog與NLog.Web.AspNetCore,如下:

CookbookApi.csproj

<ItemGroup>
    <PackageReference Include="NLog.Web.AspNetCore" Version="4.9.*" />
    <PackageReference Include="NLog" Version="4.7.*" />
</ItemGroup>

存擋後,右下角會跳出是否要重新載入專案的訊息,如下:

按下Restore,重新載入專案,此時,VS Code會自動幫我們將NLog與相依套件全部下載並安裝完成。

步驟2:在根目錄建立nlog.config,此為NLog的設定檔。

<?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="Info">

  <!-- enable asp.net core layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <!-- the targets to write to -->
  <targets>
    <!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
    <target xsi:type="Console" name="lifetimeConsole" layout="${level:truncate=4:lowercase=true}: ${logger}[0]${newline}      ${message}${exception:format=tostring}" />
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--Output hosting lifetime messages to console target for faster startup detection -->
    <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole" final="true" />

    <!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
    <logger name="Microsoft.*" maxlevel="Info" final="true" />
    <logger name="System.Net.Http.*" maxlevel="Info" final="true" />
  </rules>
</nlog>

以上設定,是將Log的資訊以Console的方式列印在視窗上。

步驟3:編輯Program.cs,讓程式啟動時能順便啟動NLog。

Program.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using NLog.Web;

namespace ASP.NET_Core_5_NLog_Example
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
            try
            {
                logger.Debug("init main");
                CreateHostBuilder(args).Build().Run();
            }
            catch (Exception exception)
            {
                //NLog: catch setup errors
                logger.Error(exception, "Stopped program because of exception");
                throw;
            }
            finally
            {
                // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
                NLog.LogManager.Shutdown();
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders();
                    logging.SetMinimumLevel(LogLevel.Trace);
                })
                .UseNLog();  // NLog: Setup NLog for Dependency injection
    }
}

步驟4:調整專案設定檔appsettings.json。

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

以上,我們已經完成NLog最基本的安裝程序了,若有需要詳細的資訊,可以參考官方教學網站

將Log導入NLog

在Controllers目錄下新增一個RecipeController.cs控制器,我們要插入導入NLog的程式碼,並且宣告NLog,如下:

RecipeController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace CookbookApi.Controllers
{
    [Route("api/[controller]")]
    public class RecipeController : Controller
    {
        private readonly ILogger<RecipeController> _logger;

        public RecipeController(ILogger<RecipeController> logger)
        {
            _logger = logger;
        }
}

在這個Controller中,若要寫入Log,可以參考以下程式碼:

_logger.LogInformation("This is a log!");

上述這段程式碼可以插在任何想要紀錄Log的地方!

而Log的等級大致分為6個等級,如下圖:

依據不同的需求可以自行參考使用,如下範例:

_logger.LogCritical("");
_logger.LogDebug("");
_logger.LogError("");
_logger.LogInformation("");
_logger.LogTrace("");
_logger.LogWarning("");

至此,我們已經可以將Log依據需求透過NLog留下紀錄了,但有一個問題,不可能預先知道哪些程式會出錯,當然也不可能將紀錄Log的程式碼插在最正確的地方,因此需要一種通用的機制來處理錯誤,通稱為Exception Handling,在ASP.NET Core中,可以利用中介層軟體(Middleware)實現,但這涉及比較深入的技術,稍後幾篇文章會特別撰述。

~ END ~


, ,

Related posts

Latest posts