journalctl でログを運用者として読む
サービスをわざと壊し、journal から原因を突き止めて直します。さらに電源を落として入れ直し、「落ちる前のログ」をマシンの境界をまたいで読みます。フィルタが強すぎて何も出ないという失敗も、この章で体験します。
| 所要時間 | 約 45 分 |
|---|---|
| 章タイプ | standard |
| 前提知識 | Part 1 Chapter 4(grep でログを読む)/ Part 3 Chapter 1(systemd の概念) |
| 使用機材 | 踏み台 workstation01 + 演習用サーバ learner01(Proxmox 電源操作あり) |
| 関連章 | 前: Chapter 1「systemd でサービスを常駐させる」/ 後: Chapter 3「ユーザ・グループ・権限を設計する」 |
ログは語る ── 失敗した理由を journal が知っている
深夜 3 時。監視アラートが鳴った。systemctl status myapp を見ると failed になっている。ログはどこにある?
# 昔の方法:ファイルの場所を知っている必要がある cat /var/log/syslog | grep myapp cat /var/log/myapp.log # systemd 時代の方法:サービス名で引く journalctl -u myapp -n 50 -p err
systemd が普及した現代の Linux では、すべてのサービスのログが journal という 1 か所に集まっています。ファイルを探し回る必要はなく、サービス名・優先度・時刻・何回目の起動かで絞り込めます。
この章の核心は マシンの境界(電源断・再起動)をまたいでログを読むことです。
① 演習用サービスを作り、正常なログを journal で読む
↓
② サービスをわざと壊す(ExecStart を壊す)→ journal で失敗を追う
↓
③ 原因を特定して修正 → journal で復旧を確認する
↓
④ 電源断(qm stop → qm start)→ journalctl -b -1 で
「電源が落ちる前のログ」をマシン境界をまたいで読む
hello-logger サービスを 1 から作り、壊す → 追う → 直す → 電源イベントまで、すべてこの章の中で完結します。Chapter 1 を受けていない状態でも、そのまま始められます。この章を終えるとできること
一次調査の 4 動詞を手に覚えます。
ログを取り出す
自分で作る
原因に辿り着く
またいで読む
journal のしくみを解きほぐす
1. journal と /var/log/syslog の違い
かつての Linux は、サービスごとに /var/log/myapp.log を書いたり、syslog が /var/log/syslog にまとめたりしていました。この方式には弱点がありました。
├── ログの置き場所がサービスごとにバラバラ(/var/log/ を探し回る) ├── ただのテキストなので絞り込みが弱い(優先度・PID・ユニット名で引けない) └── 再起動をまたぐ検索が難しい(ファイルに「起動の区切り」がない)
├── すべてのユニット(サービス・カーネル・ブート)のログを 1 か所に集約 ├── バイナリ形式(構造化ログ)→ 優先度・ユニット名・PID・時刻で絞り込める └── boot ID を記録 → -b -1 で「前回の起動」を名指しできる
journalctl はその閲覧コマンドです。テキストを grep するのとは別の絞り込み方を持ちます。
2. 覚えておきたい 7 つのフラグ
| フラグ | 意味 | 使いどころ |
|---|---|---|
-u <svc> | 特定サービスのログだけ表示 | 「このサービスに何が起きたか」を見る |
-f | リアルタイム追従(tail -f 相当) | 「今まさに起きていること」を追う |
--since "TIME" | 指定時刻以降のログ | 「あの時刻以降に何があったか」を絞る |
-p err | 優先度フィルタ(err 以上) | エラーだけを抽出する(ただし §04 STEP ⑦ の落とし穴あり) |
-b -1 | 前回ブートのログ | 電源断・再起動の前のログをまたいで読む |
-n <N> | 末尾 N 行だけ表示 | 直近だけ素早く確認する |
--list-boots | ブート一覧の表示 | いくつ前まで遡れるかを確認する |
-b は boot(起動の単位)を指定するオプションです。-b 0 が今回の起動(省略時の既定)、-b -1 が 1 つ前の起動、-b -2 が 2 つ前になります。
3. 優先度は 8 段階ある
emerg(0) > alert(1) > crit(2) > err(3) > warning(4) > notice(5) > info(6) > debug(7)
-p err は「err 以上(0〜3)だけを表示」という意味です。-p warning にすると warning 以上(0〜4)が出ます。
ここが後で効いてきます: 「サービスが落ちている」ことと「journal に
errで記録される」ことは別の話です。STEP ⑦ で、実際にサービスが落ちているのに-p errでは 1 行も出てこない場面に出会います。
4. 「マシン境界をまたぐ」とはどういうことか
/var/log/syslog を grep する方法では、再起動前のログを遡るのに古いファイルを探したり、logrotate の世代を確かめたりする必要がありました。journal は起動ごとに ID を振っているので、1 コマンドで前回の起動を名指しできます。
# 今回の起動での直近ログ journalctl -u hello-logger -b 0 -n 1 # 前回の起動(=電源が落ちる前)のログ journalctl -u hello-logger -b -1 # 何回前まで遡れるか journalctl --list-boots
実機価値: 「電源が落ちる直前に何が起きていたか」「再起動後にサービスが起き上がったのはいつか」を、マシンの境界をまたいで 1 コマンドで調べられます。これは本当に電源を落とした経験がないと、必要性がぴんと来ない機能です。本章では実際に落として、両側のログを見比べます。
試してみよう:壊して、追って、直して、またいで読む
演習用サービス hello-logger をこの章の中で 1 から作り、わざと失敗させて journal で追跡し、修正して復旧させ、最後に電源イベントをまたいでログを読みます。
| 項目 | 値 |
|---|---|
| 出発地点 | 踏み台 workstation01 |
| 演習対象 | learner01(サービス作成・journalctl 操作) |
| Proxmox 操作 | Proxmox ホスト(<Proxmox管理IP>) |
| ゲスト操作ユーザー | ops(NOPASSWD sudo) |
| 所要時間 | 約 40 分(10 ステップ) |
/usr/local/bin/hello-logger.sh と /etc/systemd/system/hello-logger.service の 2 ファイルだけです。STEP ⑩ のクリーンアップを上から順に実行すれば、どの段階からでもクリーン状態に戻せます。VMID の確認方法: Proxmox ホストで qm list | grep learner01 を実行すると、左端の数字が VMID です。以降 <VMID> と記します。STEP 01 · 接続して、クリーン状態を確認する
# workstation01 から learner01 へ接続 ssh ops@learner01 # 前セッションの残骸チェック systemctl status hello-logger
Unit hello-logger.service could not be found. と出ればクリーン状態です。active や failed が出る場合は前回の演習が途中で終わった名残なので、先に STEP ⑩「章末クリーンアップ」を実行してから STEP ① に戻ってください。
STEP 02 · journal が永続保存されているか確認する
この章の核心である journalctl -b -1(STEP ⑨)は、journal が永続保存されていないと動きません。先に確認し、無効なら有効化します。
# 永続保存されているか確認。無ければ有効化する ls /var/log/journal/ 2>/dev/null || (sudo mkdir -p /var/log/journal && sudo systemctl restart systemd-journald) # 起動の履歴を確認 journalctl --list-boots
[machine-id] -1 [boot-id] Sun 2026-07-26 17:27:22 JST Sun 2026-07-26 22:10:14 JST 0 [boot-id] Tue 2026-07-28 09:35:28 JST Tue 2026-07-28 09:55:22 JST
/var/log/journal/ が存在し、--list-boots に 1 行以上出れば準備完了です。No such file or directory が出た場合は || の後ろが自動で走り、systemd-journald が再起動されます。
なぜ先に確認するか:
/var/log/journal/が無い環境では、journal は/run/log/journal/(メモリ上)に保存されます。メモリ上ということは、電源が落ちれば消えるということです。この章の主役-b -1は前回のログを読む機能なので、先に「消えない場所に書く」設定を担保しておきます。
この設定は章末で戻しません:
/var/log/journal/は Part 3 の他の章でも使うため、クリーンアップの対象外です。
STEP 03 · 演習用サービスを作る
Chapter 1 を受けたかどうかに関係なく、ここで 1 から作ります。
# スクリプトを作成 sudo tee /usr/local/bin/hello-logger.sh << 'EOF' #!/bin/bash while true; do echo "$(date '+%Y-%m-%d %T') [hello-logger] alive" sleep 5 done EOF sudo chmod 755 /usr/local/bin/hello-logger.sh
# ユニットファイルを作成 sudo tee /etc/systemd/system/hello-logger.service << 'EOF' [Unit] Description=Hello Logger - 演習用タイムスタンプ記録サービス After=network.target [Service] Type=simple ExecStart=/usr/local/bin/hello-logger.sh Restart=on-failure RestartSec=5s StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now hello-logger systemctl is-active hello-logger
active
StandardOutput=journal と書いてあるのがポイントです。スクリプトが echo した内容は、画面ではなく journal に流れ込みます。30 秒ほど動かしてから次に進むと、読めるログが溜まっています。
STEP 04 · 正常なログを読む
# このサービスのログを末尾 10 行だけ journalctl -u hello-logger -n 10
7月 28 09:50:37 learner01 hello-logger.sh[2826]: 2026-07-28 09:50:37 [hello-logger] alive 7月 28 09:50:42 learner01 hello-logger.sh[2826]: 2026-07-28 09:50:42 [hello-logger] alive 7月 28 09:50:47 learner01 hello-logger.sh[2826]: 2026-07-28 09:50:47 [hello-logger] alive 7月 28 09:50:52 learner01 hello-logger.sh[2826]: 2026-07-28 09:50:52 [hello-logger] alive
1 行の形は 月 日 時刻 ホスト名 ユニット名[PID]: メッセージ です。時刻・ホスト名・ユニット名・PID が別々の項目として記録されているので、あとから好きな条件で絞り込めます。ここがテキストファイルとの違いです。
# リアルタイムに追いかける journalctl -u hello-logger -f
5 秒ごとに行が増えていくのを確認したら、Ctrl + C で止めてください。
# 直近 5 分だけに絞る journalctl -u hello-logger --since "5 minutes ago"
ページャの操作:
journalctlは既定でlessが開きます。スクロールは方向キー、終了は q です。パイプでgrepに渡したいときは--no-pagerを付けてください。
STEP 05 · 優先度で絞ってみる(正常時)
# err(3)以上の優先度だけを表示 journalctl -u hello-logger -p err
-- No entries --
いまは正常に動いているので、エラーはありません。この「空っぽ」の見え方を覚えておいてください。STEP ⑦ で、サービスが壊れているのにまったく同じ表示に出会います。
STEP 06 · 壊す ── 起動できないサービスにする
ExecStart= を存在しないパスに書き換えて、サービスを起動不能にします。
# ExecStart のパスを壊す sudo sed -i 's|ExecStart=/usr/local/bin/hello-logger.sh|ExecStart=/usr/local/bin/hello-logger-BROKEN.sh|' \ /etc/systemd/system/hello-logger.service # 変更を反映して再起動 sudo systemctl daemon-reload sudo systemctl restart hello-logger systemctl status hello-logger
● hello-logger.service - Hello Logger - 演習用タイムスタンプ記録サービス
Loaded: loaded (/etc/systemd/system/hello-logger.service; enabled; preset: enabled)
Active: activating (auto-restart) (Result: exit-code) since Tue 2026-07-28 09:51:09 JST; 2s ago
Process: 3611 ExecStart=/usr/local/bin/hello-logger-BROKEN.sh (code=exited, status=203/EXEC)
Main PID: 3611 (code=exited, status=203/EXEC)
7月 28 09:51:09 learner01 systemd[1]: hello-logger.service: Main process exited, code=exited, status=203/EXEC
7月 28 09:51:09 learner01 systemd[1]: hello-logger.service: Failed with result 'exit-code'.
壊れました。Active: が activating (auto-restart) になっているのは、Restart=on-failure が 5 秒おきに再挑戦し続けているからです。失敗しては再起動する、を延々と繰り返している状態です。
STEP 07 · 追う ── 優先度フィルタの落とし穴
失敗の原因を journal で探します。まず、いかにも正しそうな方法から試します。
# エラーだけ見れば分かるはず……? journalctl -u hello-logger -p err -n 20
-- No entries --
何も出ません。サービスは確実に壊れていて、いまも 5 秒おきに失敗し続けているのに、です。
なぜ空になるのか: systemd がユニットの失敗を報告する行は、
err(3)ではなくnotice(5)やwarning(4)で記録されています。「サービスが落ちている」ことと「journal に err で記録される」ことは別なのです。しかも実測では、-p warningまで下げても核心の203/EXECの行は出てきません。優先度フィルタは万能ではありません。
調査ではフィルタを外すのが確実です。
# 優先度を指定せず、全レベルで直近 30 行 journalctl -u hello-logger -n 30
7月 28 09:51:30 learner01 systemd[1]: hello-logger.service: Scheduled restart job, restart counter is at 5. 7月 28 09:51:30 learner01 systemd[1]: Started hello-logger.service - Hello Logger - 演習用タイムスタンプ記録サービス. 7月 28 09:51:30 learner01 systemd[1]: hello-logger.service: Main process exited, code=exited, status=203/EXEC 7月 28 09:51:30 learner01 systemd[1]: hello-logger.service: Failed with result 'exit-code'. (中略) 7月 28 09:52:01 learner01 systemd[1]: hello-logger.service: Scheduled restart job, restart counter is at 11. 7月 28 09:52:01 learner01 systemd[1]: Started hello-logger.service - Hello Logger - 演習用タイムスタンプ記録サービス. 7月 28 09:52:01 learner01 systemd[1]: hello-logger.service: Main process exited, code=exited, status=203/EXEC 7月 28 09:52:01 learner01 systemd[1]: hello-logger.service: Failed with result 'exit-code'.
今度は出ました。読み取るべきは status=203/EXEC です。203/EXEC は「指定された実行ファイルを起動できなかった」という意味で、パスの間違いか実行権限の欠落で起こります。これが根本原因です。
restart counter is at 5 → at 11 と数字が増えているのは、その間も失敗し続けていた証拠です。調査中も時計は動いています。
-p err を打ち、空だったからといって「問題ない」と判断してはいけません。フィルタが強すぎて見えていないだけかもしれません。困ったら、まずフィルタを外す。STEP 08 · 直す ── 復旧を journal で確認する
# ExecStart を正しいパスに戻す sudo sed -i 's|ExecStart=/usr/local/bin/hello-logger-BROKEN.sh|ExecStart=/usr/local/bin/hello-logger.sh|' \ /etc/systemd/system/hello-logger.service sudo systemctl daemon-reload sudo systemctl restart hello-logger systemctl is-active hello-logger
active
# 失敗から復旧までの流れが 1 か所に残っている journalctl -u hello-logger -n 10
7月 28 09:54:59 learner01 systemd[1]: hello-logger.service: Main process exited, code=exited, status=203/EXEC 7月 28 09:54:59 learner01 systemd[1]: hello-logger.service: Failed with result 'exit-code'. 7月 28 09:55:02 learner01 systemd[1]: Stopped hello-logger.service - Hello Logger - 演習用タイムスタンプ記録サービス. 7月 28 09:55:02 learner01 systemd[1]: Started hello-logger.service - Hello Logger - 演習用タイムスタンプ記録サービス. 7月 28 09:55:02 learner01 hello-logger.sh[4727]: 2026-07-28 09:55:02 [hello-logger] alive 7月 28 09:55:07 learner01 hello-logger.sh[4727]: 2026-07-28 09:55:07 [hello-logger] alive
「失敗 → 繰り返し → 修正後に正常起動」という一連の流れが、時系列で 1 か所に残っています。これが障害対応の証跡になります。「いつ壊れて、いつ直ったか」を後から人に説明できる形です。
systemctl is-active hello-logger が active を返し、かつ journalctl -u hello-logger -n 10 に [hello-logger] alive の行が見えること。STEP 09 · またぐ ── 電源断の前後を読み比べる
この章の核心です。まず現在の起動履歴を控えます。
journalctl --list-boots
-2 [boot-id] Sun 2026-07-19 11:51:46 JST Sun 2026-07-19 11:56:11 JST -1 [boot-id] Sun 2026-07-26 17:27:22 JST Sun 2026-07-26 22:10:14 JST 0 [boot-id] Tue 2026-07-28 09:35:28 JST Tue 2026-07-28 09:55:22 JST
0 の行が「今の起動」です。この後の電源断で、この行が -1 に押し下がります。
workstation01 で別のターミナルを開いて、Proxmox ホストから電源を落とします。
# 別ターミナルで Proxmox ホストに接続 ssh ops@<Proxmox管理IP> qm list | grep learner01 # VMID を確認 qm stop <VMID> # 電源断相当 qm status <VMID> # stopped を確認 qm start <VMID> # 再投入
およそ 20〜30 秒待ってから learner01 に再接続し、起動履歴を見直します。
ssh ops@learner01 journalctl --list-boots
-2 [boot-id] Sun 2026-07-26 17:27:22 JST Sun 2026-07-26 22:10:14 JST -1 [boot-id] Tue 2026-07-28 09:35:28 JST Tue 2026-07-28 09:55:37 JST 0 [boot-id] Tue 2026-07-28 09:56:00 JST Tue 2026-07-28 09:58:36 JST
さっき 0 だった行が -1 に移動しました。行がひとつずつ押し下がるのが、電源が 1 回落ちたということの journal 上の意味です。
# 電源が落ちる前のログ journalctl -u hello-logger -b -1
7月 28 09:55:02 learner01 systemd[1]: Started hello-logger.service - Hello Logger - 演習用タイムスタンプ記録サービス. 7月 28 09:55:02 learner01 hello-logger.sh[4727]: 2026-07-28 09:55:02 [hello-logger] alive 7月 28 09:55:07 learner01 hello-logger.sh[4727]: 2026-07-28 09:55:07 [hello-logger] alive (中略) 7月 28 09:55:37 learner01 hello-logger.sh[4727]: 2026-07-28 09:55:37 [hello-logger] alive
# 電源を入れ直した後のログ journalctl -u hello-logger -b 0
7月 28 09:57:31 learner01 hello-logger.sh[1080]: 2026-07-28 09:57:31 [hello-logger] alive 7月 28 09:57:36 learner01 hello-logger.sh[1080]: 2026-07-28 09:57:36 [hello-logger] alive (中略) 7月 28 09:58:41 learner01 hello-logger.sh[1080]: 2026-07-28 09:58:41 [hello-logger] alive
2 つの出力を見比べてください。ログは 09:55:37 でぷつりと途切れ、09:57:31 から再開しています。この空白が電源の落ちていた時間です。PID も 4727 から 1080 に変わっており、別の OS セッションであることが数字にも出ています。
本番での使い方: サーバが予期せず再起動していたとき、
journalctl -b -1 -p errで前回の終わり際のエラーを絞り込むのが一次調査の定石です。ただし STEP ⑦ で見たとおり、-p errで空でも「異常なし」とは限りません。空だったらフィルタを外して読み直してください。
STEP 10 · 章末クリーンアップ
# 停止して自動起動も解除 sudo systemctl disable --now hello-logger # ファイルを削除 sudo rm /etc/systemd/system/hello-logger.service sudo rm /usr/local/bin/hello-logger.sh # 反映して確認 sudo systemctl daemon-reload systemctl status hello-logger
Unit hello-logger.service could not be found. と出れば完了です。これはエラーではなく「もう無い」という意味です。
/var/log/journal/は消しません: STEP ② で有効にした journal の永続保存は、Part 3 の他の章でも使うため残します。
| 確認項目 | 期待値 |
|---|---|
systemctl status hello-logger | Unit hello-logger.service could not be found. |
/etc/systemd/system/hello-logger.service | 存在しない |
/usr/local/bin/hello-logger.sh | 存在しない |
演習中の -p err(STEP ⑦) | -- No entries -- になることを確認済み(=これが正しい) |
演習中の -n 30(STEP ⑦) | status=203/EXEC を確認済み |
演習中の -b -1(STEP ⑨) | 電源断前のログを確認済み |
/var/log/journal/ | 残したまま(消さない) |
詰まったら
- ハマりポイント: よくある詰まりと対処を以下に列挙しています
- AI に相談: 演習中の疑問を章の内容を踏まえて AI に聞けます
ハマりポイント
STEP ⑦ で -p err が空になる
それが正しい結果です。この章はその「空」をわざと見せるために作られています。
systemd がユニットの失敗を書く行の優先度は、203/EXEC の行が notice(5)、Failed with result の行が warning(4)です。どちらも err(3)より低いため、-p err の網には掛かりません。実測では -p warning まで下げても核心の 203/EXEC 行は出ません。
優先度の指定そのものを外して journalctl -u hello-logger -n 30 で確認してください。
STEP ⑨ で journalctl -b -1 が空になる
まず journalctl --list-boots で -1 の行が存在するかを確認してください。
行が無い場合: STEP ② の永続保存が効いていません。ls /var/log/journal/ でディレクトリの存在を確認し、無ければ作り直して sudo systemctl restart systemd-journald を実行します。ただし、永続化する前のブートのログは戻ってきません(メモリ上にあったものは電源断で消えています)。その場合はもう一度 qm stop → qm start を行えば、次からは -b -1 で読めます。
行はあるのに空の場合: そのブート中に hello-logger が動いていなかった可能性があります。-u を外した journalctl -b -1 -n 30 で、そのブート自体のログがあるかを確かめてください。
STEP ⑨ で SSH がつながらない
Connection refused: VM の起動がまだ終わっていません。qm start から 20〜30 秒待って再試行してください。
Connection timed out during banner exchange: ping も通りポート 22 も開いているのに出ることがあります。sshd がまだ応答を返し始めていない状態です。1〜2 分待ってから再試行してください。ポートが開いていることと、応答が始まっていることは別です。
上記以外の詰まりと対処を一覧にまとめます。
| 起きたこと | 対処 |
|---|---|
② --list-boots が空、または表示されない | sudo systemctl status systemd-journald で journald の状態を確認し、sudo systemctl restart systemd-journald を実行してから再試行 |
④ journalctl -u hello-logger が -- No entries -- | サービスが起動した直後で、まだログが無い。10〜15 秒待って再実行。それでも空なら systemctl is-active で動いているか確認 |
⑥ sed の後の restart が Unit not found | daemon-reload を忘れている。sudo systemctl daemon-reload を実行してから再試行 |
⑧ 修正したのに failed が続く | daemon-reload を実行したか確認。restart だけではユニットファイルの変更が反映されない |
| ページャから抜けられない | q で終了。そもそも開きたくない場合は --no-pager を付ける |
AI に相談
修了確認
ログを読む技術と、フィルタの落とし穴を確認します。
問 1 · -b -1 の意味と使いどころ
journalctl -u hello-logger -b -1 の -b -1 は何を意味しますか? また、このオプションが特に役立つのはどんな場面ですか?
解答を見る
-b は boot(起動の単位)を指定するオプションです。-b 0 が今回の起動(省略時の既定)、-b -1 が 1 つ前の起動を指します。したがってこのコマンドは「前回の OS 起動中に、このサービスが出力したログ」を表示します。
役立つ場面:
- サーバが予期せず再起動した後に「落ちる直前に何が起きていたか」を調べる
- 電源断から復帰した後に、前回のエラーを遡る
- 夜間に起きた障害を翌朝に調査する(
-b -1で昨晩のログを読む)
ただし、これが使えるのは journal が永続保存されている場合だけです(/var/log/journal/ が存在すること)。メモリ上(/run/log/journal/)に保存されている環境では、電源が落ちた時点でログも消えます。STEP ② で先に確認したのはこのためです。
問 2 · failed のときの一次調査
サービスが Active: failed になっているとき、どんな順序で調べますか? 使うコマンドを含めて説明してください。また、journalctl -p err が空だったとき、どう解釈すべきですか?
解答を見る
# 1. 概要をつかむ(Active の状態・直近数行・終了コード) systemctl status <svc> # 2. フィルタを掛けずに直近のログを読む(← ここが要) journalctl -u <svc> -n 50 # 3. 時刻が分かっているなら絞り込む journalctl -u <svc> --since "10 minutes ago"
-p err が空だったときの解釈: 「異常なし」ではありません。そのフィルタでは見えていない、というだけです。systemd はユニットの失敗を notice や warning で記録するため、-p err の網から漏れます。空だったら優先度の指定を外して読み直してください。
よくある原因と対処:
| ログに出るもの | 意味 | 対処 |
|---|---|---|
status=203/EXEC | 指定した実行ファイルを起動できなかった | パスの誤りか実行権限の欠落。ExecStart= を直すか chmod 755 |
Permission denied | 実行権限がない | sudo chmod 755 <path> の後に restart |
| 0 以外の終了コード | スクリプト自体が異常終了した | スクリプトの中身を確認して修正 |
いずれの場合も、ユニットファイルを直したら daemon-reload → restart の順です。修正後は systemctl is-active と journal の両方で確認します。
段階ヒント(問 1・問 2 共通)
段階ヒント 1 段目:出ないときは、まず絞りすぎを疑う
journalctl で何も出ないときは、フィルタが厳しすぎることがほとんどです。まず -u <svc> だけで全体を見て、そこから -p や --since を足していく順番で進めてください。逆順(最初から絞る)で始めると、この章の STEP ⑦ と同じ落とし穴にはまります。
段階ヒント 2 段目:用途別のコマンド一覧
journalctl -u hello-logger # 全体 journalctl -u hello-logger -n 20 # 末尾 20 行 journalctl -u hello-logger -f # 追従(Ctrl+C で止める) journalctl -u hello-logger --since "5 minutes ago" # 時刻で絞る journalctl -u hello-logger -p err # err 以上(空でも異常なしとは限らない)
journalctl --list-boots # 何回前まで遡れるか journalctl -u hello-logger -b -1 # 前回の起動 journalctl -u hello-logger -b 0 # 今回の起動
よくある落とし穴:
- 既定でページャ(
less)が開く。終了は q、使いたくなければ--no-pager -b -1には journal の永続保存が必要(STEP ② で担保済み)-p errが空でも「異常なし」ではない(STEP ⑦)
答えを見る(フルコマンド列)
# ── STEP② journal 永続化 ── ls /var/log/journal/ 2>/dev/null || (sudo mkdir -p /var/log/journal && sudo systemctl restart systemd-journald) journalctl --list-boots # ── STEP③ サービス作成後 ── sudo systemctl daemon-reload sudo systemctl enable --now hello-logger systemctl is-active hello-logger # active # ── STEP④⑤ 読む ── journalctl -u hello-logger -n 10 journalctl -u hello-logger --since "5 minutes ago" journalctl -u hello-logger -p err # 正常時は -- No entries -- # ── STEP⑥ 壊す ── sudo sed -i 's|ExecStart=/usr/local/bin/hello-logger.sh|ExecStart=/usr/local/bin/hello-logger-BROKEN.sh|' \ /etc/systemd/system/hello-logger.service sudo systemctl daemon-reload sudo systemctl restart hello-logger systemctl status hello-logger # 203/EXEC で失敗 # ── STEP⑦ 追う ── journalctl -u hello-logger -p err -n 20 # -- No entries --(これが正しい) journalctl -u hello-logger -n 30 # status=203/EXEC が見える # ── STEP⑧ 直す ── sudo sed -i 's|ExecStart=/usr/local/bin/hello-logger-BROKEN.sh|ExecStart=/usr/local/bin/hello-logger.sh|' \ /etc/systemd/system/hello-logger.service sudo systemctl daemon-reload sudo systemctl restart hello-logger systemctl is-active hello-logger # active(復旧) # ── STEP⑨ Proxmox ホスト(別ターミナル)── qm stop <VMID> qm start <VMID> # ── STEP⑨ learner01(20〜30 秒後)── journalctl --list-boots journalctl -u hello-logger -b -1 # 電源断前 journalctl -u hello-logger -b 0 # 電源投入後 # ── STEP⑩ クリーンアップ ── sudo systemctl disable --now hello-logger sudo rm /etc/systemd/system/hello-logger.service sudo rm /usr/local/bin/hello-logger.sh sudo systemctl daemon-reload
このフローで覚えること:
- 調査は「絞らずに全体 → 徐々に絞る」の順。逆順は見落とす
-p errが空でも異常なしとは限らない。フィルタを外して読み直す-b -1で前回の起動を読むには、journal の永続保存が要る
次の章へ
ログを追う技術で、インシデントの一次調査ができるようになりました。次は視点を変えて、そのサーバに誰がアクセスできて、誰が何をできるのかを設計します。ユーザを作り、グループでまとめ、共有ディレクトリの権限を決める ── さらに踏み台から別のユーザで learner01 にログインし、権限の境界を自分の目で確かめます。
- ユーザとグループを作り、共有ディレクトリの権限を設計する
- 「読めるが書けない」「書けるが消せない」を権限で作り分ける
- 別ユーザで実際にログインし、境界を越えられないことを確かめる
もっと知りたい方へ
journalctl --no-pager: ページャを使わずそのまま出力します。パイプでgrepに渡したいときに使います(journalctl -u hello-logger --no-pager | grep alive)journalctl -o json-pretty: ログを JSON で出力します。1 行が実は多数の項目を持つ構造化データであることが目で見えるので、一度は実行してみる価値がありますjournalctl -k: カーネルのメッセージだけを表示します(dmesg相当)。ハードウェアのエラーやメモリ不足によるプロセス強制終了を調べるときに使いますjournalctl --vacuum-size=100M: journal の容量を減らします。/var/log/journal/が膨らんだときに上限を決めて古いログを消せます/etc/systemd/journald.conf: journal の設定ファイルです。Storage=persistent(永続保存)やMaxRetentionSec=(保存期間の上限)を指定できますsystemd-cat: 任意のコマンドの出力を journal に流し込みます(echo "test" | systemd-cat -t myapp -p info)。自作スクリプトのログを journal に集約したいときに使います- 時刻範囲での絞り込み:
journalctl -u hello-logger --since "2026-07-25 03:00" --until "2026-07-25 03:30"のように、開始と終了を指定できます。障害の発生時刻が分かっているときに有効です