You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 5控制台应用使用Serilog实现多日志文件独立输出方案

.NET 5控制台应用基于Serilog实现多独立文件日志输出

原场景与问题

我有一个安装了Serilog NuGet包的.NET 5.0控制台应用,appsettings.json中Serilog相关初始配置如下:

"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"WriteTo": [
  {
    "Name": "Console",
    "Args": {
      "outputTemplate": "[{Timestamp:HH:mm:ss.fff} [{Level}] {SourceContext} {Message}{NewLine}{Exception}",
      "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
    }
  },
  {
    "Name": "File",
    "Args": {
      "path": "/Logs/SharedTreatment_logs.txt",
      "outputTemplate": "{Timestamp:G} {SourceContext} [{Level}] {Message}{NewLine:1}{Exception:1}",
      "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
      "fileSizeLimitBytes": 1000000,
      "rollOnFileSizeLimit": "true",
      "shared": "true",
      "flushToDiskInterval": 3
    }

  }
]

配置加载代码如下:

Serilog.Debugging.SelfLog.Enable(Console.Error);

var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();

var logger = loggerConfiguration.ReadFrom.Configuration(configuration).CreateLogger();

Log.Logger = logger?.ForContext<T>() ?? throw new ArgumentNullException(nameof(logger));

Host.CreateDefaultBuilder(args).UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration))

项目内每个类都通过依赖注入获取ILogger实例,例如ILogger<MyClass> logger。需求是:如何在这类类中创建新的日志器,读取appsettings.json中的其他日志配置段,将日志输出到另一个独立文件中?

已验证的实现方案

经过测试,通过子日志器+属性过滤的方案可以实现需求,思路是创建两个子日志器,一个用于主日志记录,过滤排除带指定属性的日志输出到原有文件,另一个仅收录带指定属性的日志输出到新文件。

更新后的配置

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
    "MinimumLevel": "Debug",
    "Enrich": [ "FromLogContext" ],
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "outputTemplate": "[{Timestamp:HH:mm:ss.fff} [{Level}] {SourceContext} {Message}{NewLine}{Exception}",
          "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "@p['LogToFile']"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/SharedTreatment_logs_Second.txt",
                  "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
                }
              }
            ]
          }
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByExcluding",
                "Args": {
                  "expression": "@p['LogToFile']"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/SharedTreatment_logs.txt",
                  "outputTemplate": "{Timestamp:G} {SourceContext} [{Level}] {Message}{NewLine:1}{Exception:1}",
                  "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
                  "fileSizeLimitBytes": 1000000,
                  "rollOnFileSizeLimit": "true",
                  "shared": "true",
                  "flushToDiskInterval": 3
                }
              }
            ]
          }
        }
      }
    ]
  }
}

调用代码

static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
    Log.Logger = new LoggerConfiguration().DefaultLoggerSetup<Program>();
    using (LogContext.PushProperty("LogToFile", true))
    {
        Log.Information("LogToFileTest");
    }

    Log.Information("Just log");
    Log.CloseAndFlush();
}

该方案运行后会成功生成两个日志文件,日志按照过滤规则输出到对应文件中。

方案优化建议

你当前的实现是Serilog多输出场景下的标准可行方案,针对不同使用场景可以做进一步优化:

  • 如果独立日志按业务模块/类区分,不需要手动控制单条日志的输出目标,可以直接在过滤器中匹配SourceContext(类名/命名空间),不需要手动PushProperty打标记,配置更简洁,比如过滤表达式写StartsWith(SourceContext, 'MyApp.SpecialBusiness')即可将指定命名空间下所有类的日志输出到独立文件。
  • 如果两个日志体系完全独立,不需要共享公共配置,可以单独注册一个独立的ILogger实例到DI容器,直接读取appsettings中单独的配置段(比如命名为Serilog:SecondLogger),需要使用独立日志的类直接注入该实例即可,完全和主日志隔离。

内容的提问来源于stack exchange,提问作者Banshee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:24:04