投稿日:2025/2/10最終更新日:2026/3/22
以前セットアップしたsyslog-ngにて吐き出されるメールログをlogrotateでローテートしたくなりました。
ArchLinuxのsyslog-ngにて出力している/var/log/mail.logをログローテートして圧縮か削除するスクリプトを作成したくなったので、一旦ログローテートの設定を整備します。
ArchLinuxのPackageにlogrotateというまんまのやつがあります。
そいつでセットアップします。
root@badcompany ~ [0:41:12]
> # paru -S logrotate
resolving dependencies...
looking for conflicting packages...
Packages (1) logrotate-3.22.0-1
Total Installed Size: 0.10 MiB
:: Proceed with installation? [Y/n]
(1/1) checking keys in keyring [################] 100%
(1/1) checking package integrity [################] 100%
(1/1) loading package files [################] 100%
(1/1) checking for file conflicts [################] 100%
(1/1) checking available disk space [################] 100%
:: Processing package changes...
(1/1) installing logrotate [################] 100%
:: Running post-transaction hooks...
(1/2) Reloading system manager configuration...
(2/2) Arming ConditionNeedsUpdate...
root@badcompany ~ [0:41:30]
> # sudo systemctl status logrotate
○ logrotate.service - Rotate log files
Loaded: loaded (/usr/lib/systemd/system/logrotate.service; static)
Active: inactive (dead)
TriggeredBy: ○ logrotate.timer
Docs: man:logrotate(8)
man:logrotate.conf(5)
root@badcompany ~ [0:42:01]
> # cat /etc/logrotate.conf
# see "man logrotate" for details
# rotate log files weekly
weekly
# keep 4 weeks worth of backlogs
rotate 4
# restrict maximum size of log files
#size 20M
# create new (empty) log files after rotating old ones
create
# uncomment this if you want your log files compressed
#compress
# Logs are moved into directory for rotation
# olddir /var/log/archive
# Ignore pacman saved files
tabooext + .pacorig .pacnew .pacsave
# Arch packages drop log rotation information into this directory
include /etc/logrotate.d
/var/log/wtmp {
monthly
create 0664 root utmp
minsize 1M
rotate 1
}
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}
root@badcompany ~ [0:42:40]
> # cd /etc/logrotate.d
root@badcompany /etc/logrotate.d [0:44:46]
> # cp -p /etc/logrotate.conf{,.$(date "+%Y%m%d")}
root@badcompany /etc/logrotate.d [0:43:50]
> # nvim /etc/logrotate.conf 各種ライブラリの導入段階で、それぞれ必要なファイルが生成されています。
今回の場合、syslog-ngのもののため、/etc/logrotate.d/syslog-ngというファイルを探します。
root@badcompany /etc/logrotate.d [15:22:05]
> # cat syslog-ng
/var/log/messages.log /var/log/auth.log /var/log/mail.log /var/log/kernel.log /var/log/errors.log /var/log/daemon.log /var/log/user.log /var/log/iptables.log /var/log/everything.log /var/log/syslog.log /var/log/acpid.log /var/log/crond.log /var/log/lpr.log /var/log/uucp.log /var/log/news.log /var/log/ppp.log /var/log/debug.log {
missingok
sharedscripts
postrotate
/bin/kill -HUP $(cat /run/syslog-ng.pid 2>/dev/null) 2>/dev/null || true
endscript
}これらにより、logrotateに対する設定が自動的に行われています。
設定内容は、sharedscriptsを使ってまとめて終わった後にsyslog-ngをリスタートしたり色々しています。正直言って自分は全く使いこなせていませんが、複雑な機構などもプロの方などは使いこなしているのでしょう。 man logrotate などで詳しく内容を読めますので、興味がある方は見てみると面白いかもですね。
以下、余談です。
Nginxのログ用に以下のようなやつも設定してみました。
> # cat nginx
/var/log/nginx/*log {
missingok
notifempty
create 640 http root
sharedscripts
compress
postrotate
test ! -r /run/nginx.pid || kill -USR1 `cat /run/nginx.pid`
endscript
}と言っても、ほとんどテンプレの丸写しです。 今までほぼローカルか、tailnetからのアクセスと思われていた接続についてはログを入れていなかったのですが、念の為取るようにしました。
また、以下のように、logrotateのログ保持設定を一年巻にしました。
root@badcompany /etc [4:07:22]
> # cp -p logrotate.conf{,.$(date "+%Y%m%d")}
root@badcompany /etc [4:07:39]
> # vim logrotate.conf
root@badcompany /etc [4:08:06]
root@badcompany /etc [4:31:10]
> # diff logrotate.conf.20250302 logrotate.conf
6c6
< rotate 4
---
> rotate 53
root@badcompany ~ [4:28:24]
> # logrotate --debug /etc/logrotate.d/nginx
warning: logrotate in debug mode does nothing except printing debug messages! Consider using verbose mode (-v) instead if this is not what you want.
reading config file /etc/logrotate.d/nginx
Reading state from file: /var/lib/logrotate.status
state file /var/lib/logrotate.status does not exist
Allocating hash table for state file, size 64 entries
Handling 1 logs
rotating pattern: /var/log/nginx/*log 1048576 bytes empty log files are not rotated, no old logs will be kept
considering log /var/log/nginx/access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log needs rotating
considering log /var/log/nginx/domain.tld_access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log needs rotating
considering log /var/log/nginx/domain.tld_error.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/buntin.code.domain.tld_access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/buntin.code.domain.tld_error.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/code.domain.tld_access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/code.domain.tld_error.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/dash.domain.tld_access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/dash.domain.tld_error.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/jupyterlab.domain.tld_access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/jupyterlab.domain.tld_error.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/kuma.domain.tld_access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/kuma.domain.tld_error.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/raw.domain.tld_access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/raw.domain.tld_error.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/secret.domain.tld_access.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
considering log /var/log/nginx/secret.domain.tld_error.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log does not need rotating (log size is below the 'size' threshold)
rotating log /var/log/nginx/access.log, log->rotateCount is 0
dateext suffix '-20250302'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
renaming /var/log/nginx/access.log.1.gz to /var/log/nginx/access.log.2.gz (rotatecount 1, logstart 1, i 1),
log /var/log/nginx/access.log.2.gz doesn't exist -- won't try to dispose of it
rotating log /var/log/nginx/domain.tld_access.log, log->rotateCount is 0
dateext suffix '-20250302'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
renaming /var/log/nginx/domain.tld_access.log.1.gz to /var/log/nginx/domain.tld_access.log.2.gz (rotatecount 1, logstart 1, i 1),
log /var/log/nginx/domain.tld_access.log.2.gz doesn't exist -- won't try to dispose of it
renaming /var/log/nginx/access.log to /var/log/nginx/access.log.1
disposeName will be /var/log/nginx/access.log.1.gz
creating new /var/log/nginx/access.log mode = 0640 uid = 33 gid = 0
renaming /var/log/nginx/domain.tld_access.log to /var/log/nginx/domain.tld_access.log.1
disposeName will be /var/log/nginx/domain.tld_access.log.1.gz
creating new /var/log/nginx/domain.tld_access.log mode = 0640 uid = 33 gid = 0
running postrotate script
running script with args /var/log/nginx/*log : "
test ! -r /run/nginx.pid || kill -USR1 `cat /run/nginx.pid`
"
compressing log with: /usr/bin/gzip
removing old log /var/log/nginx/access.log.1.gz
compressing log with: /usr/bin/gzip
removing old log /var/log/nginx/domain.tld_access.log.1.gz
root@badcompany ~ [4:28:40]
> # logrotate --debug /etc/logrotate.d/syslog-ng
warning: logrotate in debug mode does nothing except printing debug messages! Consider using verbose mode (-v) instead if this is not what you want.
reading config file /etc/logrotate.d/syslog-ng
Reading state from file: /var/lib/logrotate.status
state file /var/lib/logrotate.status does not exist
Allocating hash table for state file, size 64 entries
Handling 1 logs
rotating pattern: /var/log/messages.log /var/log/auth.log /var/log/mail.log /var/log/kernel.log /var/log/errors.log /var/log/daemon.log /var/log/user.log /var/log/iptables.log /var/log/everything.log /var/log/syslog.log /var/log/acpid.log /var/log/crond.log /var/log/lpr.log /var/log/uucp.log /var/log/news.log /var/log/ppp.log /var/log/debug.log 1048576 bytes empty log files are rotated, no old logs will be kept
considering log /var/log/messages.log
log /var/log/messages.log does not exist -- skipping
Creating new state
considering log /var/log/auth.log
log /var/log/auth.log does not exist -- skipping
Creating new state
considering log /var/log/mail.log
Creating new state
Now: 2025-03-02 04:28
Last rotated at 2025-03-02 04:00
log needs rotating
considering log /var/log/kernel.log
log /var/log/kernel.log does not exist -- skipping
Creating new state
considering log /var/log/errors.log
log /var/log/errors.log does not exist -- skipping
Creating new state
considering log /var/log/daemon.log
log /var/log/daemon.log does not exist -- skipping
Creating new state
considering log /var/log/user.log
log /var/log/user.log does not exist -- skipping
Creating new state
considering log /var/log/iptables.log
log /var/log/iptables.log does not exist -- skipping
Creating new state
considering log /var/log/everything.log
log /var/log/everything.log does not exist -- skipping
Creating new state
considering log /var/log/syslog.log
log /var/log/syslog.log does not exist -- skipping
Creating new state
considering log /var/log/acpid.log
log /var/log/acpid.log does not exist -- skipping
Creating new state
considering log /var/log/crond.log
log /var/log/crond.log does not exist -- skipping
Creating new state
considering log /var/log/lpr.log
log /var/log/lpr.log does not exist -- skipping
Creating new state
considering log /var/log/uucp.log
log /var/log/uucp.log does not exist -- skipping
Creating new state
considering log /var/log/news.log
log /var/log/news.log does not exist -- skipping
Creating new state
considering log /var/log/ppp.log
log /var/log/ppp.log does not exist -- skipping
Creating new state
considering log /var/log/debug.log
log /var/log/debug.log does not exist -- skipping
Creating new state
rotating log /var/log/mail.log, log->rotateCount is 0
dateext suffix '-20250302'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
renaming /var/log/mail.log.1 to /var/log/mail.log.2 (rotatecount 1, logstart 1, i 1),
log /var/log/mail.log.2 doesn't exist -- won't try to dispose of it
renaming /var/log/mail.log to /var/log/mail.log.1
disposeName will be /var/log/mail.log.1
running postrotate script
running script with args /var/log/messages.log /var/log/auth.log /var/log/mail.log /var/log/kernel.log /var/log/errors.log /var/log/daemon.log /var/log/user.log /var/log/iptables.log /var/log/everything.log /var/log/syslog.log /var/log/acpid.log /var/log/crond.log /var/log/lpr.log /var/log/uucp.log /var/log/news.log /var/log/ppp.log /var/log/debug.log : "
/bin/kill -HUP $(cat /run/syslog-ng.pid 2>/dev/null) 2>/dev/null || true
"
removing old log /var/log/mail.log.1
root@badcompany ~ [4:29:02]
> # logrotate --debug /etc/logrotate.d/postgresql
warning: logrotate in debug mode does nothing except printing debug messages! Consider using verbose mode (-v) instead if this is not what you want.
reading config file /etc/logrotate.d/postgresql
Reading state from file: /var/lib/logrotate.status
state file /var/lib/logrotate.status does not exist
Allocating hash table for state file, size 64 entries
Handling 1 logs
rotating pattern: /var/log/postgresql.log 1048576 bytes empty log files are rotated, no old logs will be kept
considering log /var/log/postgresql.log
log /var/log/postgresql.log does not exist -- skipping
Creating new stateOKそうですね。ということで起動していきます。
root@badcompany ~ [4:49:40]
> # systemctl start logrotate.timer
root@badcompany ~ [4:49:53]
> # systemctl status logrotate.timer
● logrotate.timer - Daily rotation of log files
Loaded: loaded (/usr/lib/systemd/system/logrotate.tim>
Active: active (waiting) since Sun 2025-03-02 04:49:5>
Invocation: 1b09dcc5f05942f1a133c06291ac5685
Trigger: Mon 2025-03-03 00:35:26 JST; 19h left
Triggers: ● logrotate.service
Docs: man:logrotate(8)
man:logrotate.conf(5)
Mar 02 04:49:53 badcompany.tokyo systemd[1]: Started Daily>途中の長いログはテストです。
これによりログについては、しばらくは時間稼ぎできました。 S3へのrcloneによる同期設定にするか、ローカルのバックアップサーバーにアップロードするかなど、これらのファイル(ほぼ確実に利用機会はありません)を、どう保存してやるかを考えているところです。
logrotateについての設定ほぼ完了したので、一旦この記事はここまでとします。
では!