【Linux】 journalctlコマンドで過去のログを出力する設定をしてみた。

Linux

journalctlコマンド

ログの確認という話になると、よく出てくるコマンドです。オプションを使うと日付を指定することもできます。本記事ではデフォルトでは保存されないログの保管から、過去のログの呼び出しまでを詳しく検証しています。

書式

journalctl [オプション]

オプション

オプション説明
-a (–all)画面に表示できない文字も含めて表示する。
-b (–boot)システムの起動時のログを見る。正の場合は最古から数え、負の場合は最新から数える。
※以下の例と、検証で確認。
-b 1-> 最古のログ
-b 2 -> 1より1つ新しいログ(以降3,4,….)
-b -1 -> 前回起動時のログ
-b -2 -> 前々回起動時のログ(以降-3,-4…)
-D (–directory)指定したディレクトリのログを表示する。
-e (–pager-end)末尾を表示する。
-f (–follow)出力されたログを表示する(tailコマンドの-fと似ています)
-k (–dmesg)カーネルからのメッセージを表示する。
-l (–full)全てのログを表示する。
-n (–lines)出力する行数を指定する(headを用いなくても良くなります)
–no-pagerlessコマンドで出力されず、catコマンドのように全てを表示します。ぜひとも-nオプションを併用しましょう(ログが多いので)
-o (–output)ログの出力形式を指定する。詳細表示(verbose)や、jsonなどが指定できる。short-monotonicを指定すると、起動してからの経過時間で表示される。
-r (–reverse)最新のログから表示します(sortコマンドと同じように、順番を逆にするイメージです)
–since指定した日付以降のログを表示します。
–until指定した日付より前のログを表示します。
-u (–unit)指定したunitのログを表示します。
–vacuum-sice=サイズアーカイブのジャーナルが指定したサイズを下回るまで、古いジャーナルを削除します。
–vacuum-time=時間指定した期間より古いアーカイブジャーナルを削除します。
-x説明文付きで表示します。
–list–bootbootした履歴を表示する。

検証

検証1 –no-ppager

デフォルトではlessコマンドが使用されるので、–no-pagerを使用し、さらに表示する行数を3行に指定します。lessコマンドで表示されるのが嫌いな人向け。

~ # journalctl --no-pager -n 3
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:04:46 JST. --
 1月 22 17:04:43 test01 systemd[1]: Started Network Manager Script Dispatcher Service.
 1月 22 17:04:46 test01 systemd[3341]: Starting Mark boot as successful...
 1月 22 17:04:46 test01 systemd[3341]: Started Mark boot as successful.

検証2 ログの保管設定

ブート時のログを見ます。デフォルトの設定では、再起動をすると、起動時のログは削除されます。以下はログ保管に関する設定を行っていない場合の出力です。「ないよ!」ということで、怒られます。

~ # journalctl -b 1 n -3
Specifying boot ID or boot offset has no effect, no persistent journal was found.

ログを保管し、journalctlで見られるようにするためには、「/etc/systemd/journald.conf」を編集します。編集前のデフォルトの状態は以下の状態になっています。

