■はじめに
RHEL7系からRHEL8系へインプレースアップグレードした際に、logrotateの不具合が発生しました。
今回はlogrotate不具合のトラブルシューティングについてお話できればと思います。
■事象と原因
【事象】
logrotateの処理は正常に実行されるが、rsyslogの再起動が実行されず同じログファイルにログ出力し続ける。
結果、以下のような容量0のファイルだけが作成されてしまう事象が発生。
# ll /var/log/messages*
-rw-r--r-- 1 root root 0 Jan 14 08:13 messages
-rw-r--r-- 1 root root 0 Jan 11 08:12 messages-20240112
-rw-r--r-- 1 root root 0 Jan 12 08:13 messages-20240113
-rw-r--r-- 1 root root 0 Jan 13 08:13 messages-20240114
【原因】
/etc/logrotate.d/syslog
の設定をRHEL7系からRHEL8系へ、そのまま引継いだことにより予期せぬ動作を引き起こしました。
下記記載したものが引き継いだ設定となります。
# cat /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
rotate 3
daily
dateext
missingok
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
■そもそもlogrotateとは
ローテーションとは、設定されたログファイルの最大数を超えると、最新のファイルによって最も古いファイルが書き換えられ、ファイルの名前が変更されることを意味します。たとえば、ローテーションの数が 30 の場合は、31 番目のファイル (最も古いファイル) が新しいファイルにより置き換えられます。
ログローテーションは、膨大なログファイルを減らして整理するため、ログの分析に役立ちます。
上記logrotate
を実行する際に読み込む設定ファイルには、ログローテーション全体の設定ファイルである/etc/logrotate.conf
と各サービスごとの設定ファイルのlogrotate.d/*
があり、ファイル構成としては以下のようになります。
/etc/
├── logrotate.conf(共通設定)
├── logrotate.d
│ ├─ syslog
│ ├─ ...
│ ├─ ...
│ └─ ...
│
logrotate.d/*
の設定内容の詳細については、分かりやすくまとめている記事が協栄情報ブログにあるので、気になる方はご確認ください。
■トラブルシューティング
実際に原因特定までを段階的に解説していきます。
-ステップ1
まず最初の調査としは、そもそもlogrotate
が実行されているかどうかのログ確認です。
Google先生にlogrotate ログ確認 方法
と聞くと /var/lib/logrotate.status
を見てねと返事をもらえたので確認してみました。
確認すると以下のような前回実行履歴が記載されていることが分かります。
# cat /var/lib/logrotate/logrotate.status
logrotate state -- version 2
"/var/log/spooler" 2023-10-12-10:0:0
"/var/log/maillog" 2023-10-12-10:0:0
"/var/log/secure" 2024-1-10-7:40:23
"/var/log/messages" 2024-1-14-8:13:24
"/var/log/cron" 2024-1-14-8:13:24
上記ログを確認すると2024-1-14-8:13:24
に実行されていることが分かったのでlogrotate
の実行は問題なしとしました。
※ここでもう少し深堀りしておけば早期解決できました。。
-ステップ2
logrotate
の実行が問題ないなら、そもそもログ出力できていないのではないかという考えになり、ログ出力が正常にされているかの観点で調査を始めました。
調査してみるとjournal
がlog収集し、収集したログを変形、ログファイルに出力するのがrsyslog
であることが分かりました。
-ステップ3
ステップ2の情報からjournal
がログ収集できているかを確認することにしました。
/run/log/journal/
配下にjournalログが存在することからjournalの動作としては問題なさそうであると判断しました。
-ステップ4
もう一度確認漏れがないかステップ1
から再度確認することにしました。
確認箇所としては、■そもそもlogrotateとは
で確認した下記設定ファイルを確認しました。
・/etc/logrotate.conf
・logrotate.d/syslog
■事象と原因
でも記載したsyslog
を読み解いていくとpostrotate と endscript の間にコマンドの記載があることが分かりました。
# cat /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
rotate 3
daily
dateext
missingok
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
上記コマンドを読み解いていくと、syslogd.pid
に記載のPIDを指定して再起動していることが分かります。
syslogd.pid
に記載のPIDが何のプロセスIDかを調べるとrsyslogのPIDであることが分かりました。
実際に確認した結果です。
# cat /var/run/syslogd.pid
1142
# systemctl status rsyslog
● rsyslog.service - System Logging Service
Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2024-01-14 06:21:03 UTC; 3h 32min ago
Docs: man:rsyslogd(8)
http://www.rsyslog.com/doc/
Main PID: 1142 (rsyslogd)
CGroup: /system.slice/rsyslog.service
└─1142 /usr/sbin/rsyslogd -n
syslogd.pidに記載のPIDとrsyslog.serviceのステータス確認で確認できたPIDの値が一致しています。
このことからsyslog
の設定上、日時でログローテを実施しした後にrsyslogを再起動していることが分かりました。
– -なぜ、rsyslogの再起動を実施しているのか
ログローテ後にrsyslogを再起動することにより、ログファイルに紐づいたrsyslogのPIDを再読み込みさせる。
これにより、再起動後のrsyslogのPIDが新たに作成されたログファイルに紐づき、ログ出力がされるようです。
– -もう少し詳しく
下記コマンドで、先程確認したPIDを使用しているファイルディスクリプタを確認できます。
一度オリジナルログファイル(messages-20240110
(リネーム前:messages
))を削除した後、同じファイル名のログファイル(messages
)を作成したとしてもdeletedとなり、削除したログファイル(/var/log/messages-20240110
)に紐づいたままとなります。
同じファイル名(messages
)のログファイルを作成したとしても、rsyslogは削除された元ファイルに紐付いたままなのでrsyslogを再起動してログファイルの紐付けを変えてあげないとログ出力されないとういことだったみたいです。
※ファイルディスクリプタ(file descriptor)とは、プログラムからファイルを操作する際、操作対象のファイルを識別・同定するために割り当てられる番号。
# ls -l /proc/1223/fd
total 0
lr-x------ 1 root root 64 Jan 14 07:22 0 -> /dev/null
l-wx------ 1 root root 64 Jan 14 07:22 1 -> /dev/null
lr-x------ 1 root root 64 Jan 14 07:22 10 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-000000000000035c-00060ebb248dd182.journal
lr-x------ 1 root root 64 Jan 14 07:22 11 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-0000000000000333-00060ea6df3ff816.journal
lr-x------ 1 root root 64 Jan 14 07:22 12 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-0000000000000324-00060ee31607a1f1.journal
lr-x------ 1 root root 64 Jan 14 07:22 13 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-00000000000002fe-00060ea6af0543f9.journal
lr-x------ 1 root root 64 Jan 14 07:22 14 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-00000000000002f5-00060e5633cc17a9.journal
lr-x------ 1 root root 64 Jan 14 07:22 15 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-00000000000002e4-00060e928a7063d6.journal
lr-x------ 1 root root 64 Jan 14 07:22 16 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-00000000000002da-00060ee2f6422d4b.journal
l-wx------ 1 root root 64 Jan 14 07:22 17 -> '/var/log/cron-20240112 (deleted)'
lr-x------ 1 root root 64 Jan 14 07:22 18 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-0000000000000001-00060ee2bf53e165.journal
lr-x------ 1 root root 64 Jan 14 07:22 19 -> /run/log/journal/ec242ade1d5a9d166d4054b9e165de60/system.journal
l-wx------ 1 root root 64 Jan 14 07:22 2 -> /dev/null
lr-x------ 1 root root 64 Jan 14 07:22 3 -> /dev/urandom
lrwx------ 1 root root 64 Jan 14 07:22 4 -> 'socket:[27420]'
l-wx------ 1 root root 64 Jan 14 07:22 5 -> '/var/log/messages-20240110 (deleted)'
lr-x------ 1 root root 64 Jan 14 07:22 6 -> anon_inode:inotify
l-wx------ 1 root root 64 Jan 14 07:22 7 -> '/var/log/secure-20240110 (deleted)'
l-wx------ 1 root root 64 Jan 14 07:22 8 -> /var/log/maillog-20240114
lr-x------ 1 root root 64 Jan 14 07:22 9 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system.journal
– -rsyslogが再起動出来ていない原因
RHEL7系からRHEL8系へインプレースアップグレードした際に、/var/run/syslogd.pid
が削除され、PIDの確認が出来ずrsyslogが再起動出来なかったことが根本の原因でした。
-ステップ5
syslogをRHEL8系のデフォルトの設定値に修正することでRHEL8系へ移行後もrsyslogの再起動を実施することが出来るようになります。
大きな修正内容としては、/var/run/syslogd.pid
のPIDを参照して再起動を行っていたところを、直接rsyslog.serviceを再起動するようにした箇所です。
この修正により、rsyslogを再起動させることができ新たに作成されたログファイルにPIDを紐付けることが出来ました。
# cat /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
rotate 3
daily
dateext
missingok
sharedscripts
postrotate
/usr/bin/systemctl -s HUP kill rsyslog.service >/dev/null 2>&1 || true
endscript
}
■動作確認
手動でlogrotateを実行し、再度ファイルディスクリプタを確認したところ/var/log/messages
の行に出ていたdeleted
は消え、ファイルパスも更新されていることが確認できました。
# ls -l /proc/1223/fd
total 0
lr-x------ 1 root root 64 Jan 14 07:22 0 -> /dev/null
l-wx------ 1 root root 64 Jan 14 07:22 1 -> /dev/null
lr-x------ 1 root root 64 Jan 14 07:22 10 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-000000000000035c-00060ebb248dd182.journal
lr-x------ 1 root root 64 Jan 14 07:22 11 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-0000000000000333-00060ea6df3ff816.journal
lr-x------ 1 root root 64 Jan 14 07:22 12 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-0000000000000324-00060ee31607a1f1.journal
lr-x------ 1 root root 64 Jan 14 07:22 13 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-00000000000002fe-00060ea6af0543f9.journal
lr-x------ 1 root root 64 Jan 14 07:22 14 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-00000000000002f5-00060e5633cc17a9.journal
lr-x------ 1 root root 64 Jan 14 07:22 15 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-00000000000002e4-00060e928a7063d6.journal
lr-x------ 1 root root 64 Jan 14 07:22 16 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-00000000000002da-00060ee2f6422d4b.journal
lr-x------ 1 root root 64 Jan 14 07:22 18 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system@940019254177499fa7c97737ab0ee09f-0000000000000001-00060ee2bf53e165.journal
lr-x------ 1 root root 64 Jan 14 07:22 19 -> /run/log/journal/ec242ade1d5a9d166d4054b9e165de60/system.journal
l-wx------ 1 root root 64 Jan 14 07:22 2 -> /dev/null
lr-x------ 1 root root 64 Jan 14 07:22 3 -> /dev/urandom
lrwx------ 1 root root 64 Jan 14 07:22 4 -> 'socket:[27420]'
l-wx------ 1 root root 64 Jan 14 07:22 5 -> /var/log/messages
lr-x------ 1 root root 64 Jan 14 07:22 6 -> anon_inode:inotify
lr-x------ 1 root root 64 Jan 14 07:22 9 -> /run/log/journal/38193d45b1a74a60a81037519c7026ad/system.journal
新たに作成されたログファイルにログ出力されていることも確認できたので事象解消しました。
# ll /var/log/messages*
-rw-r--r-- 1 root root 284 Jan 15 11:27 /var/log/messages
-rw-r--r-- 1 root root 0 Jan 12 08:13 /var/log/messages-20240113
-rw-r--r-- 1 root root 0 Jan 13 08:13 /var/log/messages-20240114
-rw-r--r-- 1 root root 0 Jan 14 08:13 /var/log/messages-20240115
■まとめ
インプレースアップグレードはOS設定を引き継げるところが良いところですが、軽微な変更点で既存の機能が動作しないなんてこともあるので、バージョンアップ前後で設定値の再確認は必須ですね。。