C# ASP.NET Core 6 依照功能拆分 Serilog 套件輸出的 log 檔案

所有 log 都混雜在同一個檔案中,每次尋找都很不方便,有沒有辦法將 log 檔案拆分,不同的功能寫入不同的檔案呢?當然可以,而且十分的簡單!

筆者之前寫了一篇文章 最詳細 ASP.NET Core 使用 Serilog 套件寫 log 教學 ,本文的範例是接續那篇文章完成「兩階段初始化」後的。

需要先使用 NuGet 安裝 Serilog.AspNetCore ,需要 .NET Core 3 或以上
    
dotnet add package Serilog.AspNetCore
    

原本的 log 設定如下,會將 log 放置在 logs 資料夾中,檔名會加上日期時間,檔名範例: log-2023072423.log
    
var builder = WebApplication.CreateBuilder(args);

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 檔案
    )
);
    

假設現在加了一個 UserController ,在裡面有寫 log:
    
using Microsoft.AspNetCore.Mvc;

namespace WebApplicationSerilogTest.Controllers;

[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
    private readonly ILogger<UserController> _logger;

    public UserController(ILogger<UserController> logger)
    {
        _logger = logger;
    }

    [HttpGet("/api/user")]
    public ActionResult Get()
    {
        _logger.LogInformation("Get user");
        return Ok(
            new
            {
                Id = 1,
                Name = "Ruyut"
            }
        );
    }
}
    

在上面 Serilog 設定的情況下,所有 log 都會寫入同一個檔案。如果要將 UserController 的 log 額外寫入 api 開頭的檔案可以這樣做:
    
var builder = WebApplication.CreateBuilder(args);

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 檔案
    )
    .WriteTo.Logger(loggerConfiguration => loggerConfiguration
        .Filter.ByIncludingOnly(Matching.FromSource("WebApplicationSerilogTest.Controllers.UserController"))
        .WriteTo.File("logs/api-.log",
            rollingInterval: RollingInterval.Hour, // 每小時一個檔案
            retainedFileCountLimit: 24 * 30 // 最多保留 30 天份的 Log 檔案
        )
    )
);
    

除了原先的 log-2023072423.log 檔案中會有 UserController 的 log 以外,UserController 的 log 也會被寫入剛剛設定的 api log 中,檔名範例: api-2023072423.log
註: 本文的專案名稱為 WebApplicationSerilogTest ,此 UserController 的 namespace 是 WebApplicationSerilogTest.Controllers

如果在原先的 log 中不想要紀錄 UserController 的 log,只要在 api log 中出現就好,那可以這樣排除:
    
var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog((context, services, configuration) => configuration
    .ReadFrom.Services(services)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.Logger(loggerConfiguration => loggerConfiguration
        .Filter.ByExcluding(Matching.FromSource("WebApplicationSerilogTest.Controllers.UserController"))
        .WriteTo.File("logs/log-.log",
            rollingInterval: RollingInterval.Hour, // 每小時一個檔案
            retainedFileCountLimit: 24 * 30 // 最多保留 30 天份的 Log 檔案
        )
    )
    .WriteTo.Logger(loggerConfiguration => loggerConfiguration
        .Filter.ByIncludingOnly(Matching.FromSource("WebApplicationSerilogTest.Controllers.UserController"))
        .WriteTo.File("logs/api-.log",
            rollingInterval: RollingInterval.Hour, // 每小時一個檔案
            retainedFileCountLimit: 24 * 30 // 最多保留 30 天份的 Log 檔案
        )
    )
);
    

留言