[root@localhost ~]# cat /etc/systemd/journald.conf
[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitInterval=30s
#RateLimitBurst=1000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48K

ログの保存を有効化するには、「#Storage」のコメントアウトを削除し、パラメータを「persistent」にします。また、格納されるジャーナルファイルの大きさを制限するために、「RuntimeUse」のパラメータも「5G」に設定しておきます。(このあたりの容量は任意)

~ # grep -v "#" /etc/systemd/journald.conf
[Journal]
Storage=persistent
RuntimeMaxUse=5G #容量の制限を5Gにしています。

※systemd-journaldを再起動することで設定を有効化できます。

さて、検証ために、OSを2回再起動しました。

まずは日付の確認をします。

~ # journalctl --list-boots
-2 a7256d8c9c004003a6038f578cc1d831 Wed 2021-01-20 16:46:27 JST—Fri 2021-01-22 15:54:32 JST //3番目に新しい
-1 ab5da7a178374cd589aa5aea13916755 Fri 2021-01-22 15:54:50 JST—Fri 2021-01-22 16:21:58 JST //2番目に新しい
 0 a3d40a59839449aa9f72750a0ee3bc72 Fri 2021-01-22 16:22:19 JST—Fri 2021-01-22 17:33:49 JST //1番新しい

今回の起動分を含め、合計3回分(過去の分は2回分)保存されています。

上から順に古く、一番下に出力されているログが1番新しいログになります。
オプションでも説明していますが、新しいログから数える場合は負の数で指定します。上記の結果の一番左に「-2」や「-1」とあります。「0」が一番新しく、この負の数が絶対数が大きくなるほど、古いログにということになります。

※基本的には負の数で指定すればわかりやすいですが、古いログから数えたい場合は正の数で指定します。「journalctl –list-boots」で表示される番号をそのまま流用できる点では、負の数で指定したほうがわかりやすい気もしますが、一応確認しています。

負の数で指定

前々回起動時のログを見ます。「-b -2 」で指定します。

~ # journalctl --no-pager -b -2 -n 3
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:04:46 JST. --
 1月 22 15:54:32 dns01 systemd-shutdown[1]: Syncing filesystems and block devices.
 1月 22 15:54:32 dns01 systemd-shutdown[1]: Sending SIGTERM to remaining processes...
 1月 22 15:54:32 dns01 systemd-journald[28028]: Journal stopped

前回起動時のログを見ます。 「-b -1 」で指定します。

~ # journalctl --no-pager -b -1 -n 3
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:04:46 JST. --
 1月 22 16:21:58 dns01 systemd-shutdown[1]: Syncing filesystems and block devices.
 1月 22 16:21:58 dns01 systemd-shutdown[1]: Sending SIGTERM to remaining processes...
 1月 22 16:21:58 dns01 systemd-journald[705]: Journal stopped

正の数で指定

最古のログを見ます。最古のログは、上記の「前々回の起動時のログ」と同じになるはずです。 「-b 1 」で指定します。

~ # journalctl --no-pager -b 1 -n 3
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:04:46 JST. --
 1月 22 15:54:32 dns01 systemd-shutdown[1]: Syncing filesystems and block devices.
 1月 22 15:54:32 dns01 systemd-shutdown[1]: Sending SIGTERM to remaining processes...
 1月 22 15:54:32 dns01 systemd-journald[28028]: Journal stopped

次に、最古のログより1つ新しいログを見ます。これは上記の「前回起動時のログ」と同じになります。 「-b 2 」で指定します。

~ # journalctl --no-pager -b 2 -n 3
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:04:46 JST. --
 1月 22 16:21:58 dns01 systemd-shutdown[1]: Syncing filesystems and block devices.
 1月 22 16:21:58 dns01 systemd-shutdown[1]: Sending SIGTERM to remaining processes...
 1月 22 16:21:58 dns01 systemd-journald[705]: Journal stopped

今回起動した際のログを見ます。

~ # journalctl --no-pager -n 3
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:04:46 JST. --
 1月 22 17:04:43 test01 systemd[1]: Started Network Manager Script Dispatcher Service.
 1月 22 17:04:46 test01 systemd[3341]: Starting Mark boot as successful...
 1月 22 17:04:46 test01 systemd[3341]: Started Mark boot as successful.

ややこしいですが、基本的に負の数指定のほうが操作しやすいですね。

検証3 形式指定して出力する

形式を変更して出力します。まずは指定しない場合。

~ # journalctl --no-pager -n 1
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:04:46 JST. --
 1月 23 17:04:46 test01 systemd[3341]: Started Mark boot as successful.

上記のログをjson形式で出力します。

~ # journalctl --no-pager -o json -n 1
{ "__CURSOR" : "s=1b32cb1c8e35442891d4d0b1df421650;i=1e58;b=a3d40a59839449aa9f72750a0ee3bc72;m=964bc620;t=5b978a442eb79;x=c80c3f633103313a", "__REALTIME_TIMESTAMP" : "1611302686616441", "__MONOTONIC_TIMESTAMP" : "2521548320", "_BOOT_ID" : "a3d40a59839449aa9f72750a0ee3bc72", "PRIORITY" : "6", "SYSLOG_FACILITY" : "3", "SYSLOG_IDENTIFIER" : "systemd", "_TRANSPORT" : "journal", "_PID" : "3341", "_UID" : "1001", "_GID" : "1001", "_COMM" : "systemd", "_EXE" : "/usr/lib/systemd/systemd", "_CMDLINE" : "/usr/lib/systemd/systemd --user", "_CAP_EFFECTIVE" : "0", "_SELINUX_CONTEXT" : "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023", "_AUDIT_SESSION" : "7", "_AUDIT_LOGINUID" : "1001", "_SYSTEMD_CGROUP" : "/user.slice/user-1001.slice/user@1001.service/init.scope", "_SYSTEMD_OWNER_UID" : "1001", "_SYSTEMD_UNIT" : "user@1001.service", "_SYSTEMD_USER_UNIT" : "init.scope", "_SYSTEMD_SLICE" : "user-1001.slice", "_SYSTEMD_USER_SLICE" : "-.slice", "_SYSTEMD_INVOCATION_ID" : "6327954a554747a592d7a1c0a2a56d2a", "_MACHINE_ID" : "dc5600e8ce2a4188ada0a0e68d9269ac", "CODE_FILE" : "../src/core/job.c", "CODE_LINE" : "827", "CODE_FUNC" : "job_log_status_message", "JOB_TYPE" : "start", "JOB_RESULT" : "done", "MESSAGE_ID" : "39f53479d3a045ac8e11786248231fbf", "USER_UNIT" : "grub-boot-success.service", "USER_INVOCATION_ID" : "d5ae503e09584f259b929b029e6a946d", "_HOSTNAME" : "test01", "MESSAGE" : "Started Mark boot as successful.", "_SOURCE_REALTIME_TIMESTAMP" : "1611302686615647" }

すごくたくさん出てきた!といっても、one lineで出力されているからわかりにくいですよね。以下、整形した結果を載せておきます。

{
	"__CURSOR": "s=1b32cb1c8e35442891d4d0b1df421650;i=1e58;b=a3d40a59839449aa9f72750a0ee3bc72;m=964bc620;t=5b978a442eb79;x=c80c3f633103313a",
	"__REALTIME_TIMESTAMP": "1611302686616441",
	"__MONOTONIC_TIMESTAMP": "2521548320",
	"_BOOT_ID": "a3d40a59839449aa9f72750a0ee3bc72",
	"PRIORITY": "6",
	"SYSLOG_FACILITY": "3",
	"SYSLOG_IDENTIFIER": "systemd",
	"_TRANSPORT": "journal",
	"_PID": "3341",
	"_UID": "1001",
	"_GID": "1001",
	"_COMM": "systemd",
	"_EXE": "/usr/lib/systemd/systemd",
	"_CMDLINE": "/usr/lib/systemd/systemd --user",
	"_CAP_EFFECTIVE": "0",
	"_SELINUX_CONTEXT": "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023",
	"_AUDIT_SESSION": "7",
	"_AUDIT_LOGINUID": "1001",
	"_SYSTEMD_CGROUP": "/user.slice/user-1001.slice/user@1001.service/init.scope",
	"_SYSTEMD_OWNER_UID": "1001",
	"_SYSTEMD_UNIT": "user@1001.service",
	"_SYSTEMD_USER_UNIT": "init.scope",
	"_SYSTEMD_SLICE": "user-1001.slice",
	"_SYSTEMD_USER_SLICE": "-.slice",
	"_SYSTEMD_INVOCATION_ID": "6327954a554747a592d7a1c0a2a56d2a",
	"_MACHINE_ID": "dc5600e8ce2a4188ada0a0e68d9269ac",
	"CODE_FILE": "../src/core/job.c",
	"CODE_LINE": "827",
	"CODE_FUNC": "job_log_status_message",
	"JOB_TYPE": "start",
	"JOB_RESULT": "done",
	"MESSAGE_ID": "39f53479d3a045ac8e11786248231fbf",
	"USER_UNIT": "grub-boot-success.service",
	"USER_INVOCATION_ID": "d5ae503e09584f259b929b029e6a946d",
	"_HOSTNAME": "test01",
	"MESSAGE": "Started Mark boot as successful.",
	"_SOURCE_REALTIME_TIMESTAMP": "1611302686615647"
}

以下は「vernose -n 1」で詳細表示を出力させています。よく見ると以下のログをjson形式によく似ていますね。

~ # journalctl --no-pager -o verbose -n 1
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:04:46 JST. --
Fri 2021-01-23 17:04:46.615647 JST [s=1b32cb1c8e35442891d4d0b1df421650;i=1e58;b=a3d40a59839449aa9f72750a0ee3bc72;m=964bc620;t=5b978a442eb79;x=c80c3f633103313a]
    PRIORITY=6
    SYSLOG_FACILITY=3
    SYSLOG_IDENTIFIER=systemd
    _TRANSPORT=journal
    _PID=3341
    _UID=1001
    _GID=1001
    _COMM=systemd
    _EXE=/usr/lib/systemd/systemd
    _CMDLINE=/usr/lib/systemd/systemd --user
    _CAP_EFFECTIVE=0
    _SELINUX_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    _AUDIT_SESSION=7
    _AUDIT_LOGINUID=1001
    _SYSTEMD_CGROUP=/user.slice/user-1001.slice/user@1001.service/init.scope
    _SYSTEMD_OWNER_UID=1001
    _SYSTEMD_UNIT=user@1001.service
    _SYSTEMD_USER_UNIT=init.scope
    _SYSTEMD_SLICE=user-1001.slice
    _SYSTEMD_USER_SLICE=-.slice
    _SYSTEMD_INVOCATION_ID=6327954a554747a592d7a1c0a2a56d2a
    _BOOT_ID=a3d40a59839449aa9f72750a0ee3bc72
    _MACHINE_ID=dc5600e8ce2a4188ada0a0e68d9269ac
    CODE_FILE=../src/core/job.c
    CODE_LINE=827
    CODE_FUNC=job_log_status_message
    JOB_TYPE=start
    JOB_RESULT=done
    MESSAGE_ID=39f53479d3a045ac8e11786248231fbf
    USER_UNIT=grub-boot-success.service
    USER_INVOCATION_ID=d5ae503e09584f259b929b029e6a946d
    _HOSTNAME=test01
    MESSAGE=Started Mark boot as successful.
    _SOURCE_REALTIME_TIMESTAMP=1611302686615647

すごいですね。たった1行のログですが、詳細表示にするとこの量になりました。

検証4 末尾から出力する

-eオプションを使うと、末尾から表示してくれます。

~ # journalctl --no-pager -e -n 3
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:27:26 JST. --
 1月 22 17:27:21 test01 httpd[3877]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::54dd:47e6:e1b:1bc2. Set the 'ServerName' directive globally to suppress this message
 1月 22 17:27:21 test01 systemd[1]: Started The Apache HTTP Server.
 1月 22 17:27:26 test01 httpd[3877]: Server configured, listening on: port 80

検証5 末尾から出力する

-rオプションを指定しても最新のログから表示してくれます。

~ # journalctl --no-pager -r -n 3
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:27:26 JST. --
 1月 22 17:27:21 test01 httpd[3877]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::54dd:47e6:e1b:1bc2. Set the 'ServerName' directive globally to suppress this message
 1月 22 17:27:19 test01 systemd[1]: Starting The Apache HTTP Server...
 1月 22 17:27:19 test01 systemd[1]: Stopped The Apache HTTP Server.

検証6 日付指定をする

日付を指定します。以下は2021-01-21の12:00〜18:00を指定しています。

~ # journalctl --since "2021-01-21 12:00" --until "2021-01-21 18:00" --no-pager
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:33:49 JST. --
 1月 21 12:01:01 dns01 CROND[12877]: (root) CMD (run-parts /etc/cron.hourly)
 1月 21 12:01:01 dns01 run-parts[12880]: (/etc/cron.hourly) starting 0anacron
 1月 21 12:01:01 dns01 run-parts[12886]: (/etc/cron.hourly) finished 0anacron
(途中省略) 
 1月 21 17:02:16 dns01 systemd[1]: Started Cleanup of Temporary Directories.
 1月 21 17:02:56 dns01 systemd[1]: Starting dnf makecache...
 1月 21 17:02:57 dns01 dnf[15470]: メタデータキャッシュは最近、リフレッシュされました。
 1月 21 17:02:57 dns01 systemd[1]: Started dnf makecache.

検証7 詳細表示をする

-xオプションで、説明をつけて表示します。結構便利です。トラブルシューティング時に活躍します。とはいえ、エラー発生時にログを見ても「つまり…このログの意味なんだろう?」ってことはよくありますね笑

~ # journalctl --no-pager -n 2 -x
-- Logs begin at Wed 2021-01-20 16:46:27 JST, end at Fri 2021-01-22 17:27:26 JST. --
 1月 22 17:27:21 test01 systemd[1]: Started The Apache HTTP Server.
-- Subject: Unit httpd.service has finished start-up
-- Defined-By: systemd
-- Support: https://access.redhat.com/support
--
-- Unit httpd.service has finished starting up.
--
-- The start-up result is RESULT.
 1月 22 17:27:26 test01 httpd[3877]: Server configured, listening on: port 80