A file's content is only deleted when there is no reference to it anymore. A reference to a file can be a directory entry or an open file handle. When you remove a file (e.g. with the rm
command) that a process still has open (here, the process that's logging to it), the file's content remains until the process closes the file.
The most straightforward way to get rid of old logs is to
- Move the file to another name, e.g.
mv foo.log foo.log.old
- Instruct the process to reopen its log file. If the process has no way to do that, restart it.
- Delete the now-closed old log file (
rm foo.log.old
).
The program logrotate automates this mechanism and can be configured as to how many days of old logs to keep around. It can also compress old logs.
For step 2, if you can't restart the program and it doesn't have a way to reopen its log file, you can try forcibly making it reopen the log file with a debugger. However, beware that this can crash the program if it keeps information about the log file that's now become inconsistent. Proof-of-concept (beware that lots of things can go wrong with this; if in doubt, just don't do it):
gdb -n $pid -batch -x /dev/stdin <<EOF
call close(2)
call open("/path/to/foo.log", 1)
EOF
An alternative crude method to free some disk space if you don't care about any of the logs is to truncate the file. The logging process will keep writing at the same position in the file, but the file will become a sparse file. If you read from the file from the beginning, you'll get null bytes, but these null bytes only occupy a few kB on the disk.
dd if=/dev/null of=/path/to/foo.log