logrotate
Manages logrotate configuration files in /etc/logrotate.d/.
Parameters
| Parameter | Required | Default | Description |
|---|---|---|---|
name |
Yes | -- | The resource's own name: -- used as the filename (/etc/logrotate.d/<name>). Do not add a second name: key. |
state |
Yes | -- | Desired state: present or absent. |
path |
Yes (for present) | -- | Log file path or glob pattern (e.g., /var/log/myapp/*.log). |
frequency |
No | weekly |
Rotation frequency: daily, weekly, monthly, yearly. |
rotate |
No | 4 |
Number of rotated files to keep. |
compress |
No | true |
Compress rotated files. |
delaycompress |
No | true |
Delay compression of the most recent rotated file. |
missingok |
No | true |
Do not error if the log file is missing. |
notifempty |
No | true |
Do not rotate empty files. |
copytruncate |
No | false |
Copy the log and truncate instead of moving (for apps that hold open file handles). |
size |
No | -- | Rotate based on file size (e.g., 100M, 1G). |
maxage |
No | -- | Maximum age in days for rotated files. |
create |
No | -- | Create replacement file after rotation (e.g., 0644 root root). |
postrotate |
No | -- | Command to run after rotation (e.g., systemctl reload nginx). |
States
present-- Ensure the logrotate configuration exists with the specified directives.absent-- Remove the logrotate configuration file.
Idempotency
Computes the SHA-256 hash of the desired configuration content and compares it against the existing file. Only writes when the content differs.
Choosing a path
Declare one resource per application whose logs nothing else already owns.
Never use a catch-all pattern such as /var/log/*.log or /var/log/*/*.log.
Distro packages ship their own configs in /etc/logrotate.d/ (apt,
alternatives, rsyslog, ...), and logrotate treats a log claimed by two
configs as a fatal duplicate log entry. It then skips the entire file
containing the duplicate -- so the catch-all silently rotates nothing, and
logrotate.service exits non-zero on every run.
To find what is genuinely unowned on a host:
for f in /var/log/*.log /var/log/*/*.log; do
grep -qlF -- "$f" /etc/logrotate.d/* 2>/dev/null || echo "unowned: $f"
done
Leave these to the tools that already manage them: /var/log/audit/* (auditd
rotates via max_log_file/num_logs; rotating it externally breaks the audit
trail) and /var/log/Xorg.*.log (Xorg keeps its own generations).
Examples
Basic
resources:
- name: myapp
type: logrotate
state: present
path: /var/log/myapp/*.log
frequency: daily
rotate: "7"
Nginx with postrotate
resources:
- name: nginx
type: logrotate
state: present
path: /var/log/nginx/*.log
frequency: daily
rotate: "14"
compress: "true"
postrotate: "/usr/sbin/nginx -s reload"
With copytruncate
Use copytruncate for a daemon that holds its log open and never reopens it.
A create-style rotate would leave the process writing to the unlinked inode,
so the new file would stay empty forever.
resources:
- name: myapp-service
type: logrotate
state: present
path: /var/log/myapp.log
copytruncate: "true"
frequency: daily
rotate: "30"
size: "100M"
Remove a config
resources:
- name: old-app
type: logrotate
state: absent
Platform
Linux only.
Notes
- Generates a standard logrotate configuration block with the
path { ... }format. - Boolean options default to common best practices: compress, delaycompress, missingok, and notifempty are on; copytruncate is off.
- The
postrotatescript is wrapped inpostrotate/endscriptdirectives.