@kyanny's blog

My thoughts, my life. Views/opinions are my own.

How to use journalctl

自分の中で少し整理できたので改めて。ドキュメントは man journalctl で読める。それなりに長くて盛りだくさんだけど、必要なオプション一つずつ読んでいけばそこまで負担ではない。

ログをフィルタする書式の基本

FIELD=VALUE という書式でフィルタする。

journalctl UNIT=ssh.service

FIELD については man systemd.journal-fields で解説されている。よく知られているフィールド名の説明がある。

フィールドは journald にログを記録する任意のプロセスによって追加されうる。例: docker の CONTAINER_TAG など。

アンダースコアで始まるフィールド名は予約語で、任意に追加することはできない。

-N, --fields

指定可能なフィールド名の一覧を得る。

-F, --field=

指定したフィールドの VALUE として指定可能な値の一覧を得る。

-N-F で全部のフィルタの組み合わせを網羅的に調べることも、一応できる。が、実際にはよく使う組み合わせをある程度覚えてしまうことになりそう。

-u, --unit=

UNIT 単位でフィルタする。UNIT=unit_name.service または _SYSTEMD_UNIT=unit_name.service のショートカット。だが -u は .service を省略できたり追加で表示されるログもあり、通常はこちらを使うのが良い。

journalctl -u ssh

-t, --identifier=

Syslog identifier でフィルタする。SYSLOG_IDENTIFIER=identifier のショートカット。

Syslog identifier というのは、

Dec 30 09:32:57 ip-172-26-4-82 sshd[10640]: Disconnected from invalid user user 205.185.122.174 port 36792 [preauth]

こういうログの sshd に相当する。10640 はおそらくプロセス ID か。

journalctl -t sshd

-S, --since=, -U, --until=

ログのタイムスタンプで絞り込む。日時の書式は "2012-10-30 18:17:16" という形式で指定する。時間が省略された場合は "00:00:00" が指定されたものとみなす。

journalctl -S "2021-12-30 09:30:00" -U "2021-12-30 09:40:00"

"yesterday", "today", "tomorrow", "now" という指定も可能。

journalctl -S now --follow

"+", "-" で相対日時の指定も可能。これはちょっとややこしい。

journalctl -S "-1m"

詳細な書式は man systemd.time を参照。

--utc

ログのタイムスタンプを UTC に変換して表示する。システムのタイムゾーンが UTC の場合は不要。

-g, --grep=

ログのメッセージに対して PCRE(Perl 互換の正規表現)でフィルタできる。ただし journalctl がこの機能をサポートしてコンパイルされていないと使えない。Ubuntu で systemd を PCRE2 有効化してインストールし直す方法は調べたけどわからなかった。

MESSAGE= と同じ意味。ただ、この方式で指定することはまずないだろう。

-f, --follow

tail -f と同じ。

-r, --reverse

ログをタイムスタンプ逆順で表示する。

-n --lines=

指定した行数だけログを表示する。tail -n と同じ。

-o, --output=

ログ出力フォーマットを色々変えられる。JSON 形式とかでも出力できる。形式によって追加の情報が出力される。

journalctl -o json-pretty

-o json-sse で Server-Sent Events の形式に整形して出力することもできる。何に使うかわからないが、すごい。

-o cat でログメッセージだけ出力できる。タイムスタンプもないので調査には向かないが、ログのメッセージだけ取り出して加工したりする際に自前で文字列処理をしなくて済む。

--output-fields=

-o verbose とか -o json みたいな出力フォーマットと同時に指定して、特定のフィールドの情報だけ出力できる。

フィールドはカンマ区切りで複数指定できる。カンマの前後にスペースがあると以降のフィールド指定が無視されるので注意。クォートしてもダメなので繋げて指定する。あるいは --output-fields を複数回指定することもできる。

journalctl -o json-pretty --output-fields "SYSLOG_IDENTIFIER,MESSAGE" --output-fields SYSLOG_FACILITY

いくつかのフィールドは必ず出力される。それ以外のフィールドをすべて非表示にするには --output-fiels に空文字列を指定する。

journalctl -o json-pretty --output-fields ""