- 技術 💻
tail -f・less +Fでログ監視|grep絞り込みと操作キー一覧
tail -f とは、ファイルの末尾に追記された行をリアルタイムに表示し続けるコマンドです。 ログを眺めながら動作を確かめたいときの定番で、tail -f app.log と打つだけで使えます。似た働きをするものに tail -F、less +F、journalctl -f があり、「ローテーションをまたいで追えるか」「さかのぼって読めるか」で使い分けます。
この記事では、Ubuntu 24.04(GNU coreutils 9.4 の tail、less 590、GNU grep 3.11 系)で実際にコマンドを動かし、その出力をそのまま載せています。ログローテーションで tail -f の表示が止まる様子と、tail -F で追い続けられる様子を同じ条件で再現しました。あわせて less の操作キー早見表、grep・awk と組み合わせるワンライナー集、複数ファイルの同時監視、head と tail -n +N による切り出しまで、1ページでそろえます。
ログ監視コマンドの早見表
まずは「やりたいこと」から引ける一覧です。迷ったら tail -F、読み返しもしたいなら less +F と覚えると選びやすくなります。
| やりたいこと | コマンド | ポイント |
|---|---|---|
| 末尾10行を見る | tail app.log |
既定は10行 |
| 末尾N行を見る | tail -n 50 app.log |
-50 と書いても同じ |
| 追記をリアルタイムに追う | tail -f app.log |
Ctrl+C で終了 |
| ローテーション後も追い続ける | tail -F app.log |
--follow=name --retry と同じ |
| 過去分は出さず、これからの行だけ | tail -n 0 -F app.log |
起動直後の10行を省く |
| 追いながら読み返しもする | less +F app.log |
Ctrl+C で通常モード、F で再開 |
| 特定の文字列だけ追う | tail -F app.log | grep --line-buffered ERROR |
パイプを重ねるときは --line-buffered |
| ERROR を赤く表示して追う | tail -F app.log | awk '/ERROR/{print "\033[31m" $0 "\033[0m"; next} {print}' |
全行を残して色だけ付ける |
| 複数ファイルを同時に追う | tail -F a.log b.log |
==> a.log <== の見出しが付く |
| systemd のログを追う | journalctl -f -u nginx |
サービス単位で絞れる |
| 先頭N行を見る | head -n 20 app.log |
既定は10行 |
| N行目から最後まで | tail -n +100 app.log |
+ を付けると「先頭から数えてN行目以降」 |
| 4〜6行目だけ | sed -n '4,6p' app.log |
head -n 6 | tail -n 3 でも可 |
| プロセス終了と同時に監視も終える | tail -f --pid=1234 app.log |
バッチの完了待ちに便利 |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「tail -f・less +Fでログ監視|grep絞り込みと操作キー一覧」
tail -f・tail -F・less +F・journalctl -f の違い
4つはどれも「追記を追う」コマンドですが、得意な場面が違います。違いが出るのは「ファイルが入れ替わったとき」と「過去を読み返したいとき」の2点です。
| 比較項目 | tail -f | tail -F | less +F | journalctl -f |
|---|---|---|---|---|
| 対象 | ファイル | ファイル | ファイル | systemd ジャーナル |
| 追う相手 | 開いたファイルそのもの(ディスクリプタ) | ファイル名 | 開いたファイルそのもの(--follow-name 指定で名前) |
ジャーナル全体 |
| リネーム型ローテーション後 | 旧ファイルを追い続ける(新しい行は出ない) | 新ファイルへ自動で切り替え | 既定では旧ファイル。--follow-name で切り替え |
影響なし |
| ファイルがまだ無いとき | エラーで終了 | 現れるまで待つ | エラー | 対象外 |
| さかのぼって読む | 端末のスクロール頼み | 端末のスクロール頼み | Ctrl+C で自由にスクロール・検索 | Ctrl+C 後に journalctl で再表示 |
| 検索・絞り込み | パイプで grep | パイプで grep | / 検索、& フィルタ |
-u -p -g で絞り込み |
| パイプに流せる | できる | できる | 向かない(対話用) | できる |
| 複数ファイル | できる(見出し付き) | できる(見出し付き) | :n で切り替え(同時表示はしない) |
-u を複数指定 |
選び方の目安は次のとおりです。
| 場面 | 向いているコマンド | 理由 |
|---|---|---|
| 数分だけ様子を見る | tail -f |
最短で打てる |
| 長時間つけっぱなしにする | tail -F |
ローテーションをまたげる |
| エラーが出たら止めて前後を読む | less +F |
終了せずに検索・スクロールへ移れる |
| grep や awk に流して加工する | tail -F |
パイプとの相性がよい |
| systemd 管理のサービス | journalctl -f -u サービス名 |
ファイルの場所を知らなくてよい |
なお、今回の検証環境はコンテナで systemd が動いていないため、journalctl -f の動作は実行できていません(journalctl -n 2 は No journal files were found. を返しました)。journalctl の記述は systemd の公式マニュアルで確認した内容です。絞り込みオプションの詳細は、既存記事「journalctlの使い方|目的別コマンド逆引き一覧と絞り込み例」にまとめています。
tail -f の基本的な使い方
末尾を追う・行数を指定する
# 末尾10行を表示し、そのまま追記を待つ
tail -f app.log
# 末尾50行から始める
tail -n 50 -f app.log
# 過去の行は出さず、いまから追記される行だけを見る
tail -n 0 -f app.log
終了は Ctrl+C です。-n 0 は、再起動の直前に仕掛けておいて「これから出る行だけ見たい」ときに役立ちます。
よく使うオプション一覧
tail --help(coreutils 9.4)で確認できる主なオプションです。
| オプション | 意味 | 使いどころ |
|---|---|---|
-n NUM |
末尾 NUM 行を表示(既定10) | -n 100 |
-n +NUM |
先頭から NUM 行目以降を表示 | ヘッダー行を飛ばす |
-c NUM |
末尾 NUM バイトを表示 | 1行が非常に長いログ |
-f |
追記を追う(--follow=descriptor) |
短時間の確認 |
-F |
--follow=name --retry と同じ |
ローテーションをまたぐ |
--retry |
開けないファイルを開けるまで試し続ける | まだ作られていないログ |
--pid=PID |
指定プロセスが終わったら tail も終了 | バッチの完了待ち |
-s N |
確認間隔を約 N 秒にする | 更新頻度を下げたいとき |
-q |
複数ファイルでも見出しを出さない | 連結して加工したいとき |
-v |
1ファイルでも見出しを出す | どのファイルか明示したいとき |
--pid の例です。バッチ処理(PID 1234)が終わると、tail も自動で終わります。
tail -f --pid=1234 batch.log
ログローテーションで tail -f が止まる現象を再現する
長くつけたままの tail -f が、ある時刻から何も表示しなくなることがあります。多くの場合、ログローテーションでファイルが入れ替わったことが理由です。実際に再現してみます。
再現スクリプト
0.1秒ごとに1行ずつ app.log に追記し(毎回ファイルを開き直す書き方)、途中で mv によってファイル名を変えます。tail -f と tail -F を同時に走らせ、それぞれの出力を別ファイルに保存します。
#!/bin/bash
# 0.1秒ごとに追記(40行)
( i=0; while [ $i -lt 40 ]; do i=$((i+1)); echo "line $i" >> app.log; sleep 0.1; done ) &
W=$!
sleep 0.35
tail -f app.log > out_f.txt 2> err_f.txt & T1=$!
tail -F app.log > out_F.txt 2> err_F.txt & T2=$!
sleep 1.2
mv app.log app.log.1 # ここがローテーション(リネーム)
wait $W; sleep 1.5
kill $T1 $T2
echo "--- tail -f"; wc -l < out_f.txt; tail -n 3 out_f.txt
echo "--- tail -F"; wc -l < out_F.txt; tail -n 3 out_F.txt; cat err_F.txt
wc -l app.log app.log.1
実行結果
--- tail -f
16
line 14
line 15
line 16
--- tail -F
40
line 38
line 39
line 40
tail: 'app.log' has become inaccessible: No such file or directory
tail: 'app.log' has appeared; following new file
24 app.log
16 app.log.1
40 total
tail -f は16行目で表示が止まり、tail -F は40行すべてを表示しました。 エラーメッセージは出ないまま止まるので、気づきにくいのが特徴です。
なぜ止まるのか
tail -f は、起動時に開いたファイルそのもの(ファイルディスクリプタ)を追います。mv で名前が app.log.1 に変わっても、追っている相手は同じ実体のままです。一方、アプリケーションは新しい app.log を作って書き込むので、tail が見ているファイルと、書き込まれているファイルが別物になります。
flowchart LR
A[アプリ] -->|ローテーション前| L1[app.log 実体A]
T1[tail -f] --> L1
A -->|ローテーション後| L2[app.log 実体B 新規]
L1 -.名前だけ変更.-> R[app.log.1 実体A]
T1 -.追い続ける.-> R
T2[tail -F] -->|名前で追い直す| L2
tail -F は「ファイル名」を見張っているため、同じ名前のファイルが作り直されると has appeared; following new file と表示して、新しいほうへ切り替えます。
| 状況 | tail -f の動き | tail -F の動き |
|---|---|---|
| ファイルに追記される | 追う | 追う |
mv でリネームされ、同名の新ファイルができる |
旧ファイルを追い続ける | 新ファイルに切り替える |
| ファイルが削除され、あとで作り直される | 削除済みの実体を持ったまま | 現れた時点で追い始める |
| 起動時にファイルがまだ無い | No such file or directory で終了 |
作られるまで待つ |
| 中身が切り詰められる(copytruncate) | file truncated と表示して先頭から追う |
同じ |
copytruncate 方式の場合
logrotate の copytruncate は、ファイルをコピーしたあと元ファイルを空にする方式で、ファイルの実体は変わりません。この場合は tail -f のままでも追い続けられます。確かめた結果です。
seq 1 5 | sed 's/^/old /' > ct.log
tail -f ct.log &
cp ct.log ct.log.1; : > ct.log # コピーして空にする
echo "new 1" >> ct.log
echo "new 2" >> ct.log
old 1
old 2
old 3
old 4
old 5
tail: ct.log: file truncated
new 1
new 2
ローテーション方式がどちらか分からないときは、最初から tail -F を使えば両方に対応できます。 ローテーションの設定そのものは、既存記事「logrotateの設定方法|コピペ用テンプレートとディレクティブ一覧」で扱っています。
less +F で「追う」と「読み返す」を行き来する
tail -f はエラーを見つけたあと、前後を読むために一度終了して別のコマンドを打ち直すことになります。less +F なら、追跡と閲覧を1つの画面で切り替えられます。
less +F app.log
画面の最下行に Waiting for data... (interrupt to abort) と表示され、追記が流れます。
| 操作 | 動き |
|---|---|
| Ctrl+C | 追跡を止めて通常モードへ(スクロール・検索ができる) |
F(Shift+f) |
追跡を再開 |
q |
less を終了 |
通常の less app.log で開いたあとに F を押しても同じ追跡モードに入れます。+F は「起動直後に F コマンドを実行する」という指定です。
less の操作キー早見表
less 590 の less --help をもとに、ログ閲覧でよく使うキーをまとめました。
| 分類 | キー | 動き |
|---|---|---|
| 移動 | j / k(↓ / ↑) |
1行進む / 戻る |
| 移動 | Space / b |
1画面進む / 戻る |
| 移動 | d / u |
半画面進む / 戻る |
| 移動 | g / G |
先頭へ / 末尾へ |
| 移動 | 100g |
100行目へ |
| 移動 | 50% |
全体の50%の位置へ |
| 検索 | /pattern |
下方向に検索 |
| 検索 | ?pattern |
上方向に検索 |
| 検索 | n / N |
次の一致へ / 逆方向の一致へ |
| 検索 | Esc のあと u |
検索ハイライトの表示を切り替える |
| フィルタ | &pattern |
一致する行だけを表示 |
| フィルタ | &!pattern |
一致しない行だけを表示 |
| フィルタ | & のあと Enter |
フィルタを解除 |
| 追跡 | F |
末尾を追い続ける(tail -f 相当) |
| 追跡 | Esc のあと F |
追いながら、検索パターンが現れたら止まる |
| 表示 | -N |
行番号の表示を切り替える |
| 表示 | -S |
長い行を折り返さず1行で表示(←→で横スクロール) |
| 表示 | -i |
検索で大文字小文字を区別しない(小文字だけのパターン時) |
| しるし | ma / 'a |
現在位置に a というしるしを付ける / そこへ戻る |
| ファイル | :n / :p |
次のファイル / 前のファイル |
| その他 | v |
エディタで開く |
| その他 | h / q |
ヘルプ / 終了 |
-N や -S は、起動時のオプションとしても、起動後のキー操作としても使えます。
# 行番号つき・折り返しなし・色コードを解釈して開く
less -N -S -R app.log
| 起動オプション | 意味 | 使いどころ |
|---|---|---|
-N |
行番号を表示 | 「何行目」と人に伝えるとき |
-S |
長い行を折り返さない | JSON や長いスタックトレース |
-R |
色のエスケープシーケンスを解釈 | grep --color=always の結果を読むとき |
-i |
検索で大文字小文字を区別しない | error で ERROR も探す |
-F |
1画面に収まるなら即終了 | 短い出力を less に流すとき |
-X |
終了時に画面をクリアしない | 読んだ内容を端末に残す |
+G |
末尾から開く | 最新の行をまず見る |
+/pattern |
最初の一致位置から開く | less +/ERROR app.log |
--follow-name |
F での追跡をファイル名基準にする | ローテーションをまたぐ |
小文字の -F(1画面なら終了)と、コマンドの +F(追跡)は別物です。- は表示オプション、+ は起動時に実行するコマンドと覚えると混ざりません。
& フィルタで ERROR 行だけを追う
less の & は、一致した行だけを表示するフィルタです。追跡モードと組み合わせると、tail -f | grep と同じことが less の中で完結します。次のログを例にします。
2026-10-02 10:00:01 INFO order id=1
2026-10-02 10:00:02 WARN order id=2
2026-10-02 10:00:03 INFO order id=3
2026-10-02 10:00:04 ERROR order id=4
(20行目まで同じ並び)
less -N s.log で開き、&ERROR と入力して Enter を押したときの画面です(tmux で画面を取得)。
4 2026-10-02 10:00:04 ERROR order id=4
8 2026-10-02 10:00:08 ERROR order id=8
12 2026-10-02 10:00:12 ERROR order id=12
16 2026-10-02 10:00:16 ERROR order id=16
20 2026-10-02 10:00:20 ERROR order id=20
& (END)
行番号が元ファイルのまま(4、8、12…)なので、フィルタを解除すればすぐ前後の行を読めます。この状態で F を押し、別の端末から ERROR 行を追記すると、フィルタを保ったまま追跡できました。
16 2026-10-02 10:00:16 ERROR order id=16
20 2026-10-02 10:00:20 ERROR order id=20
21 2026-10-02 10:01:00 ERROR added later
Waiting for data... (interrupt to abort)
less +F でローテーションをまたぐ
less の追跡も、既定では開いたファイルそのものを追います。--follow-name を付けると、ファイル名を基準に開き直します(less のマニュアルで確認。今回は対話画面の都合で、ローテーションをまたぐ動作までは実行していません)。
less --follow-name +F app.log
grep・awk と組み合わせるワンライナー集
grep --line-buffered が必要になる場面
tail -f app.log | grep ERROR のように、grep の出力が端末に直接出る場合は、1行ずつすぐ表示されます。grep の後ろにさらにパイプやリダイレクトをつなぐと、出力がまとめて溜められ、しばらく何も出ない状態になります。確かめてみます。
# 0.1秒ごとに追記される s.log を、2通りの書き方で追う
tail -f s.log | grep ERROR | cut -d' ' -f3- > nobuf.txt &
tail -f s.log | grep --line-buffered ERROR | stdbuf -oL cut -d' ' -f3- > buf.txt &
20行(うち ERROR は5行)を書き終えて1.5秒待ったあとの行数です。
nobuf lines: 0
buf lines: 5
ERROR order id=4
ERROR order id=8
ERROR order id=12
ERROR order id=16
ERROR order id=20
--line-buffered なしのほうは 0行 でした。grep は出力先が端末でないとき、ある程度の量(数KB)が溜まるまで書き出さないためです。データが失われたわけではなく、溜まれば出てきます。
| つなぐコマンド | 1行ずつ出すための指定 |
|---|---|
| grep | --line-buffered |
| sed | -u |
| awk(gawk) | 出力のあとに fflush() |
| cut・tr など | stdbuf -oL コマンド |
| python | python3 -u |
絞り込みのワンライナー
# ERROR を含む行だけ追う
tail -F app.log | grep --line-buffered ERROR
# ERROR または WARN(-E は拡張正規表現)
tail -F app.log | grep --line-buffered -E 'ERROR|WARN'
# 大文字小文字を区別しない
tail -F app.log | grep --line-buffered -i error
# 特定の行を除いて追う(ヘルスチェックのアクセスを除外)
tail -F access.log | grep --line-buffered -v '/health'
# ERROR の前後2行も一緒に出す
tail -F app.log | grep --line-buffered -C 2 ERROR
# 絞り込みを2段重ねる(ERROR のうち order を含む行)
tail -F app.log | grep --line-buffered ERROR | grep order
# 追いながらファイルにも保存する
tail -F app.log | grep --line-buffered ERROR | tee error-only.log
最後の grep は出力先が端末なので、--line-buffered を省けます。「途中の grep に付ける」と覚えると迷いません。grep のオプションは、既存記事「grepコマンドの使い方|オプション早見表と実務の逆引き(実行結果つき)」に一覧があります。
色を付けて読みやすくする
grep で一致した語だけに色を付けつつ、全行を残すには、パターンの最後に $(行末)を加えます。行末はすべての行に一致するので、どの行も表示されます。
tail -F app.log | grep --line-buffered --color=always -E 'ERROR|WARN|$'
cat -v で色コードを見える形にした出力です(^[[01;31m が赤の開始)。
2026-10-02 10:00:17 INFO order id=17
2026-10-02 10:00:18 ^[[01;31m^[[KWARN^[[m^[[K order id=18
2026-10-02 10:00:19 INFO order id=19
2026-10-02 10:00:20 ^[[01;31m^[[KERROR^[[m^[[K order id=20
レベルごとに色を変えたいときは awk が向いています。ERROR は赤、WARN は黄色で行全体を塗ります。
tail -F app.log | awk '
/ERROR/ {print "\033[31m" $0 "\033[0m"; next}
/WARN/ {print "\033[33m" $0 "\033[0m"; next}
{print}'
2026-10-02 10:00:15 INFO order id=15
^[[31m2026-10-02 10:00:16 ERROR order id=16^[[0m
2026-10-02 10:00:17 INFO order id=17
^[[33m2026-10-02 10:00:18 WARN order id=18^[[0m
2026-10-02 10:00:19 INFO order id=19
^[[31m2026-10-02 10:00:20 ERROR order id=20^[[0m
| 色コード | 色 | よく割り当てるレベル |
|---|---|---|
\033[31m |
赤 | ERROR |
\033[33m |
黄 | WARN |
\033[32m |
緑 | 成功・起動完了 |
\033[36m |
シアン | DEBUG |
\033[1m |
太字 | 強調 |
\033[0m |
解除 | 行末に必ず付ける |
awk の出力をさらに別のコマンドへ流す場合は、{print; fflush()} のように fflush() を足すと1行ずつ流れます。色付きの結果を less で読むときは less -R を使います。
grep --color=always -E 'ERROR|WARN|$' app.log | less -R
件数を数える・列を取り出す
追跡ではなく、いまあるログを集計するワンライナーです。
# ERROR の行数
grep -c ERROR s.log
# 3列目(レベル)が ERROR の行を数える
awk '$3=="ERROR"{c++} END{print "ERROR:", c}' s.log
# 最初の ERROR とその次の1行
grep -A1 -m1 ERROR s.log
5
ERROR: 5
2026-10-02 10:00:04 ERROR order id=4
2026-10-02 10:00:05 INFO order id=5
awk での集計は、既存記事「awkコマンドの使い方|実例50と集計・ログ解析、gawkとmawkの違い」で詳しく扱っています。
複数のログファイルを同時に監視する
tail はファイルを複数並べるだけで、まとめて追えます。
tail -F a.log b.log
# ワイルドカードも使える
tail -F /var/log/nginx/*.log
a.log と b.log に順に追記したときの出力です。
==> a.log <==
a1
a2
==> b.log <==
b1
b2
==> a.log <==
a3
==> b.log <==
b3
b4
出力元のファイルが変わるたびに ==> ファイル名 <== の見出しが入ります。同じファイルが続く間(b3、b4)は見出しが繰り返されません。
| やりたいこと | コマンド | 補足 |
|---|---|---|
| 見出し付きで同時に追う | tail -F a.log b.log |
どのファイルの行か分かる |
| 見出しなしで混ぜる | tail -q -F a.log b.log |
後段で加工するとき |
| 各ファイルの末尾1行だけ見る | tail -n 1 a.log b.log |
最終更新の確認 |
| 行頭にファイル名を付ける | 下のワンライナー | grep しても出どころが残る |
| 画面を分けて並べる | tmux でペインを分割 | アプリとWebサーバーを横に並べる |
-q を付けた tail -q -n 1 a.log b.log の出力は次のとおりで、見出しがなくなります。
a2
b2
見出しを各行の先頭に移すワンライナーです。grep で絞っても、どのファイルの行かが残ります。
tail -F a.log b.log | awk '/^==> .* <==$/ {f=$2; next} NF {print f ": " $0; fflush()}'
ワイルドカードはシェルが起動時に展開するため、あとから増えたファイルは対象に入りません。新しいファイルが増えたら、tail を起動し直します。
head と tail -n +N で必要な範囲を切り出す
追跡とは別に、ファイルの一部を取り出す操作もよく使います。1〜10 が1行ずつ入った n.txt で確かめました。
| コマンド | 意味 | n.txt での結果 |
|---|---|---|
head -n 3 n.txt |
先頭3行 | 1 2 3 |
head -n -3 n.txt |
末尾3行を除いた全部 | 1 2 3 4 5 6 7 |
tail -n 3 n.txt |
末尾3行 | 8 9 10 |
tail -n +8 n.txt |
8行目から最後まで | 8 9 10 |
sed -n '4,6p' n.txt |
4〜6行目 | 4 5 6 |
head -n 6 n.txt | tail -n 3 |
4〜6行目(別の書き方) | 4 5 6 |
head -c 5 n.txt |
先頭5バイト | 1 2 3(改行を含めて5バイト) |
tail -n 3 は「末尾から3行」、tail -n +3 は「3行目から最後まで」で、+ の有無で意味が大きく変わります。+N の N は「飛ばす行数」ではなく「始める行番号」なので、ヘッダー1行を飛ばすときは +2 です。
# CSV のヘッダー行を除いて処理する
tail -n +2 members.csv | wc -l
# 大きなログの 1000〜1020 行目を見る
sed -n '1000,1020p' app.log
# 先頭5行と末尾5行をまとめて確認
head -n 5 app.log; echo '...'; tail -n 5 app.log
head の負の指定(head -n -3)は GNU coreutils の機能です。macOS の標準 head では使えない版があるので、移植性を重視するなら sed や awk で書くと安心です。
主なログファイルの場所と監視コマンド例
追いたいログがどこにあるかの目安です。ディストリビューションや設定によって場所は変わるので、ls /var/log で確かめてから使います(検証環境の Ubuntu 24.04 でも /var/log に dpkg.log、nginx、postgresql などが並んでいました)。
| ログ | 主な場所(Debian・Ubuntu 系) | 主な場所(RHEL 系) | 監視コマンド例 |
|---|---|---|---|
| システム全般 | /var/log/syslog |
/var/log/messages |
sudo tail -F /var/log/syslog |
| 認証(ログイン・sudo) | /var/log/auth.log |
/var/log/secure |
sudo tail -F /var/log/auth.log |
| カーネル | /var/log/kern.log |
dmesg |
sudo dmesg -w |
| パッケージ操作 | /var/log/dpkg.log |
/var/log/dnf.log |
tail -n 20 /var/log/dpkg.log |
| nginx アクセス | /var/log/nginx/access.log |
同じ | tail -F /var/log/nginx/access.log |
| nginx エラー | /var/log/nginx/error.log |
同じ | tail -F /var/log/nginx/error.log |
| PostgreSQL | /var/log/postgresql/ |
/var/lib/pgsql/data/log/ |
tail -F /var/log/postgresql/*.log |
| systemd のサービス | ジャーナル | ジャーナル | journalctl -f -u サービス名 |
アクセスログでよく使う組み合わせも載せておきます。
# ステータスコードが 5xx の行だけ追う(combined 形式で9列目がステータス)
tail -F /var/log/nginx/access.log | awk '$9 ~ /^5/ {print; fflush()}'
# 特定のパスへのアクセスだけ追う
tail -F /var/log/nginx/access.log | grep --line-buffered ' /api/orders'
# アクセスログとエラーログを同時に追う
tail -F /var/log/nginx/access.log /var/log/nginx/error.log
(この3つは nginx が動いている環境向けの例で、今回の検証環境では実行していません。awk と grep の書き方は、前の章で動かしたものと同じ形です。)
大きなログファイルを less で開くコツ
less はファイル全体を読み込まずに表示するので、数GBのログでもすぐ開けます。行番号(-N)や G での末尾移動は、行を数える時間がかかることがあるため、大きなファイルでは次のように使うと軽快です。
| やりたいこと | 書き方 | 理由 |
|---|---|---|
| 末尾から読み始める | less +G app.log |
最新の行にすぐ着く |
| 行番号の計算を省く | less -n app.log |
行数を数えないので速い |
| 末尾の一部だけ読む | tail -n 5000 app.log | less |
読む範囲を先に絞る |
| 圧縮済みログを読む | zless app.log.1.gz |
展開せずに読める |
| 圧縮済みログを検索 | zgrep ERROR app.log.2.gz |
展開せずに検索できる |
つまずきやすい点と直し方
| 起きること | 理由 | 直し方 |
|---|---|---|
| ある時刻から tail -f に何も出なくなった | ローテーションでファイルが入れ替わった | tail -F を使う |
tail: cannot open 'x.log' for reading: No such file or directory で終了 |
ファイルがまだ作られていない | tail -F(作られるまで待つ) |
tail: 'x.log' has become inaccessible と出た |
追っていたファイル名が消えた(-F の通知) | そのまま待てば has appeared で再開 |
| grep を2つつないだら何も出ない | 途中の grep が出力を溜めている | 途中の grep に --line-buffered |
色コードが ESC[31m と文字で見える |
less が色を解釈していない | less -R |
| 長い行が折り返されて読みにくい | 既定は折り返し表示 | less -S(←→で横移動) |
| less +F で検索やスクロールができない | 追跡モード中 | Ctrl+C で通常モードに戻る |
Permission denied |
読み取り権限がない | sudo tail -F /var/log/syslog |
| 画面が流れすぎて読めない | 出力量が多い | grep で絞る、または less +F と & フィルタ |
| ログが出るまで数秒遅れる | アプリ側がバッファしている | アプリのログ設定(即時フラッシュ)を確認 |
最後の行は、tail の側ではなく書き込む側の事情です。たとえば Python で print の出力をファイルへリダイレクトしていると、既定ではまとめて書き出されます。python3 -u や flush=True を付けると、tail にすぐ届きます。
よくある質問
Q. tail -f と tail -F はどちらを使えばよいですか?
A. 迷ったら tail -F を選ぶと、ローテーションやファイルの作り直しに対応できます。-F は --follow=name --retry の短縮形で、ファイル名を見張り、開けない間は待ち続けます。数分の確認なら -f でも結果は同じです。
Q. less +F と tail -f の違いは何ですか?
A. 追記を追う点は同じで、違いは止めたあとの動きです。less +F は Ctrl+C で通常の less に戻り、そのまま検索やスクロールができます。再開は F です。パイプで grep や awk に流す用途には tail が向いています。
Q. tail -f | grep で何も表示されないのはなぜですか?
A. grep の後ろにさらにパイプやリダイレクトがあると、grep が出力を溜めてから書き出すためです。途中の grep に --line-buffered を付けると1行ずつ流れます。この記事の検証では、付けない場合は0行、付けた場合は5行がすぐ出力されました。
Q. journalctl -f と tail -f はどう使い分けますか?
A. systemd が管理するサービスのログは journalctl -f -u サービス名、アプリケーションが独自に書き出すファイルは tail -F が基本です。journalctl はファイルの場所を知らなくても追え、優先度や期間でも絞れます。
まとめ
tail -fは開いたファイルそのものを、tail -Fはファイル名を追う。長時間の監視は-Fが安心- リネーム型ローテーションの再現では、
tail -fは16行で止まり、tail -Fは40行すべてを表示した less +Fは Ctrl+C で読み返し、Fで追跡再開。&patternで less の中だけで絞り込める- パイプを重ねるときは途中の grep に
--line-buffered。sed は-u、awk はfflush() - 色付けは
grep --color=always -E 'ERROR|WARN|$'か awk。less で読むときは-R - 複数ファイルは
tail -F a.log b.log。==> ファイル名 <==の見出しで出どころが分かる tail -n 3は末尾3行、tail -n +3は3行目以降。+の有無で意味が変わる
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「tail -f・less +Fでログ監視|grep絞り込みと操作キー一覧」
株式会社RJCでは、tail や less を使ったログの読み方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。