この記事の見出し一覧
Proxmox ノードから毎朝届くはずの Logwatch 通知メールが、ある日だけ届かなかった。配送エラーで起きがちな SPF/DKIM/DMARC はすべて PASS 状態。そして、Postfix の status も Active 表示で問題無し。にもかかわらず特定の 1 日分だけ抜けるという、地味だが気持ち悪い事象である。
原因にたどり着くまでの調査過程と、最終的な対策をまとめておく。
事象
Gmail の受信トレイを見ると、管理している他のサーバーからは同じ日付で Logwatch メールが届いているのに、Proxmoxからの通知だけが 1 日分抜けている。翌日になると遅れて(前日分の内容が)届く、という挙動だった。
最初は Gmail のスレッド統合や Precedence: bulk ヘッダーによる自動分類を疑ったが、それらでは「特定の 1 日だけ抜ける」説明がつかない。
切り分けしていくと意外な原因
cron は実行されているか
Proxmox は Debian ベースなので、cron.daily から Logwatch が起動する。
grep -r logwatch /etc/cron*
# /etc/cron.daily/00logwatch:/usr/sbin/logwatch --output mail
実行ログを確認。
journalctl --since "2026-06-13 06:25:00" --until "2026-06-13 06:26:00" -u cron
cron.daily は問題なく起動していた。anacron は未インストールで、test -x /usr/sbin/anacron || { ... } の条件分岐で run-parts がスキップされる線も否定できた。
実際のところメールは送信されたのか
Postfix のログを確認すると、その日の該当時刻にメール送信の痕跡がまったくないことがわかった。
journalctl --since "2026-06-13 06:25:00" --until "2026-06-13 06:30:00" | grep -i "postfix\|smtp\|logwatch"
# (出力なし)
Postfix デーモンはもちろん24時間無停止であり、前日分・翌日分は正常に送信されている。つまり「Logwatch は起動したが、メールを Postfix に渡さなかった」ということになる。
Logwatch は何を出力したのか
ここが決定的だった。当該日分のレポートを手動で再生成してみる。
/usr/sbin/logwatch --output stdout --range "2026-Jun-12" 2>&1 | wc -l
# 0
0 行。前後の日付は正常に出力される。
/usr/sbin/logwatch --output stdout --range "2026-Jun-11" 2>&1 | wc -l
# 69
/usr/sbin/logwatch --output stdout --range "2026-Jun-13" 2>&1 | wc -l
# 71
Logwatch は レポートが空のときメールを送信しない。これが「届かなかった」直接の原因である。
問題は、なぜその日だけ何故空レポートになったのか…
なぜ空レポートになったのか
journald からログは取れている
該当日のログ自体はもちろん journald に存在する。
journalctl --since "2026-06-12 00:00:00" --until "2026-06-12 23:59:59" | wc -l
# 1604
1604 行ある。ログが無いわけではないと分かる。
Logwatch の journald 連携を追う
Proxmox は rsyslog ではなく journald を使うため、Logwatch は scripts/shared/journalctl という Perl ラッパー経由でログを読む。このスクリプトは環境変数 LOGWATCH_DATE_RANGE を見て journalctl の --since / --until が条件付けだ。
} elsif ( $range eq 'yesterday' ) {
push @range, '--since', 'yesterday', '--until', 'today';
}
cron.daily からは --range 指定なしで呼ばれるため、標準の yesterday 指定が使われ、実体としては次のコマンドとパラメータが走っている。
journalctl --since yesterday --until today
試しにこれを手動で実行すると正常にログが返る。--range yesterday でも正常。つまり通常は問題なく動く。
journal のローテーションがタイミング悪く詰まっていた
journal ファイルのタイムスタンプを確認したところ、見逃せない事実が出てきた。
ls -la /var/log/journal/<machine-id>/
- アクティブな
system.journalの作成時刻が当日の 04:05 - アーカイブされた journal の最終エントリも 04:05
一方で標準設定の Logwatch が走るのは 06:25。
つまり当該日の朝、Logwatch が「前日分(yesterday)」を読もうとした時点で、対象のログはすべて直前 04:05 のローテーションでアーカイブ側に移っていた。このローテーション直後の一時的な不整合により、journalctl --since yesterday --until today がその瞬間だけ前日分を返さなかった、というのが最も合理的な説明になる(事後に同じコマンドを叩くと正常に返るため、再現・確定は難しい)。
対策
Proxmox では journald を rsyslog に置き換える選択肢を取りたくない。そこで「空レポートのときは黙ってスキップせず、警告メールを飛ばす」方針にした。これなら次に同じ事象が起きても確実に検知できる。
/etc/cron.daily/00logwatch を以下に差し替えた。
#!/bin/bash
#Check if removed-but-not-purged
test -x /usr/share/logwatch/scripts/logwatch.pl || exit 0
#execute
OUTPUT=$(/usr/sbin/logwatch --output stdout)
if [ -z "$OUTPUT" ]; then
echo "WARNING: Logwatch produced empty output on $(hostname) - $(date)" | \
mail -s "Logwatch EMPTY REPORT for $(hostname)" you@example.com
else
/usr/sbin/logwatch --output mail
fi
chmod +x /etc/cron.daily/00logwatch
logwatch --output stdout を一度実行して出力が空かどうかを判定し、空なら「EMPTY REPORT」という件名の警告メールを送る。空でなければ従来どおり --output mail でレポートを送信する。Logwatch を 2 回走らせることになるが、cron.daily の日次処理なので無視できる範囲だ。
まとめ
- 現象:特定の 1 日分だけ Logwatch メールが届かない
- 直接原因:Logwatch が空レポートを生成し、メール送信をスキップした
- 推定根本原因:journal ローテーション(04:05)直後の一時的な不整合により、06:25 の Logwatch 実行時に
journalctl --since yesterday --until todayが前日分を返さなかった - 対策:空レポート時に警告メールを送るラッパースクリプトに変更し、再発を検知可能にした
「メールが届かない」系のトラブルは送信側(Postfix・DNS・SPF/DKIM)を疑いがちだが、今回は そもそもメールが生成されていなかった というオチだった。journald 環境で Logwatch を使っている場合、ローテーションのタイミング次第で同種の取りこぼしが起こりうる点は頭の隅に置いておきたい。
※本記事は当サイト管理人の個人的な備忘録です。情報内容には配慮しておりますが、本記事の参照または付随ソースコード利用後にいかなる損害が発生しても、当サイト及び管理人はいっさいの責任を負いません。
