在使用以下配置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
问题:
当 syslog-NG 已经打开文件进行日志记录时,如何logrotate
截断文件?这不就是资源的争夺吗?当没有任何内容可记录时,syslog-NG 是否会立即关闭该文件?
答案1
截断日志文件实际上是有效的,因为编写者使用 O_APPEND 打开文件进行写入。
来自打开(2)手册页:
O_APPEND:文件以附加模式打开。在每次 write(2) 之前,文件偏移量位于文件末尾,就像 lseek(2) 一样。文件偏移量的修改和写入操作作为单个原子步骤执行。
如前所述,该操作是原子的,因此每当发出写入时,它都会附加到当前的与文件末尾匹配的偏移量,而不是上一写入操作完成之前保存的偏移量。
这使得追加在截断操作后起作用,再次将下一个日志行写入文件的开头,而无需重新打开文件。
(O_APPEND 的相同功能还使得多个写入器可以追加到同一个文件,而不会破坏彼此的更新。)
记录器还使用单个 write(2) 操作写入日志行,以防止日志行在截断或并发写入操作期间被分成两部分。
请注意,像 syslog、syslog-ng 或 rsyslog 这样的记录器通常不需要使用,copytruncate
因为它们支持重新打开日志文件(通常通过向它们发送 SIGHUP)。 logrotate 对copytruncate
存在的支持是为了满足其他记录器的需求,这些记录器通常会附加到日志文件,但不一定有重新打开日志文件的好方法(因此通过重命名进行轮换在这些情况下不起作用。)
另请注意,它copyrotate
具有固有的竞争条件,因为编写者可能会在 logrotate 完成复制之后和发出截断操作之前将一行追加到日志文件中。这种竞争条件将导致它永远丢失这些日志行。这就是为什么copytruncate
通常不建议使用旋转日志,除非这是唯一可能的方法。