障害対応の速さは,ログを追えるかどうかでほぼ決まる.「いつ・何が・なぜ壊れたか」がログから再構成できれば対応は数分,できなければ数時間さまよう.ログ管理は運用の生命線だ.

ところが多くの個人開発者は,ログを「出しっぱなしで放置」している.その結果,いざという時に肝心のログが消えていたり,逆にログでディスクが溢れてサービスごと落ちたりする.

この記事は,VPSでサービスを運用する個人開発者,障害のたびに原因究明で消耗するエンジニアに向けている.journaldの実践的な使い方から,logrotateでのディスク保護,ログ集約の考え方までを解説する.

読み終えたとき,あなたのサーバーは「必要なログが残り,ディスクは溢れず,障害時に原因を追える」状態になっている.

なぜログ管理が障害対応の生命線なのか

ソフトウェアは必ず壊れる.重要なのは壊れた後に「何が起きたか」を再構成できるかだ.それを可能にする唯一の証拠がログである.

ログが無い・消えていると,原因究明は推測と当てずっぽうになる.再現させようにも条件が分からず,同じ障害を何度も繰り返す羽目になる.

一方でログを無制限に出し続けると,今度はディスクを食い尽くす.ディスク満杯はサービス停止の典型原因であり,「ログのせいでサービスが落ちる」という本末転倒が現実に起きる.

つまりログ管理とは,「必要な情報を残しつつ,量を制御する」バランスの技術だ.これを仕組みで実現することが,安定運用の条件になる.

ログはどこにあるか ― journaldと/var/logの全体像

現代のVPS(systemd環境)では,ログは大きく2系統ある.systemd管理のサービスログはjournaldに,従来型のサービスやアプリは/var/log/配下のファイルに出力される.

まずこの地図を持っておくと,「どこを見ればいいか」で迷わなくなる.多くの場合,最初に見るべきはjournaldだ.

ログの場所内容
journalctlsystemdサービス全般・カーネル・起動ログ
/var/log/syslog (or messages)システム全般のメッセージ
/var/log/auth.log (or secure)認証・SSH・sudoの記録
/var/log/nginx/Nginxのアクセス・エラーログ
アプリ独自のログアプリが指定した出力先

journalctl実践 ― 必要なログを瞬時に抽出する

journaldのログはjournalctlで自在にフィルタできる.障害対応では「サービス・期間・重要度」で素早く絞り込むのが鍵だ.

障害調査で使うjournalctl

journalctl -u myapp --since "2026-07-10 03:00" --until "03:30"
journalctl -u myapp -p err -b           # 今回起動以降のエラー
journalctl -k                            # カーネルログ(OOM等)
journalctl -f -u myapp                    # リアルタイム追従
journalctl --since "10 min ago" -p warning

とくに-p err(エラー以上)と--since(期間)の組み合わせが強力だ.「障害が起きた時間帯のエラーだけ」を一発で抜き出せる.メモリ不足でアプリが殺された(OOM Killer)疑いがあるときはjournalctl -kでカーネルログを確認する.

ログを永続化する(再起動で消さない)

journaldは既定で再起動するとログが消える設定のことがある.障害解析のために永続化しておこう./var/log/journalを作るだけで永続化が有効になる.

journaldログの永続化

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --list-boots   # 過去の起動が残るか確認

logrotate ― ディスクを溢れさせない仕組み

/var/log/に出るファイル形式のログ(Nginx・アプリ独自ログ等)は,放置すると無限に肥大化する.これを自動で分割・圧縮・削除するのがlogrotateだ.

多くのパッケージは自前のlogrotate設定を持つが,アプリ独自のログは自分で設定を書く必要がある.これを怠ると,ある日突然ディスク満杯でサービスが落ちる.

/etc/logrotate.d/myapp

/home/deploy/app/logs/*.log {
    daily               # 毎日ローテート
    rotate 14           # 14世代保持
    compress            # 古いものはgzip圧縮
    delaycompress
    missingok           # ファイルが無くてもエラーにしない
    notifempty
    copytruncate        # アプリを止めずに切り詰める
}

copytruncateは重要なオプションだ.アプリがログファイルを開きっぱなしの場合,普通にローテートするとアプリが古いファイルに書き続けてしまう.copytruncateは「コピーしてから元ファイルを空にする」ため,アプリを再起動せずにローテートできる.設定後はlogrotate -d /etc/logrotate.d/myapp(デバッグ)で動作を確認する.

アプリログの設計 ― 何を・どの粒度で残すか

ログは多ければ良いわけではない.「障害時に原因を特定できる最小限」を狙う.ノイズが多いと肝心の情報が埋もれ,少なすぎると追えない.

ログレベルを使い分ける

ERROR(対応が要る異常)・WARN(注意)・INFO(通常の動作記録)・DEBUG(詳細)を意識的に使い分ける.本番はINFO以上を出し,DEBUGは問題調査時だけ有効にするのが定石だ.

重要なのはエラー時に「いつ・どの処理で・どんな入力で・何が起きたか」が分かること.スタックトレースとリクエストIDを残すと,原因追跡が劇的に速くなる.

構造化ログ(JSON)を検討する

ログをJSON形式(構造化ログ)で出すと,後で集約・検索・集計がしやすい.人間が読むだけなら素のテキストでよいが,将来ログ集約基盤に流すなら構造化しておくと効く.

ログ集約の考え方 ― 複数サーバー・将来の拡張

サーバーが1台のうちは各サーバーでjournalctlを見れば足りる.だが複数台・コンテナ多数になると,1箇所にログを集める必要が出てくる.これがログ集約だ.

個人開発で最初から重厚な集約基盤を組む必要はない.だが「ログが各所に散らばって追えない」状態になったら,集約を検討するサインだ.

規模推奨アプローチ
1台journalctl + /var/log を直接見る
数台/コンテナLoki+Grafana 等で集約・横断検索
本格運用専用のログ基盤・外部サービス

軽量なログ集約としてはLoki + Grafanaの組み合わせが個人開発でも扱いやすい(本シリーズの別記事で詳説予定).まずは1台で確実にログを残し,必要になったら集約へ進む,という順序が現実的だ.

監査ログ ― セキュリティの観点で残すべきもの

障害解析だけでなく,セキュリティの観点でもログは重要だ./var/log/auth.log(認証ログ)には,SSHログイン試行・sudo実行・認証失敗が記録される.

不審なアクセスの兆候(深夜の大量ログイン失敗・見覚えのないsudo)を早期に発見するために,認証ログは定期的に眺める習慣を持ちたい.fail2banと組み合わせれば,怪しいアクセスを自動でブロックもできる.

認証ログから不審な動きを探す

# ログイン失敗の多いIPを集計
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
# sudoの実行履歴
sudo grep sudo /var/log/auth.log | tail

補論:ログ運用は「速いディスクと十分な容量」で安定する

ログ管理の安定は,ディスクの速度と容量に支えられる.ログの書き込み・検索が遅いと障害対応そのものが遅れるし,容量に余裕がないとlogrotateを設定しても綱渡りになる.

高速NVMe・50種類以上のOSテンプレートに対応した国内VPS─シン・VPS─ はNVMe SSDでjournalctlの検索やログ書き込みが軽快に動き,プラン選択で十分なストレージを確保できる.スナップショットを取っておけば,ログ設定やlogrotateの調整を安全に試せるのも実務で効く.

ログから得た知見(障害の傾向・アクセス分析)を独自ドメインのダッシュボードでまとめたくなったら,取り扱い400種類以上のドメイン取得サービス─ムームードメイン─ で取得したドメインをVPSに割り当てると運用が整理しやすい.

よくある質問(FAQ)

Q1.まずどのログを見ればいい?

systemd環境ならまずjournalctl -u サービス名 -p errでエラーを確認する.Webならば/var/log/nginx/error.log,認証問題なら/var/log/auth.log,メモリ不足の疑いならjournalctl -k(カーネル)だ.

Q2.ディスクがログで一杯になった

緊急対応は古いログの削除(journalctl --vacuum-size=200M等).恒久対策はjournaldの上限設定とlogrotateの導入だ.アプリ独自ログにはlogrotate設定を必ず書く.

Q3.ログを再起動後も残したい

journaldは/var/log/journalディレクトリを作ると永続化される.これをしないと再起動でログが消え,起動前後にまたがる障害の解析ができない.

Q4.アプリのログは何を残すべき?

エラー時に原因を特定できる最小限だ.エラーレベル・発生時刻・処理名・入力の要約・スタックトレース・リクエストIDがあると追跡が速い.通常時のINFOは出しすぎないこと.

Q5.ログ集約基盤は最初から要る?

1台なら不要.journalctlと/var/logで十分だ.複数台・コンテナ多数でログが散らばり追えなくなったら,Loki+Grafana等の集約を検討する,という順序でよい.

Q6.copytruncateとは何のため?

アプリがログファイルを開いたままの場合,普通のローテートだとアプリが古いファイルに書き続ける.copytruncateはコピー後に元を空にするため,アプリを再起動せずにローテートでき,ログの取りこぼしを防ぐ.

まとめ ― ログを制する者が障害対応を制する

ログ管理の要点は,journaldで追え,logrotateで溢れさせず,必要な情報を適切な粒度で残すこと.この3点が揃えば,障害時に「いつ何が起きたか」を必ず追える.

今日やるべきことは,journaldを永続化し,アプリ独自ログにlogrotate設定を1つ書くこと.この2つだけで,「肝心のログが消えていた」「ログでディスクが溢れた」という両方の事故を防げる.

ログは平時には地味だが,障害時には命綱になる.スナップショットで戻せるVPSがあれば,ログ設定の調整も恐れずに試せる.