DEV Community

dpm_bush
dpm_bush

Posted on

Logrotate for Application Logs: Configure Rotation Without Losing Data

Application logs can grow until they fill a VPS disk, but deleting a large log file by hand is not always a fix. A running process may keep writing to the file it already has open—even after you remove its directory entry. The safer approach is to configure log rotation and tell the application how to reopen its logs.

This guide sets up logrotate for a custom application that writes to /var/log/myapp/app.log. The example assumes the application runs as the myapp user and can reopen its log when it receives SIGUSR1. Check your application’s documentation before choosing a signal; not every program handles it the same way.

Check where the application writes logs

First, confirm the path and ownership of the log file:

sudo ls -l /var/log/myapp/
sudo stat /var/log/myapp/app.log
Enter fullscreen mode Exit fullscreen mode

If you are unsure whether the application still has a file open, inspect its file descriptors. Find its PID, then check the process’s open files:

pgrep -a myapp
sudo lsof -p PID | grep '/var/log/myapp/'
Enter fullscreen mode Exit fullscreen mode

Replace PID with the process ID. If lsof is not installed, /proc/PID/fd can also show the process’s open file descriptors, though the output is less convenient to interpret.

Deleting an active log is risky: the process can continue writing to the unlinked file, while du no longer counts it by name. If you are diagnosing a disk-space discrepancy, compare filesystem usage with directory usage and inspect open deleted files; the guide to finding open file handles after deleting a large file explains that diagnostic path.

Write a per-application logrotate rule

Create a file under /etc/logrotate.d/:

sudoedit /etc/logrotate.d/myapp
Enter fullscreen mode Exit fullscreen mode

Add a rule such as:

/var/log/myapp/app.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 myapp adm
    sharedscripts
    postrotate
        /bin/kill -USR1 $(cat /run/myapp.pid) 2>/dev/null || true
    endscript
}
Enter fullscreen mode Exit fullscreen mode

Adjust the path, owner, group, permissions, and signal for your application. The PID-file command is only an example: use a reliable PID source, such as the service’s documented PID file, and avoid signaling an unrelated or stale process.

Here is what the main directives do:

  • daily checks the log for rotation once per day when logrotate runs. It does not create a timer itself.
  • rotate 14 keeps up to 14 rotated files.
  • compress compresses older rotations; delaycompress waits until the next rotation before compressing the newest rotated file.
  • missingok avoids an error if the log does not exist.
  • notifempty skips empty files.
  • create 0640 myapp adm creates a new active log with the specified mode, owner, and group after rotation.
  • postrotate runs a command after rotation. In this example, it asks the application to reopen its log.
  • sharedscripts runs the post-rotation script once for this stanza, rather than once per matching log file.

Logrotate normally renames the active file and creates a replacement. The application must then close its old file handle and open the new path. If it does not, it may continue writing to the rotated file. Some applications support a reload signal; others require a service reload, a documented control command, or a different logging setup.

If the application cannot reopen logs, copytruncate is an alternative:

copytruncate
Enter fullscreen mode Exit fullscreen mode

It copies the current log to a rotated file and truncates the original in place, so the application can keep its file handle. However, log lines written during the copy-and-truncate interval can be lost. Prefer a supported reopen or reload mechanism when possible.

Test the configuration before forcing rotation

Logrotate can test a configuration without changing files:

sudo logrotate --debug /etc/logrotate.d/myapp
Enter fullscreen mode Exit fullscreen mode

Debug mode reports what logrotate would do, but does not rotate the log or update its state. Read the output for parsing errors, unexpected paths, and skipped files.

To request a rotation immediately, use the force option only after reviewing the rule and confirming you have enough disk space:

sudo logrotate --force /etc/logrotate.d/myapp
Enter fullscreen mode Exit fullscreen mode

A forced run ignores normal rotation conditions, so it is useful for a controlled test but not something to put into routine automation. Check the resulting files and the application’s status afterward:

sudo ls -lh /var/log/myapp/
sudo systemctl status myapp --no-pager
Enter fullscreen mode Exit fullscreen mode

For service diagnosis, reading systemctl status output can help distinguish an application failure from a rotation problem. If the application logs to the systemd journal instead of a file, inspect its service logs with journalctl rather than adding an unnecessary file-based rotation rule.

Confirm that rotation will run

On many systemd-based Linux distributions, a timer invokes logrotate. Check whether it is scheduled and when it last ran:

systemctl status logrotate.timer --no-pager
systemctl list-timers logrotate.timer
Enter fullscreen mode Exit fullscreen mode

The timer may not exist on every distribution or installation. Some systems use cron instead. Check the local setup rather than assuming that writing a file under /etc/logrotate.d/ automatically runs it.

Logrotate also tracks when files were last rotated in a state file, commonly /var/lib/logrotate/status. Avoid deleting or editing that file to “fix” a rule without understanding the effect: logrotate may treat logs as due for rotation again.

Common mistakes to avoid

Rotating a file the application does not use

Applications can log to the journal, a container’s standard output, or a different path than expected. Verify the actual destination before creating a rule.

Choosing the wrong owner or mode

If the replacement log is owned by root and the application runs as myapp, it may fail to write after rotation. Match create to the application’s runtime user and the access policy for log readers.

Assuming a signal is universal

SIGUSR1 is not a standard “reopen logs” instruction for every program. A wrong signal can do nothing or trigger unrelated behavior. Confirm the supported mechanism, then test it outside a critical period.

Forgetting rotated logs still consume space

Compression reduces the size of older text logs, but retention still matters. Estimate how quickly the application generates logs and choose a retention period that fits both operational needs and available storage.

A good rotation rule is specific to the application: it names the real log path, creates a writable replacement, and uses a verified reopen mechanism. Test the configuration first, then confirm that the service continues logging to the new file.

I'm building SSHFlow — an SSH client that organizes terminals, SFTP, code editing, and server tools into workspaces.

Top comments (0)