CentOSのログ出力の仕組み (journaldとrsyslog)

CentOSのログ出力について今まで雰囲気で乗り切っていましたが、いい加減に仕組みを覚えようと思い立ち、手を動かしながら調べてみました。

CentOSのログ出力の概要

CentOSのログ出力は以下の概要図の通りです。journaldrsyslogが連携して動作しています。

journaldとrsyslogは、システム内に常駐するデーモンプログラムです。サービス名は、systemd-journald.servicersyslog.serviceです。

# systemctl list-unit-files | grep -E "(systemd-journald|rsyslog)\.service"
rsyslog.service                            enabled  
systemd-journald.service                   static   

journald

journaldの役割

journaldは、各ソースからログを受信し、メモリ上のログデータベース(/run/log/journal/配下)に蓄積します。設定を変更することでログデータベースの永続化もできますが、デフォルト設定ではOSをシャットダウンするとデータが消失するので、後述のrsyslogにログを転送してファイルへログを出力します。

systemdユニットプロセス

systemdのユニットファイル(/var/lib/systemd/配下)から起動するタイプのプロセスは、同プロセスの標準出力と標準エラー出力をjournaldが収集します。systemctlコマンドでサービスを起動したときのログは、ここで収集されます。

カーネル

カーネルのログは、一旦メモリ上のログバッファ(/dev/kmsg)に出力されます。これは、OS起動時journaldやrsyslogが起動する前のカーネルログも保持しておく為です。
journaldは、カーネルのログバッファに蓄積したログを収集します。

一般プロセス

ユーザが起動した一般プロセスにおいて、syslog()ライブラリコールによってログを出力した場合、journaldがログを収集します。シェルスクリプトであれば、loggerコマンドがsyslog出力によく使われます。
一般プロセスが直接ファイル出力したログについては、journaldおよびrsyslogは関与しません。

ログデータベースの閲覧

ログデータベースを直接閲覧するには、journalctlコマンドを使用します。
以下の例では、PostgreSQLサービスを起動した後、ログデータベースの内容を表示しています。systemctlコマンドでは何もメッセージが出力されませんが、ログデータベースの中にはsystemdユニットファイルからPostgreSQLを起動したときの標準出力が記録されています。
サービスの起動に失敗した場合は、ログデータベース内のログに失敗理由が表示されるので調査に利用できます。

# systemctl start postgresql.service
# journalctl -xe
(略)
 7月 19 01:12:56 localhost.localdomain systemd[1]: Starting PostgreSQL database server...
 7月 19 01:12:56 localhost.localdomain postmaster[12605]: 2020-07-19 01:12:56.539 JST [12605] LOG:  starting PostgreSQL 12.1 on x86_64-redhat-linux-gnu, c>
 7月 19 01:12:56 localhost.localdomain postmaster[12605]: 2020-07-19 01:12:56.540 JST [12605] LOG:  listening on IPv6 address "::1", port 5432
 7月 19 01:12:56 localhost.localdomain postmaster[12605]: 2020-07-19 01:12:56.540 JST [12605] LOG:  listening on IPv4 address "127.0.0.1", port 5432
 7月 19 01:12:56 localhost.localdomain postmaster[12605]: 2020-07-19 01:12:56.542 JST [12605] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL>
 7月 19 01:12:56 localhost.localdomain postmaster[12605]: 2020-07-19 01:12:56.588 JST [12605] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
 7月 19 01:12:56 localhost.localdomain postmaster[12605]: 2020-07-19 01:12:56.688 JST [12605] LOG:  redirecting log output to logging collector process
 7月 19 01:12:56 localhost.localdomain postmaster[12605]: 2020-07-19 01:12:56.688 JST [12605] HINT:  Future log output will appear in directory "log".
 7月 19 01:12:56 localhost.localdomain systemd[1]: Started PostgreSQL database server.

なお、journalctl -u postgresql.serviceのように-uオプションで特定のサービスに関するログのみ表示することも可能です。

rsyslog

rsyslogの役割

rsyslogは、journaldのログデータベースに蓄積されたログを読み込みます。そして、ログのファシリティ(種類)とプライオリティ(優先度)に応じて、予め定義されたフォーマットで指定のファイルにログを出力します。
rsyslogの設定ファイル(/etc/rsyslog.conf)を変更することで、外部のsyslogクライアントからsyslogを受信して統合管理したり、外部のsyslogサーバにログを転送することもできます。

ログの出力設定

以下は、rsyslog(8.37.0)のデフォルトのログ出力先設定です。<ファシリティ>.<プライオリティ>の形式で、読み込んだsyslogをどのファイルへ出力するか定義しています。
プライオリティがemergのsyslogのみ、:omusrmsg:<対象ユーザ>の形で、ビルドインモジュールを使ってログイン中の全ユーザのコンソールにメッセージを出力するよう定義しています。

# grep -vE "(^#|^$)" /etc/rsyslog.conf 
(略)
*.info;mail.none;authpriv.none;cron.none                /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 :omusrmsg:*
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.log

もし、ログ出力にsyslogを使用するソフトウェアをシステムに追加する場合は、rsyslogの設定ファイルに設定行を追加します。
以下の例は、local0のファシリティでsyslogを出力するソフトウェアのログを/var/log/sampleapp.logに保存するよう指定しています。

local0.*                                                /var/log/sampleapp.log

ログの出力確認

デフォルト状態で、設定通りのログがファイル出力されているか確認してみます。

# ls -l /var/log/{messages,secure,maillog,cron,spooler,boot.log}
-rw-------. 1 root root    0  7月 19 04:49 /var/log/boot.log
-rw-------. 1 root root  849  7月 19 06:01 /var/log/cron
-rw-------. 1 root root    0  7月 19 04:49 /var/log/maillog
-rw-------. 1 root root 7541  7月 19 06:20 /var/log/messages
-rw-------. 1 root root    0  7月 19 04:49 /var/log/secure
-rw-------. 1 root root    0  7月 19 04:49 /var/log/spooler

プライオリティがemergのsyslogをわざとローカルのjournaldに送信し、コンソールにメッセージが表示されるか確認してみます。

# logger -p local0.emerg "logging test"
# 
Broadcast message from systemd-journald@localhost.localdomain (Sun 2020-07-19 06:39:57 JST):

root[12984]: logging test

参考文献

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です