出張おはき゛ろく

Twitterで書ききれないことを書こうと思います。

RHEL7/CentOS7でsyslogを全て出力するにはどうするか

RHEL7/CentOS7 では、御存知の通りsystemdが導入されています。この影響でログ関連も大きく構成が変わっています。まぁまずマニュアルの18章を読みましょうね。
第18章 ログファイルの表示と管理

とりあえず、標準構成ではだいたい以下のフローで動くと思っていれば特に問題ないと思います。

  1. 全ての Syslog メッセージはまず journald にキャッチされ、構造化された Journal データとして保持される。
  2. rsyslogd は、imjournal モジュールを利用して journald から必要なログを取得し、/var/log/messages や /var/log/maillog などに出力して永続化する。

ただ、標準設定のままだと困ったことがあって、上記の1と2の両方でログの流量制限が施されています。システムの保護という点ではよいのですが、デフォルトは結構キツめの制限なので、メールログなんかは割りとすぐ上限に達してしまいます。必要に応じて緩和しましょう。

journald の制限

journald の制限は、RateLimitInterval と RateLimitBurst によって決まります。以下、man journald.conf より。

journald.conf

RateLimitInterval=, RateLimitBurst=
Configures the rate limiting that is applied to all messages generated on the system. If, in the time interval defined by RateLimitInterval=, more messages than specified in RateLimitBurst= are logged by a service, all further messages within the interval are dropped until the interval is over. A message about the number of dropped messages is generated. This rate limiting is applied per-service, so that two services which log do not interfere with each other's limits. Defaults to 1000 messages in 30s. The time specification for RateLimitInterval= may be specified in the following units: "s", "min", "h", "ms", "us".
To turn off any kind of rate limiting, set either value to 0.

RateLimitInterval で指定した期間に RateLimitBurst を超える量のメッセージがあると破棄されます。デフォルトでは30秒あたり1,000メッセージ*1に制限されています。破棄されたメッセージの数は Journal には記録されており、 journalctl コマンドで確認することができます。必要なログの量を見積もって、適切な値を設定しましょう。
なお、いずれかの値を0にすると、破棄せず無制限に記録するようになるようです。よくわかんないのであれば無制限にしておけばいいのではないでしょうか。(投げやり)

rsyslogd の制限

rsyslog の制限は、$imjournalRatelimitInterval と $imjournalRatelimitBurst で決まります。以下、RedHatのドキュメントより。

18.6. Rsyslog での構造化ロギング
Journal から Rsyslog にデータをインポートするには、/etc/rsyslog.conf で以下の設定を使用します。

$ModLoad imjournal

$imjournalPersistStateInterval number_of_messages
$imjournalStateFile path
$imjournalRatelimitInterval seconds
$imjournalRatelimitBurst burst_number
$ImjournalIgnorePreviousMessages off/on

(中略)
seconds では、レート制限の間隔を設定します。この間隔内に処理されるメッセージ数は、burst_number で指定して値を超えることはできません。デフォルト設定は、600 秒あたり 20,000 メッセージです。Rsyslog は、この指定された時間枠内で最大バースト後に届いたメッセージを破棄します。

だいたい書いてあるとおりで、考え方は journald と同じです。rsyslog のマニュアルによれば、$imjournalRatelimitInterval を 0 にした場合は無制限になるようです。よくわかんないのであれば無制限にしておけばよいのではないでしょうか。(投げやり)

imjournal: Systemd Journal Input Module — rsyslog v7-stable documentation

ratelimit.interval seconds (default: 600)
Specifies the interval in seconds onto which rate-limiting is to be applied. If more than ratelimit.burst messages are read during that interval, further messages up to the end of the interval are discarded. The number of messages discarded is emitted at the end of the interval (if there were any discards). Setting this to value zero turns off ratelimiting. Note that it is not recommended to turn of ratelimiting, except that you know for sure journal database entries will never be corrupted. Without ratelimiting, a corrupted systemd journal database may cause a kind of denial of service (we are stressing this point as multiple users have reported us such problems with the journal database - - information current as of June 2013).
-ratelimit.burst messages (default: 20000)
Specifies the maximum number of messages that can be emitted within the ratelimit.interval interval. For futher information, see description there.

その他

なんらかの理由でレガシーな syslogd を使う場合は、journald の ForwardToSyslog オプションを使って、journald がキャッチした Syslog メッセージを更に他の syslogd に転送する必要があります。このオプション、7.0/7.1ではデフォルトで有効になっているのですが、7.2で一旦無効化されている*2*3ので、この場合は journald.conf を編集して有効にする必要があります。

ForwardToSyslog=yes

ただし、ForwardToSyslog での転送は失敗することがあります。この場合も Journal には失敗したメッセージ数が記録されます。この辺りになると RedHat のサポート範囲外でもあるので、RHEL7/CentOS7 では、あまりレガシーな syslogd に拘らないほうがいいような気がします。

*1:systemd のバージョンによって異なる可能性がありますので、システムの man journald.conf をご参照ください

*2:システム負荷の懸念から systemd 216 で無効化され、これ以降のパッケージをインストールしている場合は影響を受けます。ただ、その後 219.20 でRHEL向けには再度有効化されたので、将来的にはまた有効になりそうです。

*3:Bug 1285642 – journald.conf - changed default for ForwardToSyslog parameter