前情提要 筆者公司使用NLog
當作Log
工具,相當簡單易用,但用到現在會有一個困擾,畢竟為方便測試,到處埋Info
等級的Log
於程式中,為方便偵錯及追蹤,可能連傳入的資料都會記錄於文字檔中,變成正式環境也會有同樣的效果,因為這個Nlog.Config
又加入於版控中,要嘛就是在release
分支那邊將Nlog.config
調整成正式環境符合的設定,也是頗麻煩。
筆者這篇主要是解決上述問題,解決方式也頗簡單,將Nlog.config
製作多個帶有Environment
的檔名,NLogBuilder
註冊時套用不同的NLog.Config
檔案即可解決。基本上若為預設的NLog.config
則不需特別註冊也有效,因要針對不同環境,套用不同的config
檔案,必須宣告NLogBuilder
註冊。
內容 筆者這邊使用dotnet core
版本為6.0.100
,已經是套用minimal api
形式,還真不習慣。
Demo專案建立 首先簡單建立一下webapi
專案
1 dotnet new webapi -o NLog.Demo.API
加入NLog相關套件 筆者這邊會使用到三個NLog相關套件
NLog
NLog.Config
NLog.Web.AspNetCore
1 2 3 dotnet add package NLog dotnet add package NLog.Config dotnet add package NLog.Web.AspNetCore
製作不同環境使用的NLog.Config檔案 就直接用手動方式建立不同環境使用的NLog.Config檔案
1 2 touch nlog.development.configtouch nlog.production.config
直接從NLog.Config預設的設定,調整成不同環境所要的rules及target,筆者這邊為演示,直接使用文字檔案紀錄,並且於不同環境下設定不一樣的minlevel,以示有效套用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <?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" > <variable name ="myvar" value ="myvalue" /> <targets > <target xsi:type ="File" name ="f" fileName ="${basedir}/logs/${shortdate}.log" layout ="${longdate} ${uppercase:${level}} ${message}" /> </targets > <rules > <logger name ="*" minlevel ="Info" writeTo ="f" /> </rules > </nlog >
1 2 3 4 5 <!--以上省略--> <rules> <logger name="*" minlevel="Error" writeTo="f" /> </rules> <!--以下省略-->
套用不同的NLog.Config 於Program.cs
中宣告NLogBuilder
註冊
1 2 3 4 5 6 7 var env = builder.Environment.EnvironmentName;NLogBuilder.ConfigureNLog($"nlog.{env} .config" ).GetCurrentClassLogger(); builder.Logging.ClearProviders(); builder.Host.UseNLog();
一樣是在Program.cs
中,寫一個簡單的API
入口以準備測試
1 2 3 4 5 6 7 8 9 10 11 12 13 app.MapControllers(); app.MapGet("/logtest" , () => { app.Logger.LogTrace("LogTrace" ); app.Logger.LogDebug("LogDebug" ); app.Logger.LogInformation("LogInformation" ); app.Logger.LogWarning("LogWarning" ); app.Logger.LogError("LogError" ); app.Logger.LogCritical(new Exception("eLogCritical" ), "LogCritical" ); return "logtest" ; }); app.Run();
Demo效果 筆者透過launchsettings.json
中的設定來模擬不同執行環境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 "profiles" : { "NLog.Demo.API" : { "commandName" : "Project" , "dotnetRunMessages" : true , "launchBrowser" : true , "launchUrl" : "swagger" , "applicationUrl" : "http://localhost:5187" , "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } } , }
為方便直接透過swagger api
說明頁面點擊其API,調整一下Program.cs
中的設定
1 2 3 4 5 6 { app.UseSwagger(); app.UseSwaggerUI(); }
先看一下swagger api
說明頁面,直接點上面的/logtest API
Development環境 執行完成後會在文字檔案中可看到minlevel
為info
的效果,從info
等級開始印
1 2 3 4 2022-05-17 14:51:52.9377 INFO LogInformation 2022-05-17 14:51:52.9377 WARN LogWarning 2022-05-17 14:51:52.9377 ERROR LogError 2022-05-17 14:51:52.9377 FATAL LogCritical
Production環境 執行完成後會在文字檔案中可看到minlevel
為error
的效果,從error
等級開始印
1 2 2022-05-17 14:52:35.3299 ERROR LogError 2022-05-17 14:52:35.3434 FATAL LogCritical
結論 落落等寫了這麼多,基本上就是只有兩步驟
製作不同環境使用的NLog.Config
檔案
宣告NLogBuilder.ConfigureLog
的方式不同環境下套用不同的NLog.Config
檔案
以上解決方案,確實解決筆者困擾的問題,這篇就到這邊了,下篇見。