之前有寫過一篇 C# 使用 Serilog 紀錄 Log (不用設定檔),但是在 ASP.NET Core 中寫法有些區別,Serilog 官方的範例也有點過時,在做了一些研究,整理後寫了這篇,希望能夠幫助到需要的人。
替換為:
更好的做法就是使用 把上面 15 到 40 行的部分用 try catch 包起來,因為後面程式越寫越多,在初始化時可能會發生錯誤,包這層 try catch 就可以直接捕捉到例外狀況
因為我們使用 Serilog 寫 Log,所以就可以把 appsettings.json 裡面一開始產生的 Logging 區塊移除 (2 到 7 行)
將第 10 行刪掉,換成第 11 行的 CreateBootstrapLogger
再將下面的第 2 行刪掉,換成 3 至 10 行,會要這麼麻煩把 WriteTo 的內容再寫一次是因為第一階段的 Log 轉移給第二階段之後就會被完全替換掉,變成新的。所以如果沒有再寫一次的話就會什麼都不輸出...
增加第 3 行,刪除 6-10 行
將設定檔(appsettings.json) 新增以下內容,這些設定值等同於本文最一開始寫在 C# 的 Log 設定內容
延伸閱讀:
ASP.NET Core 實際輸出日誌訊息
參考資料:
Serilog
Serilog.AspNetCore
Serilog.Settings.Configuration
-
測試環境:
- Windows 11
- Rider 2022.2.3
- .NET SDK 6.0.401
- Serilog.AspNetCore 6.0.1
dotnet add package Serilog.AspNetCore
啟動時直接使用 Serilog
本文示範是使用 Web Api 專案,在剛開啟新專案時 Program.cs 長的樣子:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
替換為:
using Serilog;
using Serilog.Events;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("logs/log-.log",
rollingInterval: RollingInterval.Hour, // 每小時一個檔案
retainedFileCountLimit: 24 * 30 // 最多保留 30 天份的 Log 檔案
)
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog();
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Log.CloseAndFlush();
更好的做法就是使用 把上面 15 到 40 行的部分用 try catch 包起來,因為後面程式越寫越多,在初始化時可能會發生錯誤,包這層 try catch 就可以直接捕捉到例外狀況
try
{
// 裡面放上面的 15 至 40 行
}
catch (Exception e)
{
Log.Error(e, "Host terminated unexpectedly");
}
Log.CloseAndFlush();
因為我們使用 Serilog 寫 Log,所以就可以把 appsettings.json 裡面一開始產生的 Logging 區塊移除 (2 到 7 行)
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
兩階段初始化
在官方 Serilog.AspNetCore 的 Github 頁面也有說明到在上面的方式中來自 ASP.NET Core 主機的服務、依賴注入和 Log 外部設定檔都無法使用,所以最好要加上第二階段的初始化將第 10 行刪掉,換成第 11 行的 CreateBootstrapLogger
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("logs/log-.log",
rollingInterval: RollingInterval.Hour, // 每小時一個檔案
retainedFileCountLimit: 24 * 30 // 最多保留 30 天份的 Log 檔案
)
// .CreateLogger();
.CreateBootstrapLogger();
再將下面的第 2 行刪掉,換成 3 至 10 行,會要這麼麻煩把 WriteTo 的內容再寫一次是因為第一階段的 Log 轉移給第二階段之後就會被完全替換掉,變成新的。所以如果沒有再寫一次的話就會什麼都不輸出...
var builder = WebApplication.CreateBuilder(args);
// builder.Host.UseSerilog();
builder.Host.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Services(services)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File("logs/log-.log",
rollingInterval: RollingInterval.Hour, // 每小時一個檔案
retainedFileCountLimit: 24 * 30 // 最多保留 30 天份的 Log 檔案
)
);
使用設定檔
剛剛有提到從第二階段開始才可以使用設定檔,於是順便紀錄一下設定檔的使用方式和內容增加第 3 行,刪除 6-10 行
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Configuration(context.Configuration) // 從設定檔中讀取
.ReadFrom.Services(services)
.Enrich.FromLogContext()
// .WriteTo.Console()
// .WriteTo.File("logs/log-.log",
// rollingInterval: RollingInterval.Hour, // 每小時一個檔案
// retainedFileCountLimit: 24 * 30 // 最多保留 30 天份的 Log 檔案
// )
);
將設定檔(appsettings.json) 新增以下內容,這些設定值等同於本文最一開始寫在 C# 的 Log 設定內容
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft.AspNetCore": "Warning"
}
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "logs/log-.log",
"rollingInterval": "Hour",
"retainedFileCountLimit": 720
}
}
]
},
"AllowedHosts": "*"
}
延伸閱讀:
ASP.NET Core 實際輸出日誌訊息
參考資料:
Serilog
Serilog.AspNetCore
Serilog.Settings.Configuration
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com