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

NLog每日日志文件:如何在触发或创建时添加统计摘要

嘿,看起来你正在用NLog配置每日日志归档呢!咱们一个个来解决你的问题:

1. 新日志文件创建时添加「摘要」

要在新日志文件生成时插入自定义摘要,分两种场景来实现,都很灵活:

场景A:在每日新主日志(比如PDF.log)开头加摘要

如果希望每天新生成的PDF.log开头自带摘要(比如当日日期、日志用途说明),直接给FileTarget配置header属性就行,用NLog的布局渲染器动态生成内容:

<target xsi:type="File" name="ErrorLog" 
        filename="${logDirectory}PDF.log" 
        archiveFileName="log.{#}.log" 
        archiveNumbering="Date" 
        archiveEvery="Day" 
        archiveDateFormat="yyyyMMdd"
        header="=== 日志摘要:${date:format=yyyy-MM-dd} 系统PDF操作日志开始记录 ===" />

要是你需要更复杂的摘要(比如前一天的错误日志统计),那就得通过代码监听NLog的归档事件,在归档完成后往新日志里写入自定义内容:

// 先找到你配置的FileTarget实例
var errorLogTarget = LogManager.Configuration.FindTargetByName<FileTarget>("ErrorLog");

// 监听归档完成事件——这时候新的主日志文件已经创建好了
errorLogTarget.Archive += (sender, e) =>
{
    // 渲染出当前主日志文件的路径
    var newLogFilePath = errorLogTarget.FileName.Render(new LogEventInfo());
    // 写入自定义摘要到文件开头
    File.AppendAllText(newLogFilePath, $"=== 昨日错误日志统计:共XX条异常记录 ===" + Environment.NewLine);
};

场景B:在归档后的日志文件(比如log.20240520.log)里加摘要

如果要给每天归档好的历史日志文件加摘要,同样用Archive事件,在归档完成后直接修改归档文件:

errorLogTarget.Archive += (sender, e) =>
{
    // e.ArchiveFileName就是刚归档好的历史日志路径
    var archivedLogPath = e.ArchiveFileName;
    // 在文件末尾追加摘要内容
    File.AppendAllText(archivedLogPath, $"{Environment.NewLine}=== 日志摘要:当日共处理XX次PDF操作 ===");
};
2. 当日日志文件末尾添加每日日志「计数」:完全可行!

这个需求可以通过“日志计数+归档时写入”两步实现:

  1. 维护一个线程安全的计数器:每次有日志写入时,递增当日的计数(要考虑多线程场景,所以用ConcurrentDictionary):
// 按日期存储当日日志计数,保证线程安全
private static readonly ConcurrentDictionary<string, int> DailyLogCounter = new ConcurrentDictionary<string, int>();

// 给目标添加PreWrite事件,每次日志写入前更新计数
var target = LogManager.Configuration.FindTargetByName<FileTarget>("ErrorLog");
target.PreWrite += (sender, e) =>
{
    var todayKey = DateTime.Now.ToString("yyyyMMdd");
    // 计数不存在就设为1,存在就加1
    DailyLogCounter.AddOrUpdate(todayKey, 1, (key, currentCount) => currentCount + 1);
};
  1. 归档时写入计数到日志末尾:结合归档事件,把当日的计数写入刚归档好的日志文件末尾:
target.Archive += (sender, e) =>
{
    // 归档的是前一天的日志,所以取昨天的日期键
    var yesterdayKey = DateTime.Now.AddDays(-1).ToString("yyyyMMdd");
    if (DailyLogCounter.TryGetValue(yesterdayKey, out int totalCount))
    {
        // 写入计数到归档文件末尾
        File.AppendAllText(e.ArchiveFileName, $"{Environment.NewLine}=== 当日日志计数:共 {totalCount} 条记录 ===");
        // 写完后移除旧的计数,避免占用内存
        DailyLogCounter.TryRemove(yesterdayKey, out _);
    }
};
3. 如何知晓新日志何时触发?

你可以通过监听NLog的这两个事件来精准感知新日志的创建时机:

  • FileTarget.Archive事件:这是最直接的——当NLog完成每日归档、准备创建新的主日志文件时会触发这个事件,完美对应“新日志开始”的时刻。
  • FileTarget.OpenFile事件:每次日志文件被打开(包括新创建的文件)时触发,你可以通过判断文件的创建日期来识别是不是当日的新日志:
target.OpenFile += (sender, e) =>
{
    var logFileInfo = new FileInfo(e.FileName);
    if (logFileInfo.CreationTime.Date == DateTime.Now.Date)
    {
        // 这里就是新日志文件刚被创建/打开的时刻
        Console.WriteLine($"新的每日日志已创建:{e.FileName}");
    }
};

要是你用的是NLog 4.7及以上版本,还能借助NLog.Extensions.Logging的扩展能力,但上面的代码方式已经足够灵活好用啦。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:37:34