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

如何配置log4net删除N天前日志及按日期和大小滚动日志?

解决log4net日志滚动与旧日志清理的问题

一、配置RollingFileAppender实现日期+大小滚动,每日保留10个1MB日志文件

结合官方示例,我帮你补全并完善了配置,实现同时按日期和文件大小滚动,且每天仅保留10个1MB的日志文件:

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <!-- 日志文件基础命名 -->
  <file value="logfile" />
  <!-- 开启追加模式,不覆盖已有日志 -->
  <appendToFile value="true" />
  <!-- 核心设置:复合滚动模式,同时按日期和文件大小触发滚动 -->
  <rollingStyle value="Composite" />
  <!-- 日期后缀格式,生成如 logfile.20240520.log 的文件名 -->
  <datePattern value=".yyyyMMdd.log" />
  <!-- 同一日期下最多保留10个大小备份文件 -->
  <maxSizeRollBackups value="10" />
  <!-- 单个日志文件的上限大小(1MB) -->
  <maximumFileSize value="1MB" />
  <!-- 禁用静态文件名,让log4net自动生成带日期/序号的动态文件名 -->
  <staticLogFileName value="false" />
  <!-- 保留日志文件的扩展名在末尾,避免出现 logfile.log.20240520 这类格式 -->
  <preserveLogFileNameExtension value="true" />
</appender>

关键配置说明:

  • rollingStyle="Composite":这是实现双维度滚动的核心,让日志既会在每天零点自动切分,也会在单个文件达到1MB时立即滚动。
  • maxSizeRollBackups="10":限制同一天内最多保留10个备份文件,超过数量的旧文件会被自动覆盖。
  • datePattern:定义日期后缀格式,确保每天的日志文件有独立的标识,方便后续清理。

二、实现删除早于N天的日志文件

log4net的RollingFileAppender本身没有自动删除旧日期日志的功能,需要我们手动实现清理逻辑,这里提供两种实用方案:

方案1:应用启动时一次性清理

在应用初始化的代码段(比如ASP.NET的Global.asax、Console程序的Main方法开头)添加清理逻辑,启动时删除指定天数前的日志:

using System.IO;
using System;

public static void CleanExpiredLogs(string logDir, int daysToRetain)
{
    if (!Directory.Exists(logDir)) return;

    var cutoffDate = DateTime.Now.AddDays(-daysToRetain);
    // 匹配所有带日期/序号后缀的日志文件
    var logFiles = Directory.GetFiles(logDir, "logfile.*.log");

    foreach (var filePath in logFiles)
    {
        var fileInfo = new FileInfo(filePath);
        // 按文件最后写入时间判断是否过期
        if (fileInfo.LastWriteTime < cutoffDate)
        {
            try
            {
                File.Delete(filePath);
            }
            catch (IOException ex)
            {
                // 处理文件被占用的情况(比如日志正在写入)
                Console.WriteLine($"无法删除过期日志 {filePath}:{ex.Message}");
            }
        }
    }
}

// 调用示例:保留最近7天的日志
CleanExpiredLogs(AppDomain.CurrentDomain.BaseDirectory, 7);

方案2:定时任务定期清理(适合长期运行的服务)

如果你的应用是Windows服务、ASP.NET Core后台服务这类长期运行的程序,可以添加定时任务,每天自动清理一次旧日志。以ASP.NET Core为例,用IHostedService实现:

using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System;

public class LogCleanupHostedService : IHostedService, IDisposable
{
    private Timer _cleanupTimer;
    private readonly string _logDirectory;
    private readonly int _daysToKeep;

    public LogCleanupHostedService(string logDir, int daysToKeep)
    {
        _logDirectory = logDir;
        _daysToKeep = daysToKeep;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // 设置每天凌晨2点执行清理
        var now = DateTime.Now;
        var firstRun = new DateTime(now.Year, now.Month, now.Day, 2, 0, 0);
        if (now > firstRun) firstRun = firstRun.AddDays(1);
        var initialDelay = firstRun - now;

        _cleanupTimer = new Timer(ExecuteCleanup, null, initialDelay, TimeSpan.FromDays(1));
        return Task.CompletedTask;
    }

    private void ExecuteCleanup(object state)
    {
        CleanExpiredLogs(_logDirectory, _daysToKeep);
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _cleanupTimer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _cleanupTimer?.Dispose();
    }

    // 复用方案1的清理逻辑
    private void CleanExpiredLogs(string logDir, int daysToRetain)
    {
        if (!Directory.Exists(logDir)) return;

        var cutoffDate = DateTime.Now.AddDays(-daysToRetain);
        var logFiles = Directory.GetFiles(logDir, "logfile.*.log");

        foreach (var filePath in logFiles)
        {
            var fileInfo = new FileInfo(filePath);
            if (fileInfo.LastWriteTime < cutoffDate)
            {
                try
                {
                    File.Delete(filePath);
                }
                catch (IOException ex)
                {
                    Console.WriteLine($"清理日志失败:{ex.Message}");
                }
            }
        }
    }
}

// 在Program.cs中注册服务
builder.Services.AddHostedService(provider => 
    new LogCleanupHostedService(AppDomain.CurrentDomain.BaseDirectory, 7));

注意事项:

  • 清理时务必捕获IOException,避免因日志文件被log4net占用导致程序崩溃。
  • 如果你的日志文件名格式和示例不同,需要调整Directory.GetFiles的搜索通配符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:38:41