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

Serilog运行时删除日志文件后无法重建,如何强制其重新创建日志文件?

问题根因

  1. 你的日志写入逻辑存在错误:Log.CloseAndFlush()是程序终止前用来释放日志资源的方法,不能每次写完日志就调用。调用该方法后全局Log.Logger实例会被标记为已释放,后续所有写入操作都会直接失效,这是你删除文件后无法写入的核心原因之一。
  2. Serilog.File Sink默认会持有日志文件的独占句柄,手动删除日志文件后,Sink无法感知到文件已被删除,仍然会向已失效的句柄写入内容,不会主动创建新文件。

解决方案

方案1(推荐):修复写法+添加自动重建参数

首先删掉每次写日志后的Log.CloseAndFlush()调用,该方法仅需在程序完全退出前执行一次。同时在File Sink配置中添加recreateOnMissing: true参数,该参数专门用于处理日志文件被外部删除后自动重建的场景。
修改后完整代码如下:

public static class Logger
{
    // 程序启动时调用一次即可,无需重复初始化
    public static void ConfigureSerilog()
    {
        var logFile = Path.Combine(Environment.GetFolderPath(
        Environment.SpecialFolder.ApplicationData), "OSync\\OSync.log");

        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.File(logFile, 
                rollingInterval: RollingInterval.Day, 
                fileSizeLimitBytes: 2097152, 
                retainedFileCountLimit: 7,
                // 新增参数:文件被删除后自动重建
                recreateOnMissing: true)
            .CreateLogger();
    }

    public static void Write(LogEventLevel logEvent, string message)
    {
        Log.Write(logEvent, message);
        // 若需要实时落盘可以在这里调用Log.Flush(),不要调用CloseAndFlush
    }

    // 程序退出时调用一次即可
    public static void CloseLogger()
    {
        Log.CloseAndFlush();
    }
}

如果你的Serilog.Sinks.File版本较低没有recreateOnMissing参数,直接将该Nuget包升级到最新版即可。

方案2:写入前校验文件状态动态重置

如果不想升级依赖包,可以在写入日志前判断日志文件是否存在,不存在就重新初始化Logger,适合低版本兼容场景:

public static class Logger
{
    // 提前缓存日志路径避免重复拼接
    private static readonly string _logPath = Path.Combine(Environment.GetFolderPath(
        Environment.SpecialFolder.ApplicationData), "OSync\\OSync.log");

    public static void ConfigureSerilog()
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.File(_logPath, 
                rollingInterval: RollingInterval.Day, 
                fileSizeLimitBytes: 2097152, 
                retainedFileCountLimit: 7)
            .CreateLogger();
    }

    public static void Write(LogEventLevel logEvent, string message)
    {
        // 文件不存在就重新初始化Logger
        if (!File.Exists(_logPath))
        {
            ConfigureSerilog();
        }
        Log.Write(logEvent, message);
    }
}

注意该方案需要自行处理多线程并发问题,避免多个线程同时重置Logger导致异常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:36:03