Logrotate Configuration Mastery: Automating Linux Log Management
Master logrotate configuration to automate Linux log management. Prevent disk overflow and optimize server storage with these practical, hands-on techniques.
Last month, a rogue microservice started dumping stack traces into a single log file at a rate of 2GB per hour. By the time the alerts fired, we had roughly 40GB of logs consumed, and the partition was screaming for mercy. It’s a classic production nightmare that reminds you why solid log management isn't just "nice to have"—it's a requirement for uptime.
If you’re running high-traffic services, you know that disk space optimization isn't just about deleting old files. It's about having a deterministic, automated system that handles rotation, compression, and cleanup without human intervention.
Understanding the Logrotate Configuration Logic
At its core, logrotate is a state machine triggered by cron. It reads configuration files—usually located in /etc/logrotate.d/—and performs actions based on file size, age, or time.
The biggest mistake I see engineers make is relying on the default /etc/logrotate.conf without tailoring it to specific application needs. For a high-traffic app, the default daily rotation is often too slow. You need to move to size-based rotation.
Here is a standard configuration block I use for most of my production services:
Bash/var/log/myapp/*.log { size 100M rotate 7 compress delaycompress missingok notifempty copytruncate su root root }
Let’s break down why this specific setup matters:
size 100M: This forces a rotation once the file hits 100MB, regardless of the time. It’s the most important directive for preventing sudden disk overflow.copytruncate: This is a lifesaver. Instead of closing and reopening the log file (which requires application support),logrotatecopies the current log to a new file and then truncates the original. It’s safer for legacy apps that don't handle signal-based log re-opening well.delaycompress: This keeps the most recent rotated log uncompressed for a cycle. It makes debugging much faster because you don't have togunzipa file just to see the last few entries.
When copytruncate isn't enough
While copytruncate is convenient, it’s not perfect. In high-concurrency environments, you might lose a few milliseconds of log data during the copy-and-truncate window. If you need absolute precision, you have to implement signal-based rotation.
Most modern services (like Nginx or custom Go apps) support SIGHUP. You can replace copytruncate with postrotate scripts:
Bash/var/log/myapp/app.log { daily rotate 14 postrotate /usr/bin/killall -HUP myapp_process endscript }
This tells your application to finish writing to the current file, close it, and open a new one. It’s cleaner, faster, and avoids the race conditions inherent in copytruncate. Just make sure your app is actually listening for that signal.
Common Pitfalls and Best Practices
I’ve spent about two days total in my career debugging "logrotate didn't run" issues. Almost every time, it boiled down to one of these three things:
- Permissions: If your app runs as
www-databutlogrotatetries to create files asroot, you’ll end up with a permission denied error. Always use thesudirective in your config to specify the user and group context. - Cron Conflicts: Check if your system has a secondary
logrotateprocess running. I once found a duplicatecron.dailyjob that was fighting with the systemd timer. - The "Missing" Log: If your application stops logging entirely, check if
logrotatecreated a root-owned file where the application expected a user-owned one.
Comparing Rotation Strategies
| Strategy | Best For | Pros | Cons |
|---|---|---|---|
size | High-traffic logs | Predictable disk usage | Can rotate very frequently |
daily | Low-traffic logs | Simple, easy to track | Disk usage can spike |
copytruncate | Legacy apps | No app code changes | Minor log loss risk |
postrotate | Modern apps | Zero data loss | Requires app signal handling |
Managing logs effectively is just one piece of the infrastructure puzzle. If you are interested in how this fits into larger resource management, check out how we handle Kubernetes resource management: using VPA recommendation mode to keep our containers from starving. Similarly, keeping your log volume in check is vital when you start implementing complex systems like an Istio service mesh: advanced traffic management and mTLS guide, where log volume can explode if you aren't careful.
FAQ
Q: How do I test a logrotate config without waiting for a day?
A: Run it manually in debug mode: logrotate -d /etc/logrotate.d/your-config. It simulates the rotation and tells you exactly what it would do without actually moving any files.
Q: Does copytruncate affect performance?
A: On very high-I/O systems, the copy operation can cause a momentary spike in disk usage. If your logs are massive (multiple gigabytes), consider streaming them to a remote collector like Fluentd instead of local rotation.
Q: My logs are being rotated, but they aren't compressing. Why?
A: Check if gzip is installed. It sounds basic, but I've seen minimal Docker base images missing it, which causes logrotate to silently skip compression.
I’m still a fan of local rotation for simple services, but if you’re scaling out, eventually you’ll need to centralize. For now, keep your configs simple, use size limits, and always test your postrotate scripts before pushing to production. You don't want to find out your log rotation is broken when your disk is at 99%.
