When running Tomcat servers, the built-in FastCommonAccessLogValve
handles basic log rotation but lacks advanced log management features. Many administrators need automated compression and cleanup without interfering with Tomcat's native rotation mechanism.
While find
commands in cron jobs work, they create maintenance overhead. Logrotate offers:
- Centralized configuration for all logs
- Better error handling and logging
- Standardized compression options
- Conditional execution scripts
Here's a working configuration that compresses and cleans Tomcat access logs without rotation:
/var/log/tomcat/access.log {
# Disable rotation (Tomcat handles this)
rotate 0
# Compression settings
compress
compresscmd /bin/gzip
compressext .gz
compressoptions -9
# Cleanup old logs
maxage 30
missingok
# Post-compression hook (optional)
sharedscripts
postrotate
# Verify Tomcat is running before touching logs
if [ -f /var/run/tomcat.pid ]; then
kill -USR1 cat /var/run/tomcat.pid >/dev/null 2>&1
fi
endscript
}
For more control, consider these additional parameters:
# Additional compression optimization
delaycompress
dateext
dateformat -%Y%m%d
# Size-based cleanup (alternative to maxage)
maxsize 100M
1. Save the configuration to /etc/logrotate.d/tomcat
2. Test with debug mode:
logrotate -d /etc/logrotate.d/tomcat
3. Force immediate execution:
logrotate -vf /etc/logrotate.d/tomcat
Check logrotate's own logs for issues:
grep logrotate /var/log/syslog
Common pitfalls include:
- Permission issues (run as correct user)
- SELinux context mismatches
- Disk space monitoring during compression
When working with Tomcat's FastCommonAccessLogValve, we encounter a common infrastructure challenge: while the valve handles daily log rotation
effectively, it lacks built-in support for log compression
and retention management
. This leaves sysadmins with two suboptimal choices:
# Current approach using find
0 2 * * * find /var/log/tomcat/ -name "access_log.*" -mtime +30 -exec gzip {} \;
0 3 * * * find /var/log/tomcat/ -name "access_log.*.gz" -mtime +90 -delete
Using logrotate
instead of custom cron jobs offers several advantages:
- Centralized log management configuration
- Standardized compression behavior
- Better integration with system monitoring
- More sophisticated rotation schemes if needed later
Here's how to configure logrotate to work with Tomcat's existing rotation while adding compression and cleanup:
/var/log/tomcat/access_log.* {
daily
missingok
nodelaycompress
compress
delaycompress
notifempty
sharedscripts
postrotate
/bin/kill -HUP cat /var/run/tomcat.pid 2>/dev/null 2>/dev/null || true
endscript
maxage 30
rotate 0
}
rotate 0: This is the crucial parameter that tells logrotate not to perform any rotation, since Tomcat's valve already handles this.
nodelaycompress + delaycompress: These might seem contradictory but work together - immediate compression of older logs while leaving the most recent one uncompressed.
maxage 30: Automatically removes logs older than 30 days, solving the cleanup requirement.
To test your configuration without waiting for the daily cron:
# Force logrotate to run with debug output
logrotate -d /etc/logrotate.d/tomcat
# Execute a dry run
logrotate -v /etc/logrotate.d/tomcat
For production environments, consider adding these monitoring checks:
# Check if logrotate ran successfully
grep "logrotate" /var/log/syslog | tail -n 5
# Verify compressed files exist
ls -lh /var/log/tomcat/access_log.*.gz
For those preferring a Java solution, you could implement a custom valve extending AccessLogValve:
public class CompressingAccessLogValve extends AccessLogValve {
@Override
protected synchronized void close(boolean rename) {
super.close(rename);
if (rename) {
// Add compression logic here
Path logFile = Paths.get(getDirectory(), getFilename());
compressLogFile(logFile);
}
}
private void compressLogFile(Path logFile) {
// Implementation using GZIPOutputStream
}
}
However, this approach requires more maintenance and lacks the system-wide consistency of logrotate.