22.10. Journal の使用

Journal は systemd のコンポーネントで、ログファイルの表示および管理を担います。rsyslogd などの従来の syslog デーモンとの並列もしくはその代わりとして使用できます。Journal は、従来のロギングに関連する問題を処理するために開発されました。システムの他の部分と緊密に統合されており、様々なロギング技術およびログファイルのアクセス管理をサポートします。
ロギングデータは、Journal の journald サービスが収集、保存、処理を行います。カーネルやユーザー処理、標準出力、システムサービスの標準エラー出力、またはネイティブ API 経由から受信したロギング情報に基づいて、journals と呼ばれるバイナリーファイルを作成、維持します。これらの journals は構造化およびインデックス化され、これによりシーク時間が比較的速くなります。Journal エントリーは、一意の識別子を持つことが可能です。journald サービスは、各ログメッセージについて多数のメタデータを収集します。実際の journal ファイルはセキュリティー保護され、手動での編集はできません。

22.10.1. ログファイルの表示

journal ログにアクセスするには、journalctl ツールを使用します。ログタイプの基本的なビューを見るには、root で以下を入力します。
journalctl
このコマンドの出力は、システム上で生成されたすべてのログファイル一覧で、これにはシステムコンポーネントやユーザーが生成したメッセージも含まれます。この出力の構造は、/var/log/messages/ で使用されているものに似ていますが、以下の改善点があります。
  • エントリーの優先度が視覚的にマークされています。エラー優先度およびそれ以上の行は赤色のハイライト表示がされており、注意および警告の優先度の行には太字フォントが使われています。
  • タイムスタンプが使用中のシステムのローカルタイムゾーンに変換されます。
  • ローテーションされたログを含めて、すべてのログ記録済みデータが表示されます。
  • ブートの最初が特別行にタグ付けされます。

例22.18 journalctl の出力例

以下は、journalctl ツールが提供する出力例です。パラメーターなしで呼び出されると、エントリー一覧がタイムスタンプで始まり、その後にホスト名、操作を実行したアプリケーションが示され、実際のメッセージが続きます。この例では、journal ログの初めの 3 つのエントリーを表示しています。
# journalctl
-- Logs begin at Thu 2013-08-01 15:42:12 CEST, end at Thu 2013-08-01 15:48:48 CEST. --
Aug 01 15:42:12 localhost systemd-journal[54]: Allowing runtime journal files to grow to 49.7M.
Aug 01 15:42:12 localhost kernel: Initializing cgroup subsys cpuset
Aug 01 15:42:12 localhost kernel: Initializing cgroup subsys cpu

[...]
多くのケースでは、journal ログの最新のエントリーにのみ関連します。journalctl 出力を減らす簡単な方法としては、-n オプションを使用して、最新のログエントリーを指定した数だけ表示します。
journalctl -n Number
Number を、表示する行数に置き換えます。数字を指定しないと、journalctl では最新の 10 エントリーが表示されます。
journalctl コマンドを使用すると、以下の構文で出力形式をできます。
journalctl -o form
form を、出力形式を指定するキーワードに置き換えます。verbose オプションを使用すると、全フィールドをともなう完全構造化エントリーアイテムが返されます。export を使用すると、バックアップおよびネットワーク転送に適したバイナリーストリームを作成します。json を使用すると、エントリーを JSON データ構造としてフォーマットします。キーワードの一覧は、man ページ journalctl(1) を参照してください。

例22.19 詳細な journalctl 出力

すべてのエントリーに関する完全なメタデータを表示するには、以下を入力します。
# journalctl -o verbose
[...]

Fri 2013-08-02 14:41:22 CEST [s=e1021ca1b81e4fc688fad6a3ea21d35b;i=55c;b=78c81449c920439da57da7bd5c56a770;m=27cc
        _BOOT_ID=78c81449c920439da57da7bd5c56a770
        PRIORITY=5
        SYSLOG_FACILITY=3
        _TRANSPORT=syslog
        _MACHINE_ID=69d27b356a94476da859461d3a3bc6fd
        _HOSTNAME=localhost.localdomain
        _PID=562
        _COMM=dbus-daemon
        _EXE=/usr/bin/dbus-daemon
        _CMDLINE=/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
        _SYSTEMD_CGROUP=/system/dbus.service
        _SYSTEMD_UNIT=dbus.service
        SYSLOG_IDENTIFIER=dbus
        SYSLOG_PID=562
        _UID=81
        _GID=81
        _SELINUX_CONTEXT=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023
        MESSAGE=[system] Successfully activated service 'net.reactivated.Fprint'
        _SOURCE_REALTIME_TIMESTAMP=1375447282839181
        
[...]
この例では、単一ログエントリーを識別するフィールドを一覧表示しています。「高度なフィルタリング」 の説明にあるように、これらのメタデータはメッセージのフィルタリングに使用できます。全フィールドの説明は man ページ systemd.journal-fields(7)を参照してください。

22.10.2. アクセス制御

デフォルトでは、root 権限のない Journal ユーザーは、自身の生成したログファイルしか見れません。システム管理者が特定のユーザーを adm グループに追加すると、これらユーザーはすべてのログファイルにアクセスできるようになります。これを実行するには、root で以下を入力します。
usermod -a -G adm username
username を、adm グループに追加するユーザー名に置き換えると、このユーザーは、root ユーザーと同様の journalctl コマンド出力を受け取るようになります。アクセス制御が機能するのは、Journal の永続ストレージが有効になっている場合に限定されることに注意してください。

22.10.3. ライブビューの使用

パラメーターを付けずに journalctl を呼び出すと、収集されたエントリーのうち最も古いものから一覧表示します。ライブビューでは、新たなエントリーが現れると継続的に印刷されるので、リアルタイムでログメッセージを監視できます。journalctl をライブビューモードで開始するには、以下を入力します。
journalctl -f
このコマンドは、最新のログ 10 行を返します。その後は journalctl ユーティリティーの実行が継続され、新たな変化があるとそれを直ちに表示します。

22.10.4. メッセージのフィルタリング

パラメーターを付けずに実行した journalctl コマンドの出力は大規模なものになることが多いため、様々なフィルタリング方法を使うとユーザーのニーズに合った情報を抽出できます。

優先度によるフィルタリング

ログメッセージは、システム上の間違った動作を追跡するために使用されることがよくあります。特定のエントリーまたはより高い優先度のエントリーのみを表示するには、以下の構文を使用します。
journalctl -p priority
priority を、キーワード debug (7)、info (6)、notice (5)、warning (4)、err (3)、crit (2)、alert (1)、または emerg (0) のいずれか (または数字) に置き換えます。

例22.20 優先度によるフィルタリング

error もしくはそれ以上の優先度のエントリーのみを表示するには、以下を使用します。
journalctl -p err

時間によるフィルタリング

現在のブートのログエントリーのみを表示するには、以下を入力します。
journalctl -b
システムを頻繁に再起動しない場合は、-b を使用しても、journalctl の出力が大幅に削減されません。この場合は、時間ベースのフィルタリングの方が役に立ちます。
journalctl --since=value --until=value
--since および --until を使用すると、特定の時間枠内に作成されたログメッセージのみを表示できます。これらのオプションに渡す values は、以下の例で示すように日付か時間、または両方の形式で示すことができます。

例22.21 時間および優先度によるフィルタリング

フィルタリングオプションは組み合わせることで、特定のリクエストに沿って結果を絞り込むことができます。たとえば、warning またはそれ以上の優先度で、特定の時刻以降のメッセージのみを表示するには、以下を使用します。
journalctl -p warning --since="2013-3-16 23:59:59"

高度なフィルタリング

例22.19「詳細な journalctl 出力」 では、ログエントリーを特定し、フィルタリングに使用できるフィールドを一覧表示しています。systemd が保存可能なメタデータのすべての説明は、man ページ systemd.journal-fields(7) を参照してください。各ログメッセーに対するこのメタデータは、ユーザーが介入することなく収集されます。値は通常テキストベースですが、バイナリーの大きな値になることもあります。フィールドには複数の値がある場合もありますが、一般的ではありません。
指定されたフィールドで発生する一意の値を一覧表示するには、以下の構文を使用します。
journalctl -F fieldname
fieldname を関心のあるフィールド名に置き換えます。
特定条件のみに合致するログエントリーのみを表示するには、以下の構文を使用します。
journalctl fieldname=value
fieldname をフィールド名に、value をそのフィールドに含まれる特定の値に置き換えます。そうすると、この条件に合致する行のみが返されます。

注記

systemd に保存されているメタデータフィールドはかなりの数になるので、関心のあるフィールド名そのものを忘れることがよくあります。名前が不確かな場合は、以下を入力します。
journalctl
そして、Tab キーを 2 回押します。これで、利用可能なフィールド名が一覧表示されます。コンテキストベースの Tab 補完入力はフィールド名で機能するので、フィールド名の明確な文字を入力して Tab を押すと、名前が自動的に完了します。同様に、フィールドから一意の値を一覧表示することもできます。以下を入力します。
journalctl fieldname=
そして Tab を 2 回押します。これは、journalctl -F fieldname の代わりとなります。
1 つのフィールドに複数の値を指定することもできます。
journalctl fieldname=value1 fieldname=value2 ...
同一フィールドで 2 つの値を指定すると、2 つの値の論理 OR 演算が行われます。value1 または value2 に一致するエントリーが表示されます。
複数のフィールドと値の組み合わせを指定して、出力をさらにしぼり込むこともできます。
journalctl fieldname1=value fieldname2=value ...
異なるフィールド名に対して 2 つの値を指定すると、値は論理 AND で合算されます。エントリーが表示されるには、両方の条件を満たす必要があります。
+ 記号を使うと、複数のフィールドに対して複数の値の論理 OR 演算を行えます。
journalctl fieldname1=value + fieldname2=value ...
このコマンドは、両方の条件に合致するエントリーだけでなく、少なくとも条件の 1 つに合致するエントリーを返します。

例22.22 高度なフィルタリング

UID 70 のユーザーが avahi-daemon.service または crond.service で作成したエントリーを表示するには、以下のコマンドを使用します。
journalctl _UID=70 _SYSTEMD_UNIT=avahi-daemon.service _SYSTEMD_UNIT=crond.service
_SYSTEMD_UNIT フィールドに 2 つの値があるため、両方の結果が表示されますが、これは _UID=70 の条件に合致する場合のみです。これは単に (UID=70 and (avahi or cron)) と表すこともできます。
上記のフィルタリングをライブビューモードで適用して、特定のログエントリーグループにおける最新の変更を追跡することもできます。
journalctl -f fieldname=value ...

22.10.5. 永続的ストレージの有効化

Journal はデフォルトでは、ログファイルをメモリーか /run/log/journal/ ディレクトリー内の小さいリングバッファーにのみ保存します。これは、journalctl の最近のログ履歴を表示するには十分なものです。このディレクトリーは揮発性なので、ログデータは永続的には保存されません。デフォルト設定では、syslog は journal ログを読み取り、/var/log/ ディレクトリーに保存します。永続的なロギングが有効になると、journal ファイル /var/log/journal に保存され、再起動後も維持されます。これにより、一部のユーザーにとっては、Journal が rsyslog の代わりとなることも可能です (ただし、本章の序論を参照のこと)。
永続的ストレージを有効にすると、以下の利点があります。
  • 長期的なトラブルシュートに使用できる、より豊富なデータが記録されます。
  • 直ちにトラブルシュートを行う場合には、再起動後により多くのデータが利用可能になります。
  • サーバーコンソールがログファイルからではなく、journal からデータを読み取ります。
永続的なストレージには、不利な点もあります。
  • 永続的なストレージを使用しても、保存されるデータ量はメモリーの空き容量に依存するため、全期間を保存できる保証はありません。
  • ログにより、多くのディスクスペースが必要になります。
Journal 用に永続的なストレージを有効にするには、以下の例のように手動で journal ディレクトリーを作成します。root で以下を入力します。
mkdir -p /var/log/journal/
その後に journald を再起動して、変更を適用します。
systemctl restart systemd-journald