Intermediate · 12 min · practise every command in the built-in terminal

logrotate — Logs That Don't Fill the Disk

Logs only grow. An app that logs every request writes gigabytes in a month — until the disk is full and everything stops. logrotate keeps them in check: every day (or week) it renames the log, starts a fresh one, compresses the old ones and deletes the oldest.

ls -lh /var/log/myapp
-rw-r----- 1 root adm 179M Nov  1 15:38 app.log
-rw-r----- 1 root adm  48K Nov  1 13:39 error.log

Nobody set up rotation for this app's logs.

How it's set up

/etc/logrotate.conf has the defaults; every package drops its own file in /etc/logrotate.d:

ls /etc/logrotate.d
cat /etc/logrotate.d/dpkg
/var/log/dpkg.log {
	monthly
	rotate 12
	compress
	delaycompress
	missingok
	notifempty
	create 644 root root
}
LineMeans
daily / weekly / monthlyhow often
rotate 12keep 12 old copies, delete the older ones
compressgzip the old copies
delaycompress…but not the newest old one (a program may still write to it)
missingokno error when the log isn't there
notifemptyleave an empty log alone
create 644 root roota new, empty log with this mode and owner
size 100Mrotate once it's this big, whatever the date
copytruncatecopy, then empty the log in place — for apps that keep it open

One for myapp

sudo tee /etc/logrotate.d/myapp > /dev/null << 'EOF'
/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640 root adm
}
EOF

Test it

-d (debug) tells what it would do — and does nothing:

sudo logrotate -d /etc/logrotate.d/myapp
considering log /var/log/myapp/app.log
Creating new state
  Now: 2026-11-01 15:39
  Last rotated at 2026-11-01 15:00
  log does not need rotating (log has already been rotated)

A log logrotate meets for the first time counts as rotated this hour: the first real rotation is tomorrow. -f forces one now:

sudo logrotate -f /etc/logrotate.d/myapp
ls -lh /var/log/myapp
-rw-r----- 1 root adm    0 Nov  1 15:39 app.log
-rw-r----- 1 root adm 179M Nov  1 15:38 app.log.1

Tomorrow app.log.1 becomes app.log.2.gz, and so on up to .7.gz; when each log was last rotated is in /var/lib/logrotate/status. And who runs it every day?

systemctl list-timers logrotate.timer

💡 After a rotation an app may go on writing to the old, renamed file — it still has it open. A postrotate script (systemctl reload myapp) or copytruncate takes care of that.

Practice tasks

  1. See how big the app's logs are
  2. See how a package rotates its log
  3. Write /etc/logrotate.d/myapp: daily, keep 7, compressed
  4. Test it without changing anything
  5. Rotate the logs now
  6. See the new log and the old one
  7. Find the timer that runs logrotate every day

Commands in this lesson

Server Setup