サーバー運用を始めると、意外と早い段階で困るのが ログが増え続ける 問題です。
最初は数MBでも、Web サーバー、アプリ、ジョブ、エラー出力が重なると、あとから確認しづらくなります。
そこで出てくるのが ログローテーション です。
Linux では logrotate を使う場面が多いですが、最近は systemd-journald と journalctl 側で管理するログもあるので、まずはその違いから整理すると迷いにくいです。
先に要点
- ログローテーションは、ログを切り替えて圧縮・世代管理する仕組み
- 放置すると容量圧迫だけでなく、障害調査もしにくくなる
- テキストログは
logrotate、ジャーナルログはsystemd-journald側を見ることが多い copytruncateやdelaycompressは便利だが、仕組みを知らずに使うとハマりやすい
ログローテーションとは何か
ログローテーションは、1本のログファイルを延々と太らせず、一定のタイミングで区切って管理する仕組みです。
たとえば app.log を app.log.1 app.log.2.gz のように切り替えていくイメージです。
この仕組みが必要になる理由は、単純に ログが増えるから だけではありません。
実務では次の3つがかなり大きいです。
1. ディスクを圧迫しにくくする
放置するとログだけで容量を使い切ることがあります。特にアクセスログやバッチログは増え方が速いです。
2. 障害調査しやすくする
古いログを何世代残すか決めておくと、昨日の障害や先週の異常を追いやすくなります。
3. 運用の見通しをよくする
圧縮、保存期間、削除タイミングが決まっていると、容量見積もりや保守がかなり楽になります。
まず分けたいのは「テキストログ」と「ジャーナルログ」
初心者がつまずきやすいのは、Linux のログ管理は1種類ではない ことです。
テキストログ
/var/log/nginx/access.log/var/log/app/app.log/var/log/secure
このような普通のファイルとして出ているログは、logrotate で回すことが多いです。
ジャーナルログ
systemd 環境では、systemd-journald が持つジャーナルにログが保存されることがあります。
この場合は、journalctl で見たり、journald.conf 側で保持量を調整したりします。
ここを混ぜると、logrotate を触ったのに効かない みたいな混乱が起きやすいです。
logrotate でよく見る基本設定
Ubuntu の man page でも、logrotate は設定ファイルをもとにログの切り替え、圧縮、世代管理を行うツールとして説明されています。
よく使う設定は次のあたりです。
| 設定 | 意味 |
|---|---|
daily / weekly |
どの頻度でローテーションを判定するか |
rotate 7 |
何世代残すか |
compress |
古いログを圧縮する |
delaycompress |
直前の世代はすぐ圧縮せず、次回ローテーション時に圧縮する |
missingok |
ログがなくてもエラーにしない |
notifempty |
空ファイルなら回さない |
create |
ローテーション後に新しい空ログを作る |
設定例をかなり素直に書くと、こんな形です。
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
}
14日分くらい残したい 空ログは無視したい 直前世代はすぐ gzip したくない というときの、かなりよくある形です。
設定時に特に注意したいポイント
1. copytruncate は便利だが、雑に使わない
copytruncate は、元ファイルをコピーしてから元を空にする設定です。
アプリがファイルハンドルを持ち続けていても動かしやすいので、つい使いたくなります。
ただし、ログを書き込み中にコピーと切り詰めが走るので、完全にきれいな切り替えにはなりません。
書き込みが激しいログでは、取りこぼしや重複の可能性を意識した方が安全です。
Ubuntu の man page でも、copytruncate と通常の rename ベースの挙動は別物として扱われています。
再オープン対応できないアプリだから仕方なく使う くらいの感覚がちょうどいいです。
2. compress と delaycompress を分けて考える
compress だけ入れると、ローテーション直後のログもすぐ圧縮されます。
一方で delaycompress を併用すると、ひとつ前の世代は生のまま残せます。
これは、昨日のログはよく見るから plain text のまま残したい という運用でかなり便利です。
逆に、圧縮タイミングを理解しないまま使うと、なんでまだ gzip されていないの? で混乱しやすいです。
3. 世代数だけでなく「何日見たいか」を先に決める
rotate 7 と書くときも、7という数字がきれいだから ではなく、最低1週間は見返したい のように先に運用理由を置いた方が失敗しにくいです。
監視や障害対応まで含めて見るなら、監視はどこまで必要?死活監視・ログ監視・通知設計の基本を実務目線で解説 もつながりやすいです。
4. dry-run で先に確認する
設定を書いたあと、いきなり本番で任せきりにするのは少し怖いです。
logrotate -d で dry-run して、どのファイルがどう扱われるかを見るだけでも事故を減らしやすくなります。
sudo logrotate -d /etc/logrotate.conf
強制的に回したい確認用としては -f もあります。
sudo logrotate -f /etc/logrotate.conf
ただし本番で -f を使うと想定より早く世代が進むので、確認目的でもタイミングは見た方がよいです。
journalctl と systemd-journald 側の考え方
一方で、systemd のジャーナル側は少し考え方が違います。
Freedesktop の journald.conf では、SystemMaxUse= や SystemMaxFileSize= などで保持量を制御できます。
つまり、テキストログのように daily rotate 7 と書くのではなく、どこまで容量を使ってよいか を決める発想に近いです。
まず確認しやすいのはこのあたりです。
journalctl --disk-usage
journalctl --rotate
journalctl --vacuum-size=500M
ここで大事なのは、logrotate の設定をいくら触っても、ジャーナルログには効かないことです。
逆に journald.conf を触っても、/var/log/myapp/app.log のような普通のテキストログは回りません。
実務ではどこまでやるべきか
実務だと、最初はこのくらいの考え方で十分です。
- テキストログは
logrotateで日次または週次の世代管理を入れる - ジャーナルは
journalctl --disk-usageで容量感を見て、必要ならjournald.confを調整する - 書き込みが激しいアプリログは
copytruncateを安易に入れず、再オープン手順も検討する - 保持日数と圧縮タイミングは、障害対応で何日見返すかから決める
サーバーを立てた直後の土台づくり全体を見直したいなら、Linuxサーバーの初期設定で最初にやることは?見直したい項目を実務目線で整理 もかなり相性がいいです。
まとめ
ログローテーション は、ログを切り替えて圧縮・世代管理し、容量と調査性を両立させるための基本運用です。
普通のテキストログなら logrotate、systemd のジャーナルなら systemd-journald と journalctl を見る、と切り分けるだけでもかなり分かりやすくなります。
設定で大事なのは、rotate いくつにするか だけではありません。
何日見返したいか、すぐ圧縮していいか、アプリがログファイルをどう扱うか まで見ておくと、あとから困りにくいです。
まずは daily / rotate / compress / missingok / notifempty あたりを理解して、必要なら copytruncate やジャーナル側の容量制御に進む、くらいが入りやすい順番です。
参考リンク
- Ubuntu Manpage: logrotate(8)
- systemd: journalctl
- systemd: journald.conf