相信大家對於 Log 的重要性都有一定的認知,本篇筆者分享一下如何透過注入 NLog 並且透過 Mircosoft.Extensions.Logging 來解除對於 NLog 的相依,藉此實作 Dot Net Core Log 機制。
大家在使用Logger紀錄Log時常會有個問題,要用NLog還是log4net,再來就是實體要怎麼生成,要用Singleton還是要用static函式,最後要怎麼統一Log的格式,今天筆者來分享我的作法:
- 利用 Mircosoft.Extensions.Logging 來將Logger抽象化,從此不用在實做時擔心要用NLog或是log4net。
- 利用相依注入,實作只需要在建構子說明需要什麼,不需要考慮需要元件的生成與消滅。
- 學習 NLog 的設定檔設定方式以及自定義擴充方法來格式化Log的內容。
相依套件以及環境設定
此篇文章是基於.Net Core的版本寫成的,以下列出所需套件:
- NLog.Config
- NLog.Web.AspNetCore
由於安裝 NLog.Web.AspNetCore 就會安裝 Mircosoft.Extensions.Logging 所以不將其列在相依套件,接下來就一步一步說明。
實作方式
Mircosoft.Extensions.Logging
我們使用 Mircosoft.Extensions.Logging 是要將Logger 抽象化,也就是使用 Logger 的物件相依的是 Mircosoft.Extensions.Logging 的 ILogger
而不是 NLog 的。這樣做之後如果要更換 Logger 的實體就不會影響到程式碼本身了。
說了這麼多接下來就看看筆者怎麼實作,首先假設我們要實作一個 HomeController 我們只要透過建構子將 ILogger
注入即可,請看以下程式碼:
public class HomeController : Controller
{
private readonly ILogger _logger;
public LoggerService(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index () {
_logger.LogInformation("This is Index Log");
return View ();
}
}
如此當使用者造訪 HOME\Index\ 時他就會使用注入的 logger 的 LogInformation 的方法了,此時也不用在乎其使用的是 NLog 還是 log4net 了,這就看注入的 Logger 是哪一個了。
注入
當使用 .Net Core 注入就變得容易許多了,這裡只需要在
加入一段程式碼即可。Program.cs
using NLog.Web; // <--記得Using這個不然C#不認識要新增的方法.
.
.
.
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseNLog(); // <--多加這行即可
由於引用 NLog.Web 會有擴充方法 UseNLog讓注入在一行內完成。
格式化 Log 內容
也許使用者會覺得 LogInformation 這方法名稱太長,想要改短一點,又或者想要紀錄方法名稱跟行號,這時我們來自定擴充方法,透過擴充方法來格式化 Log 的內容,以及使用自訂義的方法名稱,這裡我們加入 ILogger.Extension.cs 並加入以下內容:
using System.Runtime.CompilerServices;
namespace ILogger.Extension
{
public static class ILoggerExtensions
{
public static void Info(this ILogger logger,
string log,
[CallerMemberName] string name = "",
[CallerLineNumber] int line = 0)
{
logger.LogInformation($"Method:{name}, Line:{line}, Message:{log}");
}
}
}
這裡我們使用 呼叫資訊 來列出方法名稱及行號,並定義每個 Log 都包含這資訊。
接下來在使用到 ILogger 的地方多 using 這個 namespace 就可以使用這個擴充方法了。
當然 Log 的層級不只是 Info 而已,接下來再請使用者依樣畫葫蘆實作其他層級吧。
NLog Config 設定
當安裝 NLog.Config 安裝程式會在執行檔所在目錄產生 NLog.config 檔案,接下來簡單修改就可以把 Log 寫到檔案內,以下範例真對設定內容做一簡單的說明:
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<targets>
<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="Microsoft.*" maxlevel="Info" final="true" /> <!-- BlackHole without writeTo -->
<logger name="*" minlevel="Debug" writeTo="f" />
</rules>
</nlog>
這邊做個簡單介紹,首先設定一下 target
再來設定 rules
把對應的 LOG 寫到 target
內,簡單講 target
是要寫到哪裡, rules
就是想要紀錄的 Log 條件。更進一步內容請見 NlogConfiguration 。
結語
今天跟大家分享一下筆者於 .Net Core 實作Logger 機制的方式,藉由這樣的架構可以任意抽換 Logger 的實作,而不會影響程式的實作,希望這篇文章能讓大家有所收穫。