高度なSystemd Journaldトラブルシューティングテクニック

時間フィルター、ブート選択、ユニットクエリ、優先度レベル、エクスポートを使用してsystemdジャーナルログをトラブルシューティングします。

高度なSystemd Journaldトラブルシューティングテクニック

systemdベースのLinuxホストのデバッグは、多くの場合ジャーナルから始まります。journalctl -xeは最近の障害を表示できますが、実際のトラブルシューティングでは通常、ブート、時間範囲、ユニット、優先度、プロセス、実行可能ファイルでログを絞り込む必要があります。

以下の例は、大規模なジャーナルを、サービス障害、ブート問題、繰り返し発生するシステムエラーの際に使用できる焦点を絞ったビューに変換する方法を示しています。

ジャーナルの理解:構造と場所

systemdジャーナルは、カーネル、システムサービス、アプリケーションからのログを集約します。従来のsyslogファイルとは異なり、ジャーナルはログをインデックス化されたバイナリ形式で保存するため、journalctlを介した高度なクエリが可能です。ログは通常、/var/log/journal/などのディレクトリに永続化されます。

覚えておくべき重要な概念:

  • 構造化ログ:エントリにはメタデータフィールド(_PID_COMM_SYSTEMD_UNITなど)が含まれており、journalctlがフィルタリングに使用します。
  • 揮発性 vs. 永続性:ログはメモリのみ(揮発性)またはディスクに書き込まれて(永続性)保存できます。デフォルトの設定は通常、永続性を優先します。

必須の高度なフィルタリングテクニック

journalctlの威力は、数百万のログエントリを絞り込む能力にあります。最も効果的な高度なフィルタは以下の通りです。

1. 時間ベースのフィルタリング

時間範囲は、一時的な問題やパフォーマンスの低下を診断する際に重要です。絶対形式または相対アンカーを使用して時間を指定できます。

A. 相対時間: 相対時間指定には-S(since)と-U(until)を使用します。

# 過去30分間のログを表示
journalctl --since "30 minutes ago"

# 昨日の午前10時から現在までのログを表示
journalctl -S yesterday -U now

# 特定の時間範囲のログを表示(ISO 8601形式)
journalctl --since "2024-05-01 08:00:00" --until "2024-05-01 08:15:00"

B. ブートベースの時間: 特定の問題のあるブートシーケンスを分析するには、-bフラグを使用します。

# 現在のブートからのログのみを表示
journalctl -b

# 前回のブートからのログを表示
journalctl -b -1

# 前々回のブートからのカーネルログを表示
journalctl -b -2 -k

2. systemdユニットとサービスによるフィルタリング

特定のサービスに属するログを分離するには、-uまたは--unitフラグを使用します。これは、失敗したサービスのトラブルシューティングに不可欠です。

# Apache Webサーバーサービスのすべてのログを表示
journalctl -u httpd.service

# サービスが最後に起動されてからのログを表示
journalctl -u nginx.service --since "start of job -1"

3. プロセスID(PID)と実行可能ファイル名によるフィルタリング

特定のプロセスがクラッシュしたが、どのサービスが所有しているかすぐにわからない場合、PIDまたは実行可能ファイル名(_COMM)でフィルタリングすると非常に効果的です。

# 特定のプロセスID(例:PID 4589)に関連するログを表示
journalctl _PID=4589

# 'mysqld'という名前のすべてのプロセスのログを表示
journalctl _COMM=mysqld

4. 優先度レベルによるフィルタリング

ジャーナルエントリには数値の優先度(0=緊急、7=デバッグ)が割り当てられています。-pフラグを使用して重大度でフィルタリングすると、エラーを探す際に過剰なデバッグ出力を抑制するのに役立ちます。

優先度レベル キーワード 数値
緊急 emerg 0
警報 alert 1
重大 crit 2
エラー err 3
警告 warning 4
通知 notice 5
情報 info 6
デバッグ debug 7
# システムの重大なエラー(レベル2)以上のみを表示
journalctl -p crit

# デバッグメッセージを除くすべてのログを表示
journalctl -p 6

ブート障害とカーネルメッセージの分析

システム起動の問題のトラブルシューティングには、ユーザースペースのサービス障害とカーネルまたはハードウェアの初期化問題を区別する必要があります。

カーネルメッセージの分離(-kまたは--dmesg

-kフラグは、カーネルメッセージのみを表示します(dmesgの実行と同等)。これは、systemdがサービスをロードするのデバイスドライバ、ハードウェア認識、または初期化の失敗に関連する問題を特定するために重要です。

# 現在のブートからのすべてのカーネルメッセージを確認
journalctl -k

# 前回のブートのカーネルログで特定のハードウェアエラーを検索
journalctl -k -b -1 | grep -i "error"

サービス依存関係の追跡

サービスが起動に失敗した場合、上流の依存関係の失敗が原因である可能性があります。逆順表示(-r)とユニットフィルタリングを組み合わせて、失敗に至るまでのシーケンスを確認します。

# ユニットのログを時系列の逆順で表示
journalctl -u my-app.service -r

高度な出力フォーマットとエクスポート

詳細な分析やログの共有には、出力形式の変更が不可欠です。

1. JSONとして表示(-o json

スクリプトや外部ログ分析ツールとの統合には、構造化されたJSON出力が推奨されます。

journalctl -u sshd.service -o json

2. 単一行として表示(-o cat

タイムスタンプやメタデータなしでクリーンな生の出力を取得するには(grepなどの他のツールに直接パイプする場合に便利)、cat形式を使用します。

journalctl -u cron.service -o cat

3. ログのエクスポート

ログをアーカイブまたは転送するには、標準のテキストファイルにエクスポートします。特定のメタデータフィールドが必要な場合は、構造化フィールドを含む出力形式を選択します。

# 現在のブートからのすべてのログをテキストファイルにエクスポート
journalctl -b > boot_log_$(date +%F).txt

# 1つのユニットの選択した構造化フィールドをエクスポート
journalctl -u mariadb.service -o json --output-fields=__REALTIME_TIMESTAMP,PRIORITY,_PID,_COMM,MESSAGE --since today > mariadb_recent.json

ジャーナル管理のベストプラクティス

特にログ量の多いシステムでは、ディスク容量の枯渇を防ぐためにジャーナルサイズの管理が重要です。

  • 使用状況の確認: 現在のジャーナルディスク消費量を確認します:
    journalctl --disk-usage
    
  • 古いログのクリーンアップ: vacuumコマンドを使用して、時間またはディスク使用量でジャーナルサイズを制限します:
    # 過去7日間のログのみを保持
    sudo journalctl --vacuum-time=7d
    
    # ディスク使用量を最大500MBに削減
    sudo journalctl --vacuum-size=500M
    

ジャーナルフィルタを絞り込みツールとして使用します:最初にブート、時間枠、ユニット、優先度を選択し、結果をアーカイブまたは解析する必要がある場合にのみ出力形式を変更します。