はじめに (対象読者・この記事でわかること)
この記事は、Linuxサーバーの運用・保守を担当しているエンジニアや、これからサーバー管理を始めたい方を対象にしています。特に、サービス障害が発生した際に「どのログを見れば原因が特定できるか分からない」という方に最適です。
この記事を読むことで、systemd管理下のサービスログを効率的に確認する方法、リアルタイムでのログ監視の仕方、ログローテーションの仕組みを理解できます。実際の現場で使えるワンライナーコマンドや設定例も紹介するため、すぐに業務に活用できるでしょう。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。 - Linuxの基本的なコマンド操作(cd、ls、grepなど) - テキストエディタ(viまたはnano)の基本的な使い方 - サービス(デーモン)の概念の基本的な理解
なぜ効率的なログ確認が重要なのか
Linuxサーバーでサービスを運用していると、突如として「Webサイトが表示されない」「APIが応答しない」といったトラブルに見舞われることがあります。このような状況で、ログを素早く確認できないと、サービス停止時間が長引き、ビジネスに大きな影響を与えてしまいます。
従来の/var/log/messagesをgrepする方法では、大量のログの中から必要な情報を見つけるのに時間がかかります。また、複数のサービスが連携している環境では、どのログファイルを見ればよいか迷うこともあります。
本記事では、systemdのjournalctl、tailコマンドの活用法、そして長期運用に欠かせないlogrotateの設定について、実践的な観点から解説していきます。
実践的なログ確認手法の習得
ここでは、現場で即戦力となる3つのログ確認手法を詳しく解説します。それぞれの特徴を理解し、状況に応じて使い分けることで、トラブルシューティングの効率が飛躍的に向上します。
journalctlでシステムログを一括管理する
systemdを採用した最近のLinuxディストリビューションでは、journalctlコマンドが強力な味方になります。従来のように個別のログファイルを探す必要がなく、すべてのサービスログを一元管理できます。
基本的な使い方から始めましょう。
Bash# 全てのログを表示(ページャー付き) journalctl # 特定のサービスのログのみ表示 journalctl -u nginx.service # リアルタイムでのログ表示(tail -fの代替) journalctl -f -u postgresql.service # エラーのみを絞り込んで表示 journalctl -p err -u apache2.service # タイムスタンプで絞り込み journalctl -u mysql.service --since "2024-12-31 10:00:00" --until "2024-12-31 11:00:00"
journalctlの強みは、構造化されたログデータを扱えることです。ログレベル、ユニット名、メッセージフィールドなど、様々な条件で絞り込みが可能です。特に、本番環境では以下のような高度な使い方が役立ちます。
Bash# 過去1時間の重要なログを抽出 journalctl --since "1 hour ago" -p warning # 特定のプロセスIDのログを追跡 journalctl _PID=12345 # JSON形式で出力して他のツールと連携 journalctl -u myapp.service -o json | jq '.MESSAGE'
tail -f と grep の組み合わせでリアルタイム監視する
リアルタイムでのログ監視が必要な場合、tail -fとgrepの組み合わせは依然として有力な手段です。特に、従来型のログファイル(/var/log/以下)を扱う場合や、複数のキーワードを同時に監視したい場合に有効です。
基本的な監視パターンをいくつか紹介します。
Bash# 単一ファイルのリアルタイム監視 tail -f /var/log/nginx/access.log | grep ERROR # 複数ファイルを同時監視 tail -f /var/log/nginx/*.log | grep -E " (ERROR|WARN) " # 複数の条件でフィルタリング tail -f /var/log/app/application.log | grep -E " (ERROR|CRITICAL) " | grep -v "DEBUG" # タイムスタンプ付きで出力 tail -f /var/log/syslog | while read line; do echo "$(date '+%Y-%m-%d %H:%M:%S') $line"; done
本番環境では、以下のような高度な監視スクリプトも有用です。
Bash#!/bin/bash # エラー検知時にアラートを送るスクリプト LOGFILE="/var/log/application.log" KEYWORDS="ERROR|CRITICAL|FATAL" WEBHOOK_URL="https://hooks.slack.com/services/xxx" tail -f "$LOGFILE" | while read line; do if echo "$line" | grep -E "$KEYWORDS" > /dev/null; then # Slackに通知 curl -X POST -H 'Content-type: application/json' \ --data "{\"text\":\"🚨 エラー検知: $line\"}" \ "$WEBHOOK_URL" # 音で警告(オプショナル) echo -e "\a" fi done
logrotateでログローテーションを適切に設定する
長期間の運用を考えた場合、ログファイルの肥大化は避けて通れません。適切なローテーション設定を行うことで、ディスク容量の逼迫を防ぎつつ、必要な期間のログを保持できます。
基本的な設定例を見ていきましょう。
Bash# /etc/logrotate.d/custom-app の設定例 /var/log/myapp/*.log { daily rotate 30 compress delaycompress missingok notifempty create 644 appuser appgroup postrotate # ログ再開後の処理 systemctl reload myapp.service > /dev/null 2>&1 || true endscript }
重要なポイントをいくつか解説します。
rotate 30: 30世代分のログを保持(約1ヶ月分)compress: 古いログをgzip圧縮delaycompress: 1世代前のログは次回圧縮(直近のログは素早くアクセス可能)postrotate: ログローテーション後にアプリケーションに通知
journaldの設定も忘れずに行いましょう。
Bash# /etc/systemd/journald.conf の設定 [Journal] Storage=persistent SystemMaxUse=1G MaxFileSec=30day
これにより、ジャーナルログも適切に管理されます。
ハマった点やエラー解決
実際の運用でよくある問題と、それに対する解決策をいくつか紹介します。
問題1: journalctlで「-- No entries --」と表示される
これは、ジャーナルログが保存されていないか、権限がないことを示します。
解決策
Bash# ジャーナルログが有効化されているか確認 sudo systemctl status systemd-journald # ジャーナルログの保存先を確認 ls -la /var/log/journal/ # 必要に応じてジャーナルログを有効化 sudo mkdir -p /var/log/journal sudo systemd-tmpfiles --create --prefix /var/log/journal sudo systemctl restart systemd-journald
問題2: ログローテーション後にログが出力されなくなる
これは、アプリケーションがログファイルのinodeを保持している場合に発生します。
解決策
アプリケーション側でログファイルを再オープンする仕組みが必要です。シグナルを送信する方法が一般的です。
Bash# logrotate設定にUSR1シグナルを送信する設定を追加 /var/log/app/*.log { daily rotate 30 compress postrotate # nginxの場合 kill -USR1 $(cat /var/run/nginx.pid) # アプリケーションバイナリの場合 killall -USR1 myapp endscript }
問題3: 大量のログでディスクが圧迫される
予期せぬエラーで大量のログが出力され、ディスク容量を圧迫することがあります。
解決策
監視と自動削除の設定を行います。
Bash#!/bin/bash # 緊急時用のログクリーンアップスクリプト LOG_DIR="/var/log/myapp" THRESHOLD=90 # ディスク使用率の閾値 usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//') if [ $usage -gt $THRESHOLD ]; then echo "$(date): ディスク使用率 ${usage}% 。古いログを削除します。" # 最も古いログファイルを特定して削除 find "$LOG_DIR" -name "*.log.*" -type f -mtime +7 -delete # journalログもクリーンアップ journalctl --vacuum-time=3d fi
まとめ
本記事では、Linuxサーバーのサービスログを効率的に確認する3つの手法を紹介しました。
- journalctlを活用することで、systemd管理下のサービスログを一元管理できる
- tail -fとgrepの組み合わせで、リアルタイムかつ柔軟なログ監視が可能
- logrotateの適切な設定で、長期運用に必要なログ管理が実現できる
この記事を通して、トラブル発生時のログ確認時間を大幅に短縮でき、システムの安定運用に貢献できるでしょう。特に、journalctlの高度なフィルタリング機能と、リアルタイム監視スクリプトは、日々の運用業務で即効果を発揮します。
今後は、これらのログ確認手法を活用した、より高度な監視システムの構築についても記事にする予定です。ログ集約基盤(ELKスタック等)との連携方法についても、実践的な観点から解説していきます。
参考資料
