Ubuntu Weekly Recipe

第546回 journaldとsyslogの関係

この記事を読むのに必要な時間:およそ 2.5 分

前回に引き続き,systemd-journald(以下,journald)について解説します。今回はrsyslogとの関わりを中心に,journaldを見ていきます。

journaldによるログの受信とrsyslogへの転送

systemd環境ではjournaldがシステムやサービスのログを一手に集めています。一方で,Ubuntuでは従来からのログ収集・格納サービスであるrsyslogが現在も稼働しています。おそらく,後方互換性のためと筆者は考えています。

詳しくは後述しますが,実際にはsystemd環境ではjournaldがまずシステム上のログを受け取り,必要に応じてrsyslogへログを転送しています。

たとえば,journaldは/dev/kmsgを通じてカーネルログを集めていますし,/dev/logより従来のsyslog宛てのログも集めています。もちろん,ネイティブのjournalプロトコルを通じて送られてくる,ジャーナルに書き込むべきログも集めています。

標準出力・標準エラー出力からのログの記録を確かめる

筆者がすこし変わっていると思うのは,サービスユニットの標準出力および標準エラー出力もジャーナルに記録している点です。

簡単に検証してみます。以下のような,標準出力および標準エラー出力にメッセージを出力するスクリプトを作成し,適切に実行権限を付与します。ファイル名はjournald-stdout-verify.shとします。

#!/bin/bash

echo "Standard Output"
echo "Standard Error" >&2

一時的なユニット生成・実行できるsystemd-runコマンド※1を使って,このスクリプトを一時的なサービスとして実行します。

※1
systemd-runについては,回を改めて解説したい気持ちがあります。
$ sudo systemd-run ./journald-stdout-verify.sh

Running as unit: run-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.serviceと表示されます。

このサービスのジャーナルを見ると,標準出力と標準エラー出力が記録されていることを確認できます。

$ journalctl -u run-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.service
[...]
[...] systemd[X]: Started /home/xxxx/xxxx/./journald-stdout-verify.sh.
[...] journald-stdout-verify.sh[XXXX]: Standard Output
[...] journald-stdout-verify.sh[XXXX]: Standard Error

標準出力・標準エラー出力のrsyslogへの転送

Ubuntuではjournaldとrsyslogとのどちらもが動いていますが,journaldがまずこれらのログを読み取ります。

そして,journaldが入手したすべてのログがrsyslogへ転送されます。Ubuntuのデフォルトでは/etc/systemd/journald.confの設定がForwardToSyslog=yesMaxLevelSyslog=debugになっているからです。

systemdの場合はデフォルトで,サービスの標準出力および標準エラー出力もjournaldにつながっているため,その内容はsyslogにも転送されています。

$ grep journald-stdout-verify /var/log/syslog
[...] systemd[1]: Started /home/xxxx/xxxx/./journald-stdout-verify.sh.
[...] journald-stdout-verify.sh[xxxx]: Standard Output
[...] journald-stdout-verify.sh[xxxx]: Standard Error

しかしSysV系initの場合は,サービスデーモンは標準出力および標準エラー出力を/dev/nullにつないでいるため,ログは必要に応じてrsyslogなどに投げていました※2)⁠

※2
SysV系initでのデーモンとsystemdでのデーモンとの比較についてはmanページを参照してください。

このような挙動から,サービスの仕様や設計,動作,journald側の設定にもよりますが,同じサービスにもかかわらず,SysV系initではsyslogに表示されていなかったメッセージが,systemdのシステムの場合は表示されることがありえます。つまりsyslogを眺めることで,一方の環境ではエラーが出るにもかかわらず,他方の環境ではエラーが出ないといったトラブルシューティングの役には立つ可能性があります。

どこで収集されたログかを確認する

各ログについてjournaldがどこから収集したものかは,詳細ログの_TRANSPORT=フィールドで確認できます。

_TRANSPORT=フィールドを確認するためには,-o verboseを付与してjournalctlを実行します。以下は,先ほどのjournald-stdout-verify.shを実行したときのログの例です。

$ journalctl -u run-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.service --no-pager -o verbose
[...]
    # サービス開始メッセージ(ジャーナルに向けて出力)
    _TRANSPORT=journal
    [...]
    MESSAGE=Started /home/xxxx/xxxx/./journald-stdout-verify.sh.
[...]
    # 標準出力
    _TRANSPORT=stdout
    [...]
    MESSAGE=Standard Output
[...]
    # 標準エラー出力
    _TRANSPORT=stdout
    [...]
    MESSAGE=Standard Error

_TRANSPORT=stdoutとなっているとおり,標準出力・標準エラー出力からログが収集されていることを確認できます。

なお,systemdの開発者であるLennartPoetteringのブログ記事ではsyslog()printf()sd_journal_send()と,journaldにログを拾わせる3つの方法を紹介しています。詳細が気になる方はこちらも参照してください。

フィールド

話の流れで先に_TRANSPORT=フィールドを取り上げましたが,journaldのフィールドについて簡単に触れておきます※3)⁠

※3
フィールドの網羅的な解説はmanページを確認してください。

フィールドには大きく分けて2種類,ユーザージャーナルフィールドとトラステッドジャーナルフィールドがあります。

ユーザージャーナルフィールドはサービスなどが報告してきた情報が記録されるフィールドです。メッセージ本文を示すMESSAGE=や文字通りプライオリティを示すPRIORITY=syslogとの互換性のためのSYSLOG_FACILITY=SYSLOG_IDENTIFIER=SYSLOG_PID=などです。

ちなみにjournald-stdout-verify.shからの標準出力を記録したログでは,PRIORITY=6(info)であることを確認できます。

一方,トラステッドジャーナルフィールドはjournaldにより情報が付与されるフィールドで,フィールド名の先頭に_が付与されています。特徴として,これらの情報はjournald側でのみ記録が可能なことです。ログを送ってくる側の都合で設定や変更はできません。そのような性質から,⁠信頼できる(trusted)⁠フィールドと言えます。

たとえば,ログを送ってきたプロセスのID_PIDや実行ユーザーのID_UIDなどがあります。先ほどの_TRANSPORTも先頭に_があり,こちらに該当します。

なお,_BOOT_ID=は次項各カーネルの起動ごとに割り振られるランダムなIDです。これで,どのブート時のログかを区別できます。

ブートごとのIDは--list-bootsオプションを付けることで確認できます。

$ journalctl --list-boots

ジャーナルを残す設定の場合,あるブートの時のログを確認するオプション-b${_BOOT_ID}±nという形式を取ることも可能です。これにより,あるブート時のログから相対的にn回前・後のブートを指定してジャーナルを確認できます。

ログは誰の手に?

一部ではありますが,前回と今回でsystemdでのログ収集・管理について解説してきました。

journald.confのmanページにある記述ではsyslogに"traditional"の形容詞がついていることからも,syslogの置き換えを目指してjournaldやjournalctlがつくられていることが窺えます。ログを集めて管理し,閲覧するという点では,journaldやjournalctlは十分に実用的なレベルになっているしょう※4)⁠

※4
ログのリモート転送も可能です。これについても別の機会に解説できればと考えています。

一方で,すでに述べたとおり,Ubuntuではrsyslogが併用されています。サーバーの監視ソフトウェアなどがsyslogのログデータを読む限り,当面の間syslogの出番がまったくなくなることはないとは思います。

逆に,そのようなサーバー用途でもない限り,journaldだけでいいのではないか,という考え方もできそうです。よって,デスクトップ版のUbuntuではjournaldだけが動いているという未来はそう遠くはないタイミングに訪れるのでは,と筆者は考えています。

著者プロフィール

たなかあきら

Ubuntu Japanese Team Member。ちょっとお高い電子辞書を買ったので,楽しく翻訳をしていたところ,気づいたらメンバーになっていました。

コメント

コメントの記入