systemdのjournaldを理解する
journalの概要
journalはsystemdのログシステム。journalctl
コマンドでログ (journal entry) を読むことができる。systemdのserviceとして動いているものなので、次のようにするとjournalのserviceがactiveであることを確認できる。
$ systemctl status systemd-journald.service
● systemd-journald.service - Journal Service
Loaded: loaded (/usr/lib/systemd/system/systemd-journald.service; static)
Active: active (running) since Sat 2022-07-23 13:22:08 JST; 3min 15s ago
TriggeredBy: ● systemd-journald-dev-log.socket
● systemd-journald-audit.socket
● systemd-journald.socket
Docs: man:systemd-journald.service(8)
man:journald.conf(5)
Main PID: 248 (systemd-journal)
Status: "Processing requests..."
Tasks: 1 (limit: 18799)
Memory: 130.6M
CPU: 860ms
CGroup: /system.slice/systemd-journald.service
└─248 /usr/lib/systemd/systemd-journald
...
ログが書き込まれるディレクトリ
私が確認したArch Linuxの場合、/var/log/journal/
にログが貯まっていく。/etc/systemd/journald.conf
のStorage=
がauto
になっているとここにロギングされる。
他のディストリビューションはどうなんだろうと思い少し調べたところ、どうも$ man systemd-journald
でmanページのFILES
を見ればわかるっぽい。configファイルとログ書き込みファイルの一覧が確認できた。
$ man systemd-journald
...
FILES
/etc/systemd/journald.conf
Configure systemd-journald behavior. See journald.conf(5).
/run/log/journal/machine-id/*.journal, /run/log/journal/machine-id/*.journal~, /var/log/journal/machine-id/*.journal, /var/log/journal/machine-id/*.journal~
systemd-journald writes entries to files in /run/log/journal/machine-id/ or /var/log/journal/machine-id/ with the ".journal" suffix. If the daemon is stopped uncleanly, or if the files are found to be corrupted, they are renamed using the ".journal~" suffix, and systemd-journald starts writing to a new file. /run/ is used when /var/log/journal is not available, or when Storage=volatile is set in the journald.conf(5) configuration file.
...
もしこのディレクトリが削除されてもsystemdは同ディレクトリを自動的には作らない。代わりに/run/systemd/journal/
に非永続的なログを書き込んでいく。/etc/systemd/journald.conf
でStorage=persistent
として、systemd-journald.serviceをrestartする (またはコンピュータごと再起動する) と、/var/log/journal/
が再度作られる。
ちなみにこのディレクトリの中を覗いてみると分かるのだが、ファイルの内容は人間が見るように作られていないようだ。ログを読む場合はjournalctl
コマンドを使う。
Priority level / Facility
journalはPriority levelとFacilityによってログを分類する。Priority levelやFacilityはSyslog (RFC5424) で標準化されているものが使われている。(ここらへんに一覧がある。)
Priority level
ログ出力時にはこのpriority levelによって行が色付けされる。
- 0 = Emergency: system is unusable
- 1 = Alert: action must be take immediately
- 2 = Critical: critical conditions
- 3 = Error: error conditions
- 4 = Warning: warning conditions
- 5 = Notice: normal but significant conditions
- 6 = Informational: informational messages
- 7 = Debug: debug-level messages
Facility
20以上あるのでいくつかだけ。
- 0 = kernel messages
- 1 = user-level messages
- 2 = mail system
- 3 = system daemons
- 4 = security/authorization messages
- 5 = messages generated internally by syslog
...
journalctl
のフィルタリング例
いよいよログを出力する。
journalctl
をオプションなしで実行すると、journalが保持している全てのログが出力される。ただこれはかなりの量になり得るのであまり気軽に実行しない方が良いかも知れない。journalctl
には出力をフィルタリングするための様々なオプションがあるのでこれらを活用するのが良い。
(journalctl
の出力はデフォルトでless
に渡される。--no-pager
を付けるとただstdoutに出力されるだけになる。)
-b, --boot
起動してからのログを出力する。
$ journalctl -b
-g, -grep=
MESSAGEフィールドの値を正規表現でgrepする。
$ journalctl --grep=browser
-f, --follow
最新のログのみ表示され、以降新しいログができると追加で出力され続けていく。
$ journalctl -f
-S, --since=, -U, --until=
日時範囲の指定ができる。
$ journalctl --since="2022-07-03 00:00:00"
$ journalctl --since="2022-07-04 00:00:00" --until="2022-07-05 12:00:00"
こんな指定の仕方もできる。
$ journalctl --since="20 min ago"
-k, --dmesg
kernel ring bufferのみ出力する。
$ journalctl -k
-p, --priority=
priority levelの値を指定する。
$ journalctl -p 2
数値だけではなく略称でも指定できる。
$ journalctl -p crit
範囲指定もできる。
$ journalctl -p 0..2
--facility=
facilityの値を指定する。
$ journalctl --facility=1
カンマ区切りで複数のfacilityを指定できる。
$ journalctl --facility=0,1,3
実行ファイルのログ
特定の実行ファイルのログのみ出力する。
$ journalctl /usr/lib/systemd/systemd
オプションの組み合わせ
フィルタリングオプションは組み合わせることができる。
$ journalctl --since="1 week ago" --grep=browser
参照
- ArchWiki: systemd/Journal
- systemd-journaldのmanページ
- journalctlのmanページ
- Wikipedia: Syslog
- RFC5424
Discussion