RHEL 中級 #5 ログ管理 — journald、rsyslog、log rotation
基礎 #4 で journald と journalctl を扱いました。この記事ではその上にもう 1 段入って運用でログを回す方法を整理します。保管ポリシーでディスク使用量を掴み、rsyslog でリモートサーバーにログを集め、logrotate でテキストログを自動回転させるフローまでつながります。
RHEL 中級 シリーズでこの記事の位置:
- #1 SELinux 入門 — Enforcing/Permissive、ラベル、トラブルシューティング
- #2 LVM — PV/VG/LV、スナップショット、拡張
- #3 ストレージ深化 — Stratis、NFS、Samba
- #4 ネットワーキング — NetworkManager (nmcli)、bonding、teaming
- #5 ログ管理 — journald、rsyslog、log rotation ← この記事
- #6 ジョブスケジューリング — cron、systemd timer、at
- #7 コンテナ入門 — Podman/Buildah/Skopeo (Docker との違い)
RHEL 9 のログ構造 #
RHEL 9 では 2 つのツールが一緒に働きます。journald がメイン、rsyslog がサブです。
カーネル / サービス / ユーザープロセス
│
│ syslog() / journald API
▼
┌─────────────────────────┐
│ journald │ ← メイン (構造化バイナリ)
│ /run/log/journal/ │ /var/log/journal/ (永続)
└────────────┬────────────┘
│ 転送 (オプション)
▼
┌─────────────────────────┐
│ rsyslog │ ← 古いテキストログ互換 + リモート送信
│ /var/log/messages │
│ /var/log/secure │
│ /var/log/maillog │
└────────────┬────────────┘
│ logrotate (cron)
▼
回転された圧縮ログファイル
/var/log/messages-20260420.gzフローの要点:
- カーネル・サービスが送るログはすべて journald がまず受けます。
- journald は自分のバイナリ形式で保存しながら同時に rsyslog にも転送。
- rsyslog は古いテキストファイル (
/var/log/messagesなど) を作り、リモート syslog サーバーに送信することもできます。 - すべてのテキストログファイルは logrotate が一定サイズ・期間で自動回転。
運用者は両方を知らなければなりません。新しいツールは journalctl ですが、古い資料・外部 SIEM (セキュリティ情報イベント管理)・他のホストとの統合には rsyslog が依然として必須です。
journald — 深く入る #
基礎 #4 で見た journalctl -u、-b、--since のようなコマンドは日常ツール。今回はその後ろの 保管ポリシー と ディスク使用量制御 を見ます。
揮発性 vs 永続保管 #
デフォルトの RHEL 9 は journald が 揮発性 (/run/log/journal/) で動作します。再起動すると消えます。運用マシンでは永続保管をオンにするのが標準。
$ sudo mkdir -p /var/log/journal
$ sudo systemd-tmpfiles --create --prefix /var/log/journal
$ sudo systemctl restart systemd-journald
# 確認
$ journalctl --list-boots
-2 ... 2026-04-18 09:01:23 2026-04-19 08:55:11
-1 ... 2026-04-19 09:00:01 2026-04-20 08:55:32
0 ... 2026-04-20 09:00:01 2026-04-20 14:23:01--list-boots が複数の起動を見せれば永続保管がオンになったことです。
ディスク使用量制御 — journald.conf
#
永続保管をオンにするとログが無限に積もる可能性があります。上限 を明示的に掴んでおくのが運用の要点。
[Journal]
Storage=persistent
# ディスク使用量上限
SystemMaxUse=2G
SystemKeepFree=500M
SystemMaxFileSize=128M
SystemMaxFiles=100
# 保管期間
MaxRetentionSec=30day
# 圧縮 / 封印
Compress=yes
Seal=yesオプションの読み方:
| オプション | 意味 |
|---|---|
Storage=persistent | 永続保管強制 |
SystemMaxUse | journald が使うディスク上限 |
SystemKeepFree | ディスクに常に空けておく余裕 |
SystemMaxFileSize | 1 つの journal ファイルの最大サイズ (このサイズで回転) |
SystemMaxFiles | 保管するファイル数 |
MaxRetentionSec | 保管最大期間 (30day、4week、1month など) |
Compress | 自動圧縮 |
Seal | 完全性封印 (改ざん防止) |
SystemMaxUse と MaxRetentionSec のうち 先に到達した方 が適用されます。両方掴むのが安全。
$ sudo systemctl restart systemd-journald
$ journalctl --disk-usage
Archived and active journals take up 1.2G in the file system.journald 整理 — 即時回収 #
急いでディスク領域が必要なとき:
$ sudo journalctl --vacuum-size=500M # 500M 以下に減らす
$ sudo journalctl --vacuum-time=7d # 7 日以上経ったものを削除
$ sudo journalctl --vacuum-files=10 # ファイル 10 個に減らす--vacuum-size が最もよく使われるオプション。運用でディスクアラート直後の即時回収が必要なときに使います。
構造化ログ活用 #
journald の本当の利点。すべてのログがキー値メタデータを持っています。
$ journalctl _COMM=sshd # sshd コマンドのログ
$ journalctl _SYSTEMD_UNIT=nginx.service # 特定 unit
$ journalctl _UID=1000 # 特定ユーザー
$ journalctl _PID=1234 # 特定 PID
# すべてのメタデータを見る
$ journalctl -o verbose -n 5# nginx のエラーのみ、今日
$ journalctl -u nginx -p err --since today
# 特定ユーザーが叩いた sudo コマンド
$ journalctl _COMM=sudo _UID=1000
# 特定 IP から来た ssh 試行 (メッセージ本文検索)
$ journalctl -u sshd | grep "192.168.64.50"出力形式変更 #
$ journalctl -o json -n 10 # 1 行 JSON
$ journalctl -o json-pretty -n 5 # 見やすい JSON
$ journalctl -o cat -n 100 # メッセージ本文のみ
$ journalctl -o short-iso -n 100 # ISO 8601 時刻-o json は自動化に有用。jq と一緒に使うと強力な分析ツールになります。
$ journalctl -o json -u nginx --since today | \
jq 'select(.PRIORITY == "3") | .MESSAGE' # err メッセージのみ抽出rsyslog — 古い標準が生きている理由 #
journald がメインですが rsyslog は依然として活発です。3 つの理由:
- 外部 SIEM (Splunk、Graylog、ELK など) 連携 — 標準の syslog プロトコルで受ける。
- リモートログ収集 — 複数ホストのログを 1 つのサーバーに集める。
- 古いテキストファイル互換 —
/var/log/messages、/var/log/secureを見る自動化 / モニタリング。
$ systemctl status rsyslog
● rsyslog.service - System Logging Service
Active: active (running)
...主要テキストログ #
rsyslog が作るおなじみのファイルたち:
| ファイル | 内容 |
|---|---|
/var/log/messages | 一般システムメッセージ |
/var/log/secure | 認証 / 権限 (sshd、sudo など) |
/var/log/maillog | メール |
/var/log/cron | cron / at ジョブ |
/var/log/boot.log | 起動ログ |
/var/log/dnf.log | パッケージ作業 |
/var/log/secure はセキュリティ点検の最初の入口。誰がいつ ssh で接続して sudo を使ったかがすべてここに残ります。
設定 — /etc/rsyslog.conf
#
# デフォルトモジュール
module(load="imuxsock") # local システムログを受ける
module(load="imjournal") # journald から受ける
# ルール (facility.priority + アクション)
*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure
mail.* -/var/log/maillog
cron.* /var/log/cron
*.emerg :omusrmsg:*ルールの左側は facility.priority (どんな種類のログを)、右側は アクション (どこへ)。facility は auth/authpriv/cron/daemon/kern/mail/user/local0~7 などがあり、priority は debug/info/notice/warning/err/crit/alert/emerg。
追加設定 — /etc/rsyslog.d/
#
要のファイルはそのまま置き、新しいルールは分離ファイルに置くのが標準です。
# 私たちのアプリが使う facility local6 だけ別ファイルに
local6.* /var/log/myapp.log$ sudo systemctl restart rsyslogリモートログ — 複数ホスト → 中央サーバー #
運用マシンが複数台ならログを 1 か所に集めるのが標準。rsyslog がこれをします。
中央サーバー (受信側) #
# UDP 514 で受信
module(load="imudp")
input(type="imudp" port="514")
# TCP も一緒に (安定性)
module(load="imtcp")
input(type="imtcp" port="514")
# ホスト別ディレクトリに分ける
$template RemoteHost,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
*.* ?RemoteHost
& stop$ sudo firewall-cmd --permanent --add-port=514/udp
$ sudo firewall-cmd --permanent --add-port=514/tcp
$ sudo firewall-cmd --reload
$ sudo systemctl restart rsyslogこれで他のホストが送ったログが /var/log/remote/<hostname>/<プログラム>.log に保存されます。
クライアント (送信側) #
# すべてのログを 192.168.64.10 に転送
*.* @192.168.64.10:514 # @ は UDP
# *.* @@192.168.64.10:514 # @@ は TCP (より安全)$ sudo systemctl restart rsyslogTLS で暗号化 (運用推奨) #
平文 syslog はネットワークで平文で流れます。運用では TLS で包むのが標準です。rsyslog-gnutls パッケージをインストールして証明書を掴み、imrelp / omrelp モジュールを使うフローを整理します。詳細なセットアップは 上級シリーズ で扱います。
logrotate — ログ回転の標準 #
テキストログファイルはそのまま放置すると GB まで大きくなります。logrotate が一定周期・サイズに到達したら回転 (名前を変えて新しいファイルを開始) + 圧縮 + 古いものの削除を自動で。
logrotate は 独立したデーモンではなく cron または systemd timer で呼ばれる ツールです。
$ systemctl list-timers | grep logrotate
NEXT LEFT LAST PASSED UNIT ACTIVATES
... ... ... ... logrotate.timer logrotate.service
$ systemctl cat logrotate.timer
[Timer]
OnCalendar=daily
AccuracySec=1h
Persistent=true毎日 1 度自動実行。古い RHEL は /etc/cron.daily/logrotate で実行しましたが RHEL 9 は systemd timer に移されました。
設定構造 #
weekly
rotate 4
create
dateext
include /etc/logrotate.d# 例: /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /run/nginx.pid ]; then
kill -USR1 $(cat /run/nginx.pid)
fi
endscript
}オプションの読み方:
| オプション | 意味 |
|---|---|
daily / weekly / monthly | 回転周期 |
rotate N | 保管する回転本数 |
compress | 回転直後に圧縮 (デフォルト gzip) |
delaycompress | 回転後にもう 1 度待って圧縮 (現在使うファイル保護) |
missingok | ファイルがなくてもエラーを出さない |
notifempty | 空なら回転しない |
create <mode> <user> <group> | 回転後の新ファイル生成権限 |
dateext | ファイル名に日付を付ける (-20260420) |
sharedscripts | 複数ファイルに 1 度だけスクリプト実行 |
postrotate 〜 endscript | 回転後に実行するコマンド (シグナル送信など) |
直接書く #
私のアプリのログを logrotate に任せるには:
/var/log/myapp/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 myapp myapp
sharedscripts
postrotate
systemctl reload myapp.service > /dev/null 2>&1 || true
endscript
}テスト / 強制実行 #
$ sudo logrotate -d /etc/logrotate.d/myapp # debug — どう回転されるかだけ出力
$ sudo logrotate -v /etc/logrotate.d/myapp # verbose — 実際の実行 + 詳細出力
$ sudo logrotate -f /etc/logrotate.d/myapp # force — 回転条件を無視して強制運用では -d でまずシミュレーション し、意図と合えばそのまま置けばよいです。timer が自動で適用します。
journald と logrotate の関係 #
/var/log/journal/ の journald ファイルは logrotate が触りません。 journald が自分のポリシー (SystemMaxUse など) で直接回転します。
logrotate は rsyslog が作るテキストログファイル (/var/log/messages など) とユーザーが作ったログファイルを扱います。journald には logrotate、rsyslog テキストには journald が触れない 2 領域の分業。
セキュリティ / コンプライアンス観点 #
運用でよく出会う要求事項:
ログ完全性 #
Seal=yes で journald 封印をオンにするとログを改ざんすると検出されます。
$ sudo journalctl --setup-keys
$ sudo journalctl --verify保管期間ポリシー #
産業・規制に応じて異なります。よくある基準:
| 環境 | 推奨保管 |
|---|---|
| 一般サーバー | 30〜90 日 |
| PCI-DSS (決済) | 1 年 |
| HIPAA (医療) | 6 年 |
| 金融 / SOX | 7 年 |
長期保管は通常リモートサーバーまたは S3・tape に移します。マシン内には短期のみ。
ログ無限増加防止 #
SystemMaxUse と MaxRetentionSec を両方掴み、logrotate の rotate N も明示。モニタリングアラートも /var/log 使用量にかけるのが標準。
AlmaLinux / Rocky の違い #
この記事のすべてのコマンドが そのまま動作 します。journald / rsyslog / logrotate は RHEL パッケージそのまま。
よく出会う落とし穴 #
「journald 永続保管をオンにしたのにディスクが満杯になる」 #
SystemMaxUse を明示的に掴まないとデフォルトはディスクの 10% まで埋まります。大きなディスクでは問題になりえます。常に明示的に上限指定。
「journalctl が古い起動ログを見せない」 #
永続保管がオンになっていない場合。/var/log/journal/ ディレクトリがあるか確認。
「rsyslog リモートサーバーにログが来ない」 #
ファイアウォール (514 UDP/TCP) と SELinux を一緒に見てください。SELinux でポートを変えたなら syslogd_port_t が合っているか確認し、必要なら semanage port で登録する必要があります。
「logrotate が回らない」 #
systemctl status logrotate.timer で timer がアクティブか確認。または logrotate -d でシミュレーションしてどのファイルがどんな理由で回転しないか見ましょう。
「回転後にアプリが新ファイルに書かず古いファイルに書き続ける」 #
アプリが SIGHUP を受けてファイルを開き直さなければならないのに、postrotate で kill -HUP または systemctl reload を抜かした場合。回転ルールに必ず reload コマンドを含めましょう。
よく使うコマンド一覧 #
| ツール | コマンド |
|---|---|
| journald | journalctl -u <unit> [-f] |
| journald | journalctl --since "1 hour ago" |
| journald | journalctl --list-boots |
| journald | journalctl --disk-usage |
| journald | journalctl --vacuum-size=500M |
| journald | journalctl _COMM=sshd (フィールド検索) |
| journald | journalctl -o json (JSON 出力) |
| rsyslog | systemctl status rsyslog |
| rsyslog | tail -f /var/log/messages |
| rsyslog | tail -f /var/log/secure |
| logrotate | logrotate -d <conf> (シミュレーション) |
| logrotate | logrotate -f <conf> (強制実行) |
| logrotate | systemctl list-timers | grep logrotate |
まとめ #
この記事で整理したフロー:
- RHEL 9 のログは journald (メイン) + rsyslog (サブ) + logrotate (回転) の 3 ツールが一緒に働きます。
- journald は永続保管 (
/var/log/journal/) を明示的にオンにし、SystemMaxUse/MaxRetentionSecでディスク上限を掴むのが標準。 - ディスクが急なときは
journalctl --vacuum-size=...で即時回収。 - 構造化ログ検索は
_COMM=/_SYSTEMD_UNIT=のようなフィールド +-o json+ jq の組み合わせ。 - rsyslog は古いテキストログ互換と リモート syslog 収集 の標準。中央サーバー + クライアントのフローは 1 ホストを越える運用の日常。
- logrotate は systemd timer で毎日実行。
/etc/logrotate.d/<app>にルールを置き、-dシミュレーション で常に検証。 - 保管ポリシーは産業・規制に応じて 30 日〜7 年、マシン外部に移すフローが一般的。
次 — ジョブスケジューリング #
ログを整理したら、次はその作業をいつ回すかへ移ります。毎日実行される logrotate 自体も systemd timer の代表的事例です。
#6 ジョブスケジューリング — cron、systemd timer、at では、伝統の cron とユーザー crontab、1 度だけ予約実行する at、マシンが切れていた時間を補う anacron、そして cron のモダンな代替である systemd timer まで — どのツールをどの状況で使うかをガイドと一緒に整理します。