Copytruncate 实际上是如何工作的?

Copytruncate 实际上是如何工作的?

在使用以下配置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通常不建议使用旋转日志,除非这是唯一可能的方法。

相关内容