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

.NET Core 3.1控制台应用Serilog WriteTo.File不生效无报错问题

问题根因
  • 未释放日志资源:Serilog的File Sink默认采用缓冲写入机制,日志不会实时落盘,程序退出前如果不主动执行刷新操作,缓冲区中未写入磁盘的日志会全部丢失,且不会抛出任何异常。
  • 配置项拼写错误:appsettings.json中Serilog的最低日志级别配置项误写为MinimalLevel,正确键名为MinimumLevel,拼写错误会导致配置读取逻辑异常,干扰Sink初始化流程。
  • 静态Logger实例被覆盖:调用Host.CreateDefaultBuilder().UseSerilog()时,默认会重新构建Logger实例替换你之前手动初始化的全局Log.Logger,而你的配置文件中没有配置File Sink写入规则,替换后的Logger仅保留控制台输出能力。
  • 日志路径认知偏差:代码中传入的是相对路径log.txt,日志文件不会生成在项目源码目录,默认会生成在程序运行时的工作目录(调试状态下为bin/Debug/netcoreapp3.1/目录),找错路径会误以为文件未生成。
  • 运行时错误被吞:Serilog默认会捕获Sink运行时的非致命错误(比如目录无写入权限、文件被占用),不会向外抛出异常打断主程序运行,没有开启SelfLog时很难直接感知到错误。
修复方案
  1. 修正appsettings.json中的配置拼写错误,修正后的配置如下:
{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Error",
        "System": "Error"
      }
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "DataSource=app.db;Cache=Shared"
  }
}
  1. 调整Host构建逻辑,避免手动初始化的Logger被覆盖,同时显式指定日志文件的绝对路径,避免找错文件位置:
static IHost AppStartup()
{
    var builder = new ConfigurationBuilder();
    BuildConfig(builder);
    var config = builder.Build();

    // 提前创建日志存放目录,避免目录不存在导致写入失败
    var logPath = Path.Combine(AppContext.BaseDirectory, "logs");
    Directory.CreateDirectory(logPath);

    Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(config)
            .MinimumLevel.Information()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Error)
            .MinimumLevel.Override("System", LogEventLevel.Error)
            .Enrich.FromLogContext()
            .WriteTo.Console()
            .WriteTo.File(
                path: Path.Combine(logPath, "log.txt"),
                rollingInterval: RollingInterval.Day,
                fileSizeLimitBytes: 10 * 1024 * 1024,
                rollOnFileSizeLimit: true,
                retainedFileCountLimit: 30
            )
            .CreateLogger();

    Log.Logger.Information("Application Starting");

    var host = Host.CreateDefaultBuilder()
                .ConfigureServices((context, services) => { 

                })
                // 传入preserveStaticLogger: true,保留手动初始化的全局Logger,不被Host构建流程覆盖
                .UseSerilog(Log.Logger, preserveStaticLogger: true)
                .Build();

    return host;
}
  1. 修正Main方法逻辑,在程序退出前强制刷新日志缓冲区,确保所有日志落盘:
static void Main(string[] args)
{
    try
    {
        var host = AppStartup();
        Log.Warning("test log");
        Console.ReadKey();
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "Application start-up failed");
    }
    finally
    {
        // 释放日志资源,强制将缓冲区日志写入磁盘
        Log.CloseAndFlush();
    }
}
  1. (可选排查项)如果修复后仍无法写入,可开启Serilog的SelfLog查看内部报错,在初始化Logger前加如下代码:
Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine($"Serilog内部错误: {msg}"));

启动后控制台会输出Serilog运行时的内部错误,可直接定位是权限、文件占用还是其他问题。

修复完成后启动程序,到程序输出目录(bin/Debug/netcoreapp3.1/)下的logs文件夹即可看到按日期滚动生成的日志文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:51:12