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. 当日日志文件末尾添加每日日志「计数」:完全可行!
这个需求可以通过“日志计数+归档时写入”两步实现:
- 维护一个线程安全的计数器:每次有日志写入时,递增当日的计数(要考虑多线程场景,所以用
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); };
- 归档时写入计数到日志末尾:结合归档事件,把当日的计数写入刚归档好的日志文件末尾:
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
相关产品推荐
相关产品推荐

