サービスを運用していると、エラーがいつ発生したかを特定するためにログを調べる機会は少なくありません。一方で、過去ログを遡るだけでは「今まさに何が起きているか」を把握しにくい場面があります。ログの末尾をリアルタイムで追跡する手法を身につけておくと、コマンド実行直後やリクエスト到達の瞬間にどのような記録が残るかをその場で確かめられます。
ログのリアルタイム追跡が役立つ場面
ログファイルは時間とともに追記されていきます。ファイルを静的に開いて確認するだけでは、以降に書き込まれる行を見ることができません。リアルタイム追跡は、次のような場面で特に効果を発揮します。
- 設定変更後にサービスを再起動し、エラーログが出ないかすぐに確かめたいとき
- 外部からリクエストを送信しながら、アクセスログや応答コードを即座に観察したいとき
- 夜間バッチの進捗をターミナルで追いかけながら完了を待つとき
- 障害が疑われる環境で、ログが流れているかどうかを目視で確かめたいとき
tail -f でファイルの末尾を追跡する
tail -f はファイルへの追記をリアルタイムで表示する基本的なコマンドです。-f オプションはファイルの終端まで出力したあとも処理を続け、新しい行が書き込まれるたびに画面に反映します。
tail -f /var/log/syslog
追跡を終了するには Ctrl+C を押します。追跡開始時に表示する行数を増やしたいときは -n を組み合わせます。次の例では末尾から 50 行を表示した状態で追跡を始めます。
tail -n 50 -f /var/log/syslog
ローテーション後も継続して追跡する(-F オプション)
ログローテーションが設定されている環境では、ファイルが一定のサイズや日時を境に切り替わります。-f(小文字)はファイルの iノードを監視するため、ファイルが入れ替わった瞬間に旧ファイルを追い続けてしまうことがあります。ファイル名で追跡し直す動作が必要な場合は -F(大文字)を使います。
tail -F /var/log/nginx/access.log
「truncate 型」のローテーション(同じファイル名のまま内容だけ空にして書き直す方式)にも -F は有効です。ローテーションの方式が不明な場合は、最初から -F を使っておくと安心です。
systemd 環境では journalctl -f を使う
最近のディストリビューションでは、systemd の journald がログを一元管理しています。/var/log/ 以下のテキストファイルではなく、バイナリ形式のジャーナルに記録されるケースが増えているため、tail -f では追跡できないサービスも出てきます。そのような場合は journalctl -f を使います。
journalctl -f
特定サービスのログだけを追跡するには -u(unit)オプションでサービス名を指定します。
journalctl -f -u nginx
複数のサービスをまとめて追跡したいときは -u を重ねます。
journalctl -f -u nginx -u php-fpm
優先度でフィルタリングするには -p オプションを使います。err 以上(crit・alert・emerg を含む)のログだけを表示する例です。
journalctl -f -p err
優先度は emerg・alert・crit・err・warning・notice・info・debug の順で定義されており、-p err と指定すると err より深刻なレベルも含まれます。
grep と組み合わせてエラーだけを絞り込む
アクセス数の多いサーバーではログの流量が多く、画面が次々と更新されて必要な情報を見失いやすくなります。grep をパイプでつなぐと、特定のキーワードを含む行だけを絞り込んで表示できます。
tail -f /var/log/syslog | grep -i "error"
-i は大文字・小文字を区別しないオプションです。Error・ERROR・error のいずれにも一致します。複数のキーワードを OR 条件で指定するには -E と | を組み合わせます。
tail -f /var/log/syslog | grep -iE "error|warn|critical"
一致した箇所をカラーで強調したいときは --color=always を付けます。ターミナルの見た目が改善され、流れの速いログの中でも該当行を素早く見つけられます。
tail -f /var/log/syslog | grep --color=always -iE "error|warn"
journalctl -f との組み合わせも同様の書き方で動作します。HTTP ステータスコードを条件にする場合の例です。
journalctl -f -u nginx | grep -iE "502|504"
複数ファイルを同時に追跡する
nginx のように access ログと error ログを別ファイルに分けて記録するサービスでは、tail -f に複数のパスを渡すと一括して追跡できます。
tail -f /var/log/nginx/access.log /var/log/nginx/error.log
どのファイルからの出力かを区別するため、ファイルが切り替わるタイミングで ==> ファイル名 <== という見出し行が自動で挿入されます。複数のログを見比べながら原因を絞り込みたいときに便利です。
よくあるつまずきと対処
追記されているのに画面が更新されない
ログローテーション後に画面が止まる場合は、-f から -F への切り替えを試してください。-f はファイルの iノードを監視しているため、ローテーションでファイルが入れ替わると旧ファイルを追い続け、新しいファイルへの書き込みを拾えなくなります。
Permission denied が出る
/var/log/ 以下のファイルは root または特定グループ(adm など)が所有しているケースが多いです。一時的に確認するだけであれば sudo を付けるのが手軽です。
sudo tail -f /var/log/syslog
一般ユーザーで継続的に読めるようにするには、そのユーザーをロググループに追加する方法が一般的です。Debian 系では adm、RHEL 系では adm または systemd-journal が使われることが多いです。グループへの追加後は再ログインが必要です。
grep と組み合わせると表示が遅れる
grep はデフォルトで出力をバッファリングします。パイプでつないだときに表示が遅れる場合は、--line-buffered オプションを付けると行単位でフラッシュされ、遅延を解消できます。
tail -f /var/log/syslog | grep --line-buffered -i "error"
journalctl で "No journal files were found" と出る
journald が停止しているか、ジャーナルの保存先が変わっている可能性があります。次のコマンドでサービスの状態を確認できます。
systemctl status systemd-journald
/etc/systemd/journald.conf の Storage= が none になっていると、ジャーナルへの書き込み自体が無効化されています。persistent または auto に変更して journald を再起動すると解決することがあります。再起動後は journalctl -f で追跡できるかどうかを確認できます。
「コマンドは打てる。次は"現場で通用する型"を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
