How copytruncate actually works?

5,413

Truncating a logfile actually works because the writers open the files for writing using O_APPEND.

From the open(2) man page:

O_APPEND: The file is opened in append mode. Before each write(2), the file offset is positioned at the end of the file, as if with lseek(2). The modification of the file offset and the write operation are performed as a single atomic step.

As mentioned, the operation is atomic, so whenever a write is issued, it will append to the current offset matching the end of file, not the one saved before the previous write operation completed.

This makes an append work after a truncate operation, writing the next log line to the beginning of the file again, without the need to reopen the file.

(The same feature of O_APPEND also makes it possible to have multiple writers appending to the same file, without clobbering each other's updates.)

The loggers also write a log line using a single write(2) operation, to prevent a log line from being broken in two during a truncate or concurrent write operation.

Note that loggers like syslog, syslog-ng or rsyslog typically don't need to use copytruncate since they have support to reopen the log files, usually by sending them a SIGHUP. logrotate's support for copytruncate exists to cater for other loggers which typically append to logfiles but that don't necessarily have a good way to reopen the logfile (so rotation by renaming doesn't work in those cases.)

Please note also that copyrotate has an inherent race condition, in that it's possible that the writer will append a line to the logfile just after logrotate finished the copy and before it has issued the truncate operation. That race condition would cause it to lose those lines of log forever. That's why rotating logs using copytruncate is usually not recommended, unless it's the only possible way to do it.

Share:
5,413

Related videos on Youtube

overexchange
Author by

overexchange

Updated on September 18, 2022

Comments

  • overexchange
    overexchange over 1 year

    we would like to understand copytruncate before rotating the file using logrotate with below configuration:

    /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 RAM, 4 VCpu

    Question:

    How does logrotate truncate the file, when syslog-NG already opened file for logging? Is it not the contention of resource? Does syslog-NG close the file immediately, when it has nothing to log?

    • Admin
      Admin over 5 years
      @JeffSchaller May I know the reason for this query tagged opinion-based?
    • Admin
      Admin almost 3 years
      This question originally asked about the ideal logfile size for rotation, which is why it got closed as "opinion-based". That part of the question is no longer there, so I'm reopening it.