こんにちは。サイオステクノロジー OSS サポート担当 山本 です。
今回は systemd + rsyslog な環境でどうしてもシステムパフォーマンスを優先させたい場合にもしかしたら役に立つかもしれない、journald のログを記録させずに rsyslog のログだけを記録させる方法を見てみようと思います。
■おさらい:journald、rsyslog って?
いずれもログに関するものです。
一部の Linux ディストリビューション (Red Hat Enterprise Linux、Debian など) では、いずれもシステム上のログ管理のためにデフォルトでインストールされています。
journald は、システム管理ソフトウェア systemd のコンポーネントの一つで、システム全体のロギングを担うものです。
これのログはデフォルトでは一時ディレクトリ /run/ 配下の /run/log/journal/ 配下に保存されます。
rsyslog はログに関する様々な処理を行うことのできるソフトウェアです。これは様々なものからログを受け取り、書式を整えるなどの加工をし、また様々なものにログを出力することができます。
journald とともにデフォルトで導入される場合は、主に journald のログ を読み込んで /var/log/ 配下の /var/log/messages などのファイルにログを記録する役割を持ちます。
■二重に保存されるログ
さて、先述したとおり、また過去の systemd-journald & rsyslog の記事でも何度かお話ししましたが、
systemd-journald + rsyslog でロギング環境を構築しているシステムでは、デフォルトで
・journald によって保存される /run/log/journal/ 配下の一時ログファイル
・rsyslog によって保存される /var/log/ 配下のログファイル
の両方を保存しています。
この場合、rsyslog 側で記録されているログの内容は journald の (一時) ログファイルの内容を元にしているため、ほぼ同じ内容のログを二重で保存していることになります。
journald のログは、「時間はこれ」「本文はこれ」「ID はこれ」…といった具合に、複数の決められた要素で一つのログを表現する “構造化” という形式で保存されており、専用のコマンドを使ってログの絞り込みを行なったりできる一方、
rsyslog のログは普通のテキストとして保存されるため比較的軽量であり長期保存に適しています。また rsyslog 自体のログの処理速度は極めて高速であるとされているため、
このデフォルトの二重で同じログを保存する動作はもちろん無駄ということはなく、むしろ特に理由がないならパフォーマンスとログ活用範囲のバランスが取れている方法と考えられます。
しかし、当然ながらこのデフォルトのロギング動作は “journald による一時ファイルへの書き込み” と “rsyslog でのファイル書き込み” の2回のファイル書き込みを行うため、システムパフォーマンスのみの観点で言えば最適とは言えません。
ではログは残したいけれどとにかくシステムパフォーマンスを優先したい、と考えた場合はどうすればいいでしょう?
答えはシンプル、journald か rsyslog のどちらか片方だけでログをファイルに書き込むようにすればよいのです。
journald のみのログを記録させたいのであれば、先述のとおり rsyslog は journald のログファイルを読み取ってその内容をログに記録しているだけなので、単純に rsyslog を停止させてしまえば OK です。
その上で、以前の記事で紹介した journald のログを永続化する設定をすれば、journald のログのみを残すことができるようになります。
(勿論、rsyslog の読み込み元として journald 以外のものを設定していた場合、この方法は使えません。)
今回のお話はその逆、rsyslog でのみログをファイルに記録させる方法についてお話しします。
■rsyslog でのみログファイルを記録する設定
ということで、rsyslog でのみログをファイルに記録したいのですが……繰り返しになりますが journald + rsyslog な環境では rsyslog のログは journald のログを元にしているため、単純に journald を止めるだけではログが記録されなくなってしまいます。
そのため、journald のログファイルを介さずに jouranld と rsyslog がデータをやり取りできるように設定してやる必要があります。
これは journald と rsyslog の双方が syslog ソケットとも呼ばれるソケット (Unix ドメインソケット) を使うように設定してやれば、実現することができます。
その設定方法の例を見ていきます。
■journald 側の設定
journald のほうでは、journald によって収集したログを
・ファイルへの書き込みを停止
・syslog ソケットへ転送
するように設定します。
journald の設定ファイル /etc/systemd/journald.conf を開き、”[Journal]” セクションの中に以下の2つの設定を追加します。
[Journal] Storage=none ForwardToSyslog=yes
この設定変更を反映するにはシステムの再起動が必要になるので、後述の rsyslog の設定変更の後にシステムを再起動します。
■rsyslog 側の設定
rsyslog のほうでは、
・ログの読み込み元として journald を設定している箇所の無効化
・ログの読み込み元として syslog ソケットを使用
するように設定します。
rsyslog の設定ファイル /etc/rsyslog.conf を開き、以下の 2つの変更を行ないます。
①、journald のログファイルを読み込む設定箇所を、行頭に “#” を付けて無効化
#module(load="imjournal" # StateFile="imjournal.state"
②、syslog ソケットからログデータを読み込めるように設定します。
(“SysSock.Name” には、syslog ソケットのパスを設定する必要があります。記事執筆時点の journald は “/run/systemd/journal/syslog” を syslog ソケットとして使用しているはずですが、環境によっては設定すべきパスが異なる可能性もあります。)
module(load="imuxsock" # provides support for local system logging (e.g. via logger command) SysSock.Use="on" SysSock.Name="/run/systemd/journal/syslog")
これらの設定を行なったら、システムを再起動します。
$ sudo reboot
■動作確認してみる
設定と再起動を行なったら、
・journald のログ (jouranlctl コマンドなど) が記録されていない
・rsyslog のログ (/var/log/messages など) が記録されている
ことを確認しましょう。
rsyslog 側のログがその環境で元々出ていたログと同等の内容になっていることが肝要ですが、ここでは logger コマンドと httod サービス起動を実行して、そのログを確認してみます。
[ ~]$ logger test1 [ ~]$ sudo systemctl restart httpd [ ~]$ logger test2 [ ~]$ sudo tail -n5 /var/log/messages Oct 25 16:54:45 localhost user1: test1 Oct 25 16:54:51 localhost systemd[1]: Starting The Apache HTTP Server... Oct 25 16:54:51 localhost systemd[1]: Started The Apache HTTP Server. Oct 25 16:54:51 localhost httpd[1464]: Server configured, listening on: port 80 Oct 25 16:54:57 localhost user1: test2 [ ~]$ [ ~]$ sudo journalctl -o short-full --no-pager --no-hostname -n 5 Wed 2023-10-25 16:50:02 JST systemd[1]: Finished Cleanup udev Database. Wed 2023-10-25 16:50:02 JST systemd[1]: Reached target Switch Root. Wed 2023-10-25 16:50:02 JST systemd[1]: Starting Switch Root... Wed 2023-10-25 16:50:02 JST systemd[1]: Switching root. Wed 2023-10-25 16:50:02 JST systemd-journald[239]: Journal stopped [ ~]$
このように、logger と httpd サービスのログは /var/log/messages にのみ出力されており、journald のログはそれらのログよりも前の時間に “Journal stopped” と記録されて以降更新されていないことが確認できるかと思います。
■最後に
今回は journald + rsyslog なロギング環境で、rsyslog のみにログファイルに記録させる方法についてお話ししました。
本記事の執筆時点では、journald か rsyslog のいずれかのみでログファイルに記録させようと考えた場合、システムパフォーマンスの観点で言うと今回の方法は jouranld のみにログファイルを記録させるよりも優れているとされています。
どのように、どの程度ログを残していくべきかはそれぞれのシステムの要件や用途などによって異なるため一概にこのやり方がいい、というものはありませんが、今回の方法も一応知っておくと役立つ時が来るかもしれません。
関連する他の回:
/var/log/messages を知りたい:journald 編
/var/log/messages を知りたい:rsyslog 編
journald のログを永続化したい
ログ “Suppressed X messages” とログの抑制について (journald)
Short Tips:journald のログ抑制の設定 おまけ
ログ “X messages lost due to rate-limiting” とログの抑制について (rsyslog)
rsyslog のログフォーマットを変更する