在使用以下配置copytruncate
旋转文件之前, 我们想了解一下:logrotate
/app/syslog-ng/custom/output/all_devices.log {
size 200M
copytruncate
dateext
dateformat -%Y%m%d-%s
rotate 365
sharedscripts
compress
postrotate
/app/syslog-ng/sbin/syslog-ng-ctl reload
endscript
}
RHEL 7.x,8GB 内存,4 个 VCpu
问题:
logrotate
当 syslog-NG 已经打开文件进行日志记录时,如何截断文件?不是资源争夺吗?syslog-NG 是否会在没有任何要记录的内容时立即关闭文件?
截断日志文件实际上是有效的,因为编写者使用 O_APPEND 打开要写入的文件。
从open(2)手册页:
如前所述,操作是原子的,因此每当发出写入操作时,它都会附加到与文件末尾匹配的当前偏移量,而不是在前一个写入操作完成之前保存的偏移量。
这使得在截断操作之后追加工作,将下一个日志行再次写入文件的开头,而无需重新打开文件。
(O_APPEND 的相同功能还可以让多个写入者附加到同一个文件,而不会破坏彼此的更新。)
记录器还使用单个 write(2) 操作写入日志行,以防止在截断或并发写入操作期间将日志行分成两部分。
请注意,像 syslog、syslog-ng 或 rsyslog 这样的记录器通常不需要使用
copytruncate
,因为它们支持重新打开日志文件,通常通过向它们发送 SIGHUP。logrotate 对存在的支持copytruncate
是为了迎合其他记录器,这些记录器通常附加到日志文件,但不一定有重新打开日志文件的好方法(因此在这些情况下通过重命名进行轮换不起作用。)另请注意,它
copyrotate
具有固有的竞争条件,因为在 logrotate 完成复制之后和发出截断操作之前,作者可能会在日志文件中附加一行。这种竞争条件会导致它永远失去那些日志行。copytruncate
这就是为什么通常不推荐使用旋转日志的原因,除非这是唯一可行的方法。