前言
近期專案都在嘗試 Serilog,對於使用上有點小小心得,因此整理這篇文章分享 Serilog 在 ASP.NET Core API 上的使用與設定,也接續之前 Serilog 的系列介紹文 : 傳送門 的實際應用心得,希望可以幫到有需要的朋友,若有問題或是錯誤的地方歡迎提出來一起討論或是給予指導。
ASP.NET Core logging
首先先建立新的 ASP.NET Core Web Application 專案,開啟 Visual Studio 2019 選擇建立新專案,專案名稱輸入 SerilogWebAppLab,模板部分選擇 API,然後按下確定送出
新增完專案之後,可以看到專案中 program.cs 內建 CreateWebHostBuilder 方法,此方法會在 Application 啟動時,使用預設方法也會一併註冊內建 logging,接著我們來看一下內建 logging 輸出樣式,在 ValueController 中建構式加入 _Logger 並在 GET 方法中使用 log.Information、Warning 以及 Error
從預設 logging 內容可以發現紀錄了除了自己紀錄的 log 之外資料,紀錄了 Application 以及 Request 的內容還有執行的時間,CreateWebHostBuilder 方法預設的情況下使用的 Config 為專案檔底下的 appsettings.json 及 appsettings.Development.json (依設定環境決定),之前有撰寫過一篇關於設定環境變數的文章,有興趣可以參考 : 傳送門。在此如果希望不啟用內建的 logging 紀錄資訊,可以在 CreateWebHostBuilder 方法中加上 config.ClearProviders() 刪除預設的 logging 提供者
也成功寫入檔案,預設會在指定檔名 File 後加上 日期,log_ 變成 log_20190101.txt
感想
透過以上的說明,希望可以讓對 Serilog 有興趣的的朋友可以快速入門,之前也花了點時間介紹 Serilog 相關的入門 & 基本設定方式,若有興趣想了解細節的也可以了解看看,系列文連結 : 傳送門 :)
參考
Structured logging concepts in .NET Series
Serilog series post近期專案都在嘗試 Serilog,對於使用上有點小小心得,因此整理這篇文章分享 Serilog 在 ASP.NET Core API 上的使用與設定,也接續之前 Serilog 的系列介紹文 : 傳送門 的實際應用心得,希望可以幫到有需要的朋友,若有問題或是錯誤的地方歡迎提出來一起討論或是給予指導。
首先先建立新的 ASP.NET Core Web Application 專案,開啟 Visual Studio 2019 選擇建立新專案,專案名稱輸入 SerilogWebAppLab,模板部分選擇 API,然後按下確定送出
新增完專案之後,可以看到專案中 program.cs 內建 CreateWebHostBuilder 方法,此方法會在 Application 啟動時,使用預設方法也會一併註冊內建 logging,接著我們來看一下內建 logging 輸出樣式,在 ValueController 中建構式加入 _Logger 並在 GET 方法中使用 log.Information、Warning 以及 Error
public class ValuesController : ControllerBase { private readonly ILogger _logger; public ValuesController(ILogger<ValuesController> logger) { _logger = logger; } // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { _logger.LogInformation("This is LogInformation"); _logger.LogWarning("This is LogWarning"); _logger.LogError("This is LogError"); return new[] { "value1", "value2" }; } ...執行專案按下 F5,輸出內容如下
從預設 logging 內容可以發現紀錄了除了自己紀錄的 log 之外資料,紀錄了 Application 以及 Request 的內容還有執行的時間,CreateWebHostBuilder 方法預設的情況下使用的 Config 為專案檔底下的 appsettings.json 及 appsettings.Development.json (依設定環境決定),之前有撰寫過一篇關於設定環境變數的文章,有興趣可以參考 : 傳送門。在此如果希望不啟用內建的 logging 紀錄資訊,可以在 CreateWebHostBuilder 方法中加上 config.ClearProviders() 刪除預設的 logging 提供者
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, config) => { config.ClearProviders(); }) .UseStartup<Startup>();在重新執行一次 Application,就會看到 Console output 僅剩三個 log。
Serilog
接著輪到今天的重頭戲 Serilog 登場,首先先透過 Nuget 下載 Serilog for .NET Core 套件
MinimumLevel.Information : 定義 Log 輸出 Level
WriteTo.Console : 設定使用 Console 輸出
WriteTo.File : 設定使用 File 檔案輸出,輸出位置及檔名為 log & log_txt
上述是在 Program.cs 中加上 Serilog 設定組態設定,在 Serilog 中也支援使用 Config 檔案來設定的動作,如果想要透過定義檔則需要至 Nuget 下載 Settings library
接著輪到今天的重頭戲 Serilog 登場,首先先透過 Nuget 下載 Serilog for .NET Core 套件
Install-Package Serilog.AspNetCoreSerilog 核心負責紀錄 Log 事件的內容,要將 Log 輸出則是透過 Sink,如果想瞭解更多細節可以參考 結構化日誌 Serilog 初體驗,這裡就不在多加介紹,這裡範例是使用 Console 與寫入實體檔案作為輸出,因此需要另外透過 Nuget 下載相關套件 Sinks.Console 與 Sinks.File 兩種,如果有其他需
Install-Package Serilog.Sinks.Console Install-Package Serilog.Sinks.File下載完 Serilog 相關 Package,接著就是在 WebHost 啟動時設定 Serilog 資訊也就是 Program.cs 中的 main 方法加下以下代碼
public class Program { public static void Main(string[] args) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/log_.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, config) => { config.ClearProviders(); }) .UseStartup<Startup>(); }程式說明
Install-Package Serilog.Settings.Configuration在 appSettings.json 加以下 config 定義內容,設定目的與內容與剛剛在 Program 寫 Log 方式相同
{ "Serilog": { "MinimumLevel": "Information", "WriteTo": [ { "Name": "Console", "Args": { "outputTemplate": "{Timestamp:yyyy/MM/dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}" } }, { "Name": "File", "Args": { "Path": "logs/log_.txt", "rollingInterval": "Day" } } ] } }在來修改 Program.cs 中的代碼,要調整新增 Configuration 時以檔案的內容為主
public class Program { private static string _envName; public static void Main(string[] args) { var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddJsonFile($"appsettings.{_envName}.json", optional: true, reloadOnChange: true) .Build(); Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .CreateLogger(); CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, config) => { config.ClearProviders(); _envName = hostingContext.HostingEnvironment.EnvironmentName; }) .UseStartup<Startup>(); }
configuration 部分代碼為定義設定檔的來源,也就是使用建立專案時內建的 appsettings.json,指定 Config 會隨不同環境取得不同的 appsettings.json,其中 CreateLogger 時用 ReadFrom.Configuation() 指定用 檔案內容指定取代原先落落長的代碼。
下一步就需要在 Startup.cs 中的 ConfigureService() 新增 Serilog 至服務中,這裡使用的是內建的 DI Framework,如果用習慣 Autofac 的朋友也可以下載 autofac-serilog-integration,
下一步就需要在 Startup.cs 中的 ConfigureService() 新增 Serilog 至服務中,這裡使用的是內建的 DI Framework,如果用習慣 Autofac 的朋友也可以下載 autofac-serilog-integration,
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog() ); }以上設定 Serilgo 完畢,接著重新執行 Application 並觀察其輸出內容,可以看到 logging 紀錄內容已透過 Console 與檔案輸出如下
也成功寫入檔案,預設會在指定檔名 File 後加上 日期,log_ 變成 log_20190101.txt
2019-05-13 13:00:06.279 +08:00 [INF] User profile is available. Using 'C:\Users\marcustung\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. 2019-05-13 13:00:08.112 +08:00 [INF] Request starting HTTP/1.1 GET https://localhost:5001/api/values 2019-05-13 13:00:08.178 +08:00 [INF] Executing endpoint 'SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab)' 2019-05-13 13:00:08.202 +08:00 [INF] Route matched with {action = "Get", controller = "Values"}. Executing action SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab) 2019-05-13 13:00:08.216 +08:00 [INF] Executing action method SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab) - Validation state: "Valid" 2019-05-13 13:00:08.221 +08:00 [INF] This is LogInformation 2019-05-13 13:00:08.222 +08:00 [WRN] This is LogWarning 2019-05-13 13:00:08.224 +08:00 [ERR] This is LogError 2019-05-13 13:00:08.230 +08:00 [INF] Executed action method SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 5.7992ms. 2019-05-13 13:00:08.240 +08:00 [INF] Executing ObjectResult, writing value of type 'System.String[]'. 2019-05-13 13:00:08.340 +08:00 [INF] Executed action SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab) in 131.7199ms 2019-05-13 13:00:08.344 +08:00 [INF] Executed endpoint 'SerilogWebAppLab.Controllers.ValuesController.Get (SerilogWebAppLab)' 2019-05-13 13:00:08.351 +08:00 [INF] Request finished in 245.3211ms 200 application/json; charset=utf-8成功紀錄 Log 在 Console 與 File 檔案,如果想要的輸出不只是檔案在 Serilog 提供多種 Provider,詳細可以參考官方網站所列的 Provided Sinks : 傳送門。
感想
透過以上的說明,希望可以讓對 Serilog 有興趣的的朋友可以快速入門,之前也花了點時間介紹 Serilog 相關的入門 & 基本設定方式,若有興趣想了解細節的也可以了解看看,系列文連結 : 傳送門 :)
Structured logging concepts in .NET Series
Loggly in ASP.NET Core using Serilog
0 意見:
張貼留言