前言
近期專案都在嘗試 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 意見:
張貼留言