NLog按日期滚动最直接,需设archiveEvery="Day"且enableArchiveFileCompression="false";Serilog按大小滚动更可控,须设rollOnFileSizeLimit=true和fileSizeLimitBytes;手动实现需避免FileStream锁与时钟误差。
用
配置按日期滚动最直接
绝大多数 C# 项目不需要手写滚动逻辑,
内置的
支持开箱即用的日期滚动。关键不是“能不能”,而是“怎么配不踩坑”。
常见错误是只设
却没关掉
(默认为
),结果每天生成一堆
文件而非纯文本,排查日志时反而更麻烦。
推荐配置片段:
:旧文件编号递增(
,
…),比
模式更易脚本清理
:硬性限制归档数,否则磁盘可能被撑爆——这是生产环境最容易被忽略的点
路径中避免使用
做
,会导致日志写入失败(NLog 不支持在主文件名里动态插日期)
用
+
按大小切分更可靠
按大小滚动比按日期更可控,尤其适合高吞吐服务。Serilog 的
默认就支持,但默认行为容易误导人。
它不叫“按大小滚动”,而叫“按文件大小限制 + 自动重命名”。关键参数是
和
,但真正触发切割的是
。
示例代码:
必须显式开启,否则即使设了
也无效
是保留的**总文件数**(当前 + 归档),不是“最多存 7 天”——这点文档写得模糊,实际测试会发现第 8 个归档产生时,最老的就被删了
归档文件名形如
或
,取决于
设置;若只想按大小切、不掺日期,设成
即可
手动实现滚动要绕开
锁和时间判断误差
真要自己写(比如嵌入式场景或规避第三方依赖),核心难点不在逻辑,而在两个地方:
的独占锁导致无法安全重命名正在写的文件;以及服务器时钟跳变让“是否跨天”判断出错。
解决方案不是修判断,而是换思路:
C知道
CSDN推出的一款AI技术问答工具
下载
用
前先
,别试图在流开着时移动文件
不依赖
判断是否换日,改用“记录上一次滚动时间戳 + 24 小时检查”,避免 NTP 校时或夏令时导致误切
大小判断别用
(可能因缓存不准),而是在每次
后累加已写字节数,更实时
一句话:手动滚动不是“写个计时器+判断大小”,而是“管好文件句柄生命周期 + 用增量计数替代查询”。
的
容易卡在
老项目还在用
的话,
的
是开关,但默认是
——这意味着即使你配了
,它也只写一个文件,不滚动。
典型错误配置:
缺了
,上面配置完全无效。加上之后还要注意:
中的
会被当字面量,所以
生成的是
,而不是
。
真正想按日期生成
,得把
设为空,靠
构建完整文件名,且必须配合
。
滚动逻辑本身不复杂,难的是边界:文件锁、时钟漂移、归档清理策略、压缩与可读性的权衡。选库时别只看“支持滚动”,要看它默认行为是否贴合你的运维习惯。
NLogNLogFileTargetarchiveEvery="Day"enableArchiveFileCompression="false"true.ziparchiveNumbering="Rolling"app.1.logapp.2.logDatemaxArchiveFiles="30"${date:format=yyyy-MM-dd}fileNameSerilogFile sinkSerilog.Sinks.FilerollingIntervalretainedFileCountLimitfileSizeLimitBytesLog.Logger = new LoggerConfiguration()
.WriteTo.File("logs/app.log",
fileSizeLimitBytes: 10_485_760, // 10MB
rollOnFileSizeLimit: true,
retainedFileCountLimit: 7,
rollingInterval: RollingInterval.Day) // 这个值其实不影响大小滚动,仅用于命名后缀
.CreateLogger();rollOnFileSizeLimit: truefileSizeLimitBytesretainedFileCountLimit: 7app.log.20240520.txtapp.log.1.txtrollingIntervalRollingInterval.InfiniteFileStreamFileStreamFile.Move()stream.Dispose()DateTime.Now.DateFileInfo.LengthWriteLinelog4netRollingFileAppenderStaticLogFileNamelog4netRollingFileAppenderStaticLogFileName="false"truedatePattern
datePattern..yyyy-MM-ddapp.log.2024-05-20app.2024-05-20.logapp.YYYY-MM-DD.logdatePatternstaticLogFileName="false"