When an active process like Apache HTTP Server keeps writing to log files (e.g., access_log, error_log), traditional file deletion methods (rm
) or truncation (> file.log
) can cause issues. The process maintains its own file handle, meaning:
# Dangerous approach (don't do this):
$ rm /var/log/apache2/access_log
# Or
$ > /var/log/apache2/access_log
These methods appear to work initially but can lead to:
- Apache continuing to write to the now-invisible deleted file
- Disk space not being freed until Apache restarts
- Potential log corruption in some cases
Method 1: Using truncate()
The safest approach is to use the truncate operation while preserving the file handle:
$ sudo truncate -s 0 /var/log/apache2/access_log
This:
- Maintains the same inode
- Keeps file permissions intact
- Immediately frees disk space
Method 2: Log Rotation (Recommended)
A more sustainable solution involves using logrotate:
# /etc/logrotate.d/apache2
/var/log/apache2/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
}
Key advantages:
- Automated rotation
- Compression of old logs
- Proper signal handling with reload (not restart)
Method 3: Copy-Truncate Pattern
For systems without logrotate:
$ sudo cp /dev/null /var/log/apache2/access_log
# Or alternatively
$ : > /var/log/apache2/access_log
After truncation, verify with:
$ sudo lsof | grep access_log
$ df -h
$ ls -li /var/log/apache2/access_log # Check inode
When dealing with large-scale deployments:
- Consider log shipping solutions for centralized logging
- For high-traffic sites, rotate more frequently than daily
- Monitor inode usage along with disk space
When dealing with production servers, we often encounter situations where log files grow uncontrollably while being actively written to by processes like Apache HTTPD. Simply deleting access_log
or error_log
through rm
won't free up disk space because the file handle remains open by the Apache process.
In Unix/Linux systems, when a process opens a file, it maintains a file descriptor pointing to the file's inode. The actual disk space isn't released until all references to that inode are closed - even if the directory entry is removed.
Here are three reliable methods to handle active log files:
1. Using logrotate with copytruncate
The safest approach is configuring /etc/logrotate.d/apache2
with:
/var/log/apache2/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
copytruncate
}
The copytruncate
option copies the log file then truncates the original, rather than moving and recreating it.
2. Manual Truncation with :> Operator
For immediate needs, you can use Bash's truncation operator:
:> /var/log/apache2/access.log
This empties the file while maintaining the same inode and file handle.
3. Using fallocate for Large Files
For extremely large files (10GB+), fallocate
is more efficient:
fallocate -c -l 0 /var/log/apache2/access.log
Avoid these common mistakes:
- Directly deleting the log file (
rm access.log
) - doesn't free space - Restarting Apache - causes service interruption
- Using
echo "" > file.log
- doesn't completely truncate
Implement proactive monitoring with a script like:
#!/bin/bash
THRESHOLD=90
CURRENT=$(df / | grep / | awk '{print $5}' | sed 's/%//g')
if [ "$CURRENT" -gt "$THRESHOLD" ]; then
:> /var/log/apache2/access.log
logger "Apache log truncated due to disk space threshold"
fi