rsyslog 5 | ||
---|---|---|
HOME |
RHEL/CentOS 6の標準の rsyslog は 5.8.x。rsyslogのドキュメントでも言われているが甚だ中途半端なバージョンだ。Syslogサーバに仕立てるために調べていたらコツや癖がいろいろと分かってきたので、まとめておくことにした。なお、RHEL/CentOS 6でも rsyslog7 という名称で rsyslog 7.4.x のパッケージも用意されていて、5.8.x からアップグレードすることが可能だ。ちなみに RHEL/CentOS 7 では rsyslog 7.4.x が元来標準となっている。
バージョン7 の検証は別ページにまとめた。
ここでは 514/UDP でのリモートログ受け入れを基本とし、TCPについては補足的に述べるに留める。TCPの方がログ欠落の可能性は低いが、ファイヤーウォールアプライアンスなど、未だにUDPでしかログを送れない機器が多く存在するからだ。
同時オープンファイル上限数やエフェメラルポート範囲の拡大は基本中の基本。以下のファイルに下記の記述が含まれるように編集。
/etc/sysctl.conf
fs.file-max = 6815744 fs.aio-max-nr = 1048576 net.ipv4.ip_local_port_range = 9000 65500
`sysctl -p` で反映。
/etc/security/limits.d/91-nofile.conf
root soft nofile 4096 root hard nofile 65536
/etc/security/limits.d/90-nproc.conf (RHEL/CentOS 6.x では元々こうなっているはず)
* soft nproc 1024 root soft nproc unlimited
ulimit関係の設定変更は次回のrootシェルセッションから反映される。
頭が $ で始まる語句は、変数ではなく rsyslog のディレクティブ。RuleSet を意識した構造とインクルードコンフィグファイルを使うと、きれいで変更もしやすい設定ができる。
$ModLoad imuxsock $ModLoad imklog $ModLoad imudp <- UDPインプットモジュールのロード #$ModLoad imtcp #$ModLoad imptcp <- TCPをリスニングする場合はこちらをロード(TLS機能なし版) #### GLOBAL DIRECTIVES #### $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $IncludeConfig /etc/rsyslog.d/*.conf #### RULES #### <- ここは暗黙のデフォルトRuleSet "RSYSLOG_DefaultRuleset" のコンテキスト #kern.* /dev/console *.info;mail.none;authpriv.none;cron.none /var/log/messages # <-- 通常のローカルログフィルタ記述が続く。略 --> # A template to for higher precision timestamps + severity logging $template SpiceTmpl,"%TIMESTAMP%.%TIMESTAMP:::date-subseconds% %syslogtag% %syslogseverity-text%:%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" :programname, startswith, "spice-vdagent" /var/log/spice-vdagent.log;SpiceTmpl #### Remote server log RuleSet ### <- ここからがUDPリモートロギングの設定 $Ruleset RemoteUDP <- UDPリモートロギング用RuleSetへのコンテキスト切り替え。まだ存在しないのでここで生成される $RulesetCreateMainQueue on <- パフォーマンスと信頼性向上のためルールセット専用のインプットキューを設ける $InputUDPServerBindRuleset RemoteUDP <- UDPインプットリスナーをルールセットに結びつける #$UDPServerAddress 192.168.1.25 <- リッスンするネットワークIFを限定することも可能 $UDPServerRun 514 <- ここでUDPのリッスンを有効化。UDP用は"Input"が付かないことに注意 #$UDPServerRun 10514 <- 複数のUDPポートでリッスンしたい場合は複数回唱えればよい $IncludeConfig /etc/rsyslog.d/remote-udp.conf_r <- フィルタはインクルードコンフィグファイルに書く。ローカルとは別の拡張子にするとよい #### Remote server log RuleSet for TCP ### #$Ruleset RemoteTCP <- TCPリモートロギングRuleSetのコンテキスト(使うなら) #$InputPTCPServerBindRuleset RemoteTCP <- 平文専用TCPモジュール用なので"P"が入る。下も同様 #$InputPTCPServerRun 514 #$IncludeConfig /etc/rsyslog.d/remote-tcp.conf_r
$UDPServerAddress を使うと、リッスンするネットワークインターフェイスを限定することができる。普通は書かないので `$UDPServerAddress *' を指定したのと同じなわけだ。 プレインTCPモジュールの場合も同様の(しかし名前が全く違う)ディレクティブがあり確かに機能するのだが、imptcpモジュールの説明のバグ欄に "module always binds to all interfaces" と書いてあるのはドキュメントのバグか?
リモートログをUDPでなくTCPで待ち受ける場合、通信をTLSで保護するつもりがないのなら、imtcpモジュールより、平文通信に機能を絞った imptcpモジュールを使った方が理屈的に言って処理速度が速いはずだ。自分で測定してみたわけではないが、GitHubに"Receiving massive amounts of messages with high performance"というガイドもある。その他のチューニングポイントは後述の omrulesetモジュールによるルールセットの階層化 を参照いただきたい。
IPアドレス 192.168.1.24 のリモートサーバから送信されてくるログのうち、ntpd のログを /rlog/centos6u/ntpd.log に、Syslogファシリティ AUTHPRIV のログを /rlog/centos6u/secure に記録する例。書き方はいろいろある(ありすぎて困る)が、
$AllowedSender UDP, 192.168.1.24/32 $Template centos6u-perprog,"/rlog/centos6u/%programname%.log" if $fromhost-ip == '192.168.1.24' and $programname startswith 'ntpd' then -?centos6u-perprog if $fromhost-ip == '192.168.1.24' and $syslogfacility-text == 'authpriv' then -/rlog/centos6u/secure if $fromhost-ip == '192.168.1.24' then ~
フィルタはレイナースクリプト (RainerScript) 形式というやつで書いてある。?テンプレート名 やファイル名の前の '-`は、従来の syslogd と同様、遅延書き込みを有効にすることを意味する。最後の行のアクションである `~' は discard つまり破棄。rsyslog のルールセットは、書かれている順番に、基本的にはいつも全フィルタが評価される。ただし、discard の結果通過しているログエントリが消えてしまえば、評価はそこで終わりとなる。それ以上どこにも記録しないログをしっかり discard するように心掛ければ、上記ルール群の下に例えば他のサーバからのログを処理するフィルタ群があった場合でも、もうそこから後へは流れず、間違って他のログファイルへ流れ込んだり無用なリソースを処理に費やしたりせずに済む。
一番上の $AllowedSender は、ソースアドレスによる受け付け制限。誰かが勝手に Syslogサーバへログを送る設定をして、知らぬ間にCPUやディスクを食い潰されてはたまらない。'UDP' のところはもちろん、TCPインプットモジュールなら 'TCP' に置き換えていただきたい。エージェントアドレスは書き方の見本として /32 を付けたが、単一のIPアドレスなら /prefix は書く必要はない。名前解決のできる環境ならホスト名や *.hoge.cxm のようなワイルドカード指定もできる。複数指定したい時は、カンマ区切りで列挙するか、$AllowedSender ステートメントを複数回唱えてもよいとされている。
2行目は rsyslog 独特のテンプレート という機能で、ファイル名やディレクトリ名をプロパティを使って動的に発生させる用途の他、ログフォーマットをカスタマイズしたり、データベースにログを格納する場合の insertクエリを定義したりでき、使い回しができる。テンプレートを使わずに書くと次のようになる。
$AllowedSender UDP, 192.168.1.24/32 if $fromhost-ip == '192.168.1.24' and $programname startswith 'ntpd' then -/rlog/centos6u/ntpd.log if $fromhost-ip == '192.168.1.24' and $syslogfacility-text == 'authpriv' then -/rlog/centos6u/secure :fromhost-ip,isequal,"192.168.1.24" ~
実は、この例ではわざと`$programname == 'ntpd'' と書かずに startswith で評価しているので、前記のテンプレートパターンでは ntpdate のログが来ると ntpdate.log という別のファイルに書かれてしまう。意図によってはこのように固定ファイル名にした方がすっきりするだろう。ごちゃ混ぜにして `... then -/rlog/centos6u/%programname%.log' とは書けない - やってみると、そのものズバリの %programname%.log というログファイルが出来上がってしまった。最後の行は、もうひとつのフィルタ記述形式であるプロパティベース形式を使ってみた - 意味は前の例と全く同じだ。ただし rsyslog のサイトではもうプロパティベース形式を推奨していないということも申し添えておこう。下記は、やらかしがちな間違いだ。
if $fromhost-ip == '192.168.1.24' and $programname startswith 'ntpd' then -/rlog/centos6u/ntpd.log
if $fromhost-ip == '192.168.1.24' and $syslogfacility-text == 'authpriv' then -/rlog/centos6u/secure
& ~
`&' は「直前の条件と同じものを」を表す短縮形。単一条件ならこれでよいが、すぐ上の条件は and による複数条件指定なので、ファシリティ=authpriv 以外の 192.168.1.24 からのログ(ntpdのものも含む) はこれより下にも流れてしまう。とはいえ、ルールセットを使ってローカルログとUDPリモートログ(と使うならTCPログ) を隔離しているので、UDPルールセットのログが他のルールセットに処理されるおそれはない。
レイナースクリプトが一応の完成を見た rsyslog バージョン7 以降なら `if ... then { if ... then ... }' という風に波括弧を使って評価文がネストできるようになったためもう少し論理的にルールが組み立てられるのだが、5.8 では仕方がない。
その代用というにはちょっと仕掛けが大袈裟すぎる気もするが、omruleset というモジュールがある。これを使うとルールセットを階層化することができる。iptables のユーザ定義チェーンのように、ルールセットからルールセットへと処理を飛ばすことができるのだ。面白いのでその例も示しておこう。
$ModLoad imuxsock $ModLoad imklog $ModLoad omruleset $ModLoad imudp #$ModLoad imptcp #### GLOBAL DIRECTIVES #### $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $IncludeConfig /etc/rsyslog.d/*.conf # <-- 中略 --> :programname, startswith, "spice-vdagent" /var/log/spice-vdagent.log;SpiceTmpl #### RuleSet for a specific server ### $Ruleset Centos6uRuleSet <- 2段目のRuleSetを先に作っておく $RulesetCreateMainQueue on <- RuleSet専用のインプットキューを設ける $IncludeConfig /etc/rsyslog.d/centos6u.conf_o <- フィルタはインクルードコンフィグファイルに書く #### Remote server log RuleSet ### $Ruleset RemoteUDP $RulesetCreateMainQueue on $InputUDPServerBindRuleset RemoteUDP $UDPServerRun 514 $IncludeConfig /etc/rsyslog.d/remote-udp.conf_r
$AllowedSender UDP, 192.168.1.24 $ActionOmrulesetRulesetName Centos6uRuleSet <- omrulesetモジュールのジャンプ先RuleSetをセットする if $fromhost-ip == '192.168.1.24' then :omruleset: <- ここでCentos6uRuleSetつまりcentos6u.conf_oの内容へ処理が飛ばされる & -/rlog/centos6u/messages <- Centos6uRuleSetでdiscardされなかったエントリはここへ帰ってくる & ~
if $programname startswith 'ntpd' then -/rlog/centos6u/ntpd.log & ~ if $syslogfacility-text == 'authpriv' then -/rlog/centos6u/secure & ~
remote-udp.conf_r で全破棄の手前で振り向けている centos6u/messages ログファイルには、ntpdやauthprivファシリティを除いた残りのログが記録されることになる。ちょっとだけ構造が複雑になるが、その分、ログエントリの通過する評価処理は軽くなり、`& ~' も心おきなくバンバン使える。リモートサーバ毎にキューが分けられるのも利点だ。複雑な振り分けをしたくなった時のために、頭の隅においておくといい技かもしれない。
これをもう一歩推し進めると、第二階層の汎用化というところに行き着く。
$ModLoad imuxsock $ModLoad imklog $ModLoad omruleset $ModLoad imudp #$ModLoad imptcp #### GLOBAL DIRECTIVES #### #$MaxOpenFiles 65535 #$OMFileAsyncWriting on #$OMFileFlushOnTXEnd off #$OMFileIOBufferSize 64k # <-- 中略 --> :programname, startswith, "spice-vdagent" /var/log/spice-vdagent.log;SpiceTmpl #### Per-server 2nd stage RuleSet ### $Template PerServerNtpLogfileTpl,"/rlog/%hostname%/ntpd.log" $Template PerServerAuthLogfileTpl,"/rlog/%hostname%/secure" $Template PerServerMainLogfileTpl,"/rlog/%hostname%/messages" $Ruleset PerServer2ndStage #$MainMsgQueueSize 250000 #$MainMsgQueueDequeueBatchSize 4096 #$MainMsgQueueWorkerThreads 4 #$MainMsgQueueWorkerThreadMinimumMessages 60000 #$MainMsgQueueType FixedArray $RulesetCreateMainQueue on $IncludeConfig /etc/rsyslog.d/perserver2nd.conf_o #### Remote server log RuleSet ### $Ruleset RemoteUDP #$MainMsgQueueSize 10000 #$MainMsgQueueDequeueBatchSize 16 #$MainMsgQueueWorkerThreads 1 $RulesetCreateMainQueue on $InputUDPServerBindRuleset RemoteUDP $UDPServerRun 514 $IncludeConfig /etc/rsyslog.d/remote-udp.conf_r
$AllowedSender UDP, 192.168.1.24, 192.168.1.23 $ActionOmrulesetRulesetName PerServer2ndStage if $fromhost-ip == '192.168.1.24' then :omruleset: & ~ if $fromhost-ip == '192.168.1.23' then :omruleset: <- 別のエージェントも簡単に追加できる & ~
if $programname startswith 'ntpd' then -?PerServerNtpLogfileTpl & ~ if $syslogfacility-text == 'authpriv' then -?PerServerAuthLogfileTpl & ~ *.* -?PerServerMainLogfileTpl
テンプレートの働きと相まって (192.168.1.24のサーバ名が centos6u、.23がcentos6u2 だったとすると)、
/rlog/ \_ centos6u/ \_ ntpd.log secure messages \_ centos6u2/ \_ ntpd.log secure messages
という構造がオートマチックにできてしまうのだ。サーバ名は大文字にしたい? はいはい、テンプレート定義の "/rlog/%hostname%/ntpd.log" を "/rlog/%hostname:::uppercase%/ntpd.log" に変えてください。rsyslogのプロパティ置換機能 (PropertyReplacer) というやつだ。なぜコロンが3つも並んでいるかというと、リプレーサーの書式は
%PropName:[StartPos]:[EndPos][:Option]%
となっているから。ホスト名が centos6u2 なら、%hostname:1:7% は "centos6"、%hostname:5:$% は "os6u2" といった具合。他にも様々な変換ができるようなので興味があれば覗いてみてはいかがだろうか。
ただ、この 2ndステージの汎用化構造だと、どのエージェント発のログも、終着地であるディスクに書く手前で結局 PerServer2ndStage ルールセットに集中してしまい、エージェント毎にキューを別々にできるというメリットは犠牲になる。そこで、ここでもまた"Receiving massive amounts of messages with high performance"を参考にして、主設定ファイルにインプットキューのチューニングを入れてみた。"Understanding rsyslog Queues"も参考になる。ただし、例はただの受け売りであって、(今のところ)値を詳細に評価したわけではないのでコメントアウトしてある。UPSや予備電源を備えていない環境の場合はリスクもある。$Ruleset 宣言の中で $RulesetCreateMainQueue の手前で $MainMsgQueue* を唱えると、そのルールセット固有のインプットキューパラメータをカスタマイズすることができるのだが、デバグしてみると、変更したパラメータはそれ以降に作成するルールセットキュー全部に反映されてしまうので、RemoteUDP ルールセットセクションに示したように、デフォルトのキュー設定で作りたい最初のルールセットで元の値を宣言しなおしてやる必要がある。
以下は、グローバルディレクティブセクションに書いたステートメント。$OMFile* パラメータは、rsyslog 7以降だとルールセット毎に設定できるようだが、5.8 ではグローバルに設定するしかなさそう。omfile とは、否応なしにロードされる、ローカルファイルシステム(NFSマウントも含む)へのアウトプットモジュールのこと。
キューやバッファ絡みの他にも、チューニングの要素はある。きわめてリモートログ取扱量の多いSyslogサーバなら、検討する価値がある。
自分の書いたコンフィグが意図通りに解釈されているか確かめるには、rsyslogd をデバグモードで起動してみる。
root# service rsyslog stop root# RSYSLOG_DEBUG=DEBUG RSYSLOG_DEBUGLOG=/var/tmp/rsyslog-debug.log /sbin/rsyslogd -c5 <ctl-c>
ログは標準出力にも出力されるので RSYSLOG_DEBUGLOG変数は指定しなくてもいいが、指定すればファイルにも記録されるので調査がしやすい。RHEL/CentOS だと、普段 SysVinit から起動する時には /etc/sysconfig/rsyslog の SYSLOGD_OPTIONS に入れてあるコマンドラインオプションが拾われて付加されるので、正確を期すならデバグの時にも指定した方がよい(上記の例での -c5)。
比較演算子 | 説明 |
== | 等しい。文字列でも数値でも有効。プロパティベース形式にある isequal は使えないことに注意 |
!=, <> | 等しくない。文字列でも数値でも有効 |
< | より小さい |
> | より大きい |
<= | 以下 |
>= | 以上 |
contains | 含む。文字列でのみ使える |
contains_i | 同上、大文字小文字を区別しない |
startswith | ~で始まる。文字列でのみ |
startswith_i | 同上、大文字小文字を区別しない |
評価を反転する not も使える。ただし "not $A == 'B'" は (not $A) == 'B' と評価されてしまうため "not ($A == 'B')" と書かなければならず、だったら単純に "$A != 'B'" と書いた方がマシ、と注意書きあり。contains などと組み合わせる場合は "if not ($A contains 'B')" と書くべきと思われる。
Syslogもひとつのプロトコルである。好き勝手な文字や数字の羅列が送られてくるわけではないし、我々が普段ログファイルで見るままのカタチで送られてくるわけでもない。例えば、ファシリティとシビアリティは然るべき計算をもって1~3桁の数字にまとめて '<' と '>' で挟んで送れ(このフィールドを PRI [プライオリティ] と呼ぶ)とか、そういった種々のフィールドを何をデリミタにしてどういう順番で並べろという規格が決まっている。RFC5424 (RFC3164を置き換え) が Syslogプロトコルの基本定義。RFC5426 が Syslog over UDPの仕様。さらに RFC5425 で TLS による暗号化送受信の規格が定義されている。新しい方のSyslogプロトコルでは、UDPによるトランスポートが別文書になっていることからもうかがえるように、意外なことに、ネットワークによるSyslog送信はTCPが基本となっている。
RFC5424を書いたのは、何を隠そう、rsyslog 開発の中心人物 レイナー・ゲルハルト氏その人である。ゲルハルト氏はドイツのシステムコンサルタント/ソフトウェア会社 Adiscon の代表でもある。
とはいえ、現在も、そして今後もかなり長らく、実世界では、RFC5424フォーマットとRFC3164フォーマットのメッセージが入り乱れて使用されていくだろう。そこで rsyslog は、複数のパーサーモジュールで順繰りにメッセージを評価して、RFC5424形式のメッセージなのかRFC3164のメッセージなのかを判定してフィールドをプロパティに割り当てる。デフォルトでは、先に評価するのは pmrfc5424 パーサーモジュールで、それが失敗すると pmrfc3164 でパースが行われる。RFC3164は5424よりずっと規則が緩いので、先に pmrfc3164 で評価するとどのメッセージもRFC3164フォーマットと判定されてしまうからだという。
rsyslog のコンフィグで使えるプロパティは、Syslogメッセージから取り出したそういったフィールドが主だが、それ以外から取得するものもある。
プロパティ名 | 説明 |
msg | SyslogメッセージのMSGフィールド。RFC3164フォーマットではMSGフィールドはTAG部(プログラム名等)とCONTENT部から成り、このプロパティはCONTENT部のみを指す。RFC5424ではMSGフィールド全体 |
rawmsg | 同じくMSGフィールドだが、フィールドに格納されたそのままの形。RFC3164フォーマットのメッセージではTAG部も含んでいるようだ |
hostname | SyslogメッセージのHOSTNAMEフィールド |
source | 上記 hostname のエイリアス |
fromhost | Syslogパケットの送信元アドレスをDNSリゾルブしたもの。リゾルブ不能な場合はIPアドレスのまま。ログがリレーされている場合、これはログの発生元ではなく直前のSyslogリレーサーバとなることに注意 |
fromhost-ip | Syslogパケットの送信元IPアドレス。リゾルブなし |
syslogtag | SyslogメッセージのTAG部。TAGはまたプログラム名+PID/MSGIDから成る。例: named[12345] |
programname | TAGのプログラム名のみ |
pri | SyslogメッセージのPRIフィールド。(ファシリティ x 8 + シビアリティ) の計算による1~3桁の数字の状態 |
pri-text | PRIにそこから解釈したを文字列を付けたもの。例:local0.err<133> |
iut | MonitorWare InfoUnitType よく分からん |
syslogfacility | PRIをデコードした結果得られたファシリティの数字表記。つまり 0~23 のいずれか |
syslogfacility-text | 上記の文字表記。kern, mail, authpriv, local0 など |
syslogseverity | PRIをデコードした結果のシビアリティ数字表記。つまり 0~7 のいずれか |
syslogseverity-text | 上記の文字表記。emerg, warning, notice, info など |
syslogpriority | 上記 syslogseverity のエイリアス。下位互換のために残っているだけで、前者を使うべき。PRIそのものではないことに注意 |
syslogpriority-text | 上記 syslogsevierity-text のエイリアス。下位互換のために残っているだけで、なるべく前者を使うべき |
timegenerated | Syslogメッセージ受信時のタイムスタンプ |
timereported | SyslogメッセージのTIMESTAMPフィールド |
timestamp | 上記 timereported のエイリアス |
protocol-version | SyslogメッセージのPROTOCOL-VERSIONフィールド |
structured-data | SyslogメッセージのSTRUCTURED-DATAフィールド |
app-name | SyslogメッセージのAPP-NAMEフィールド |
procid | SyslogメッセージのPROCIDフィールド |
msgid | SyslogメッセージのMSGIDフィールド |
inputname | メッセージを生成したインプットモジュールの名前。imuxsock, imudp など。rsyslogd自体の出したログを他と区別するために考案されたものらしい |
Syslogメッセージの属性とは直接関係のないその他のプロパティ。頭の $ もプロパティ名の一部であり、例えばテンプレートでなら %$myhostname% といった具合に使う。
プロパティ名 | 説明 |
$bom | UTF-8でエンコードされたUnicodeのBOM(byte-order mask) |
$now | 現在の YYYY-MM-DD |
$year | YYYY |
$month | MM |
$day | DD |
$hour | 現在の HH (24時間表記) |
$hhour | 1時間のうちの前半後半。今が x時00分~29分なら 0、30~59分なら 1 |
$qhour | こちらはクォーター時間。上記同様に 0, 1, 2, 3 のいずれかとなる |
$minute | 現在の mm |
$myhostname | 自ホスト名。ドメイン部なしになる可能性が高い |
$ModLoad imuxsock $ModLoad imklog #### GLOBAL DIRECTIVES #### $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $IncludeConfig /etc/rsyslog.d/*.conf #### RULES #### #kern.* /dev/console *.info;mail.none;authpriv.none;cron.none /var/log/messages # <-- 通常のローカルログフィルタ記述が続く。略 --> # ### begin forwarding rule ### $WorkDirectory /var/lib/rsyslog #<- ディスクキューとして使うディレクトリ $ActionQueueFileName fwdRule1 #<- キューチャンクファイルの接頭句。実際のファイルはfwdRule1.0000001といった名前で作られる $ActionQueueMaxDiskSpace 200m #<- 補助キュー用ディスクスペースの容量制限。本番サーバなら数g などできるだけ大きい方がよい $ActionQueueSaveOnShutdown on #<- キューWorkerの終了時にまだメモリ上に処理残のキューがあればディスクキューに保存する #$ActionQueueHighWaterMark 8000 #<- 補足説明参照 #$ActionQueueLowWaterMark 2000 #<- 補足説明参照 $ActionQueueType LinkedList #<- LinkedLisタイプのtメモリキューを作成 #$ActionResumeInterval 60 #<- リトライ間隔の初期値(秒) $ActionResumeRetryCount 60 #<- リトライ回数。ローカルにも書かれるので、Syslogサーバが長らくアクセス不能な時はあきらめる。デフォルト見本は -1(無制限) *.* @192.168.1.25:514 #<- 全ログをSyslogサーバへUDP送信する #*.* @@192.168.1.25:514 #<- TCPの場合は@を2つにする #if $programname startswith 'ntpd' then @192.168.1.25:514 #<- ntpdとntpdateのログだけ送るならこんな感じ # ### end of the forwarding rule ### # A template to for higher precision timestamps + severity logging $template SpiceTmpl,"%TIMESTAMP%.%TIMESTAMP:::date-subseconds% %syslogtag% %syslogseverity-text%:%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" :programname, startswith, "spice-vdagent" /var/log/spice-vdagent.log;SpiceTmpl
核心の`*.* @192.168.1.25:514' については特に説明は要らないだろう。
その上の送信キューについて少し補足しておく。rsyslogオフィシャルドキュメントの他に、RHEL7 のドキュメントが参考になる。送信先のSyslogサーバがオフラインになると、送信すべきログは出力キューにバッファされる。RHEL/CentOS 6 でインストールされるサンプルコンフィグ(上記もそれを元にしている) に書いてある送信キューは、ディスク補助付きInメモリキュー(Disk-Assisted In-memory Queue) と呼ばれるタイプ。メインキューはメモリで、それが閾値に達した場合だけ補助キュー(=ディスクキュー) にバッファされ始める。閾値とはメモリ上のログメッセージの数が $ActionQueueHighWaterMark に達した時で、それが $ActionQueueLowWaterMark 値に下がるまで補助キューへ吐き出される。上でコメントとして書き添えた値は暗黙のデフォルト閾値だ。
では、キューが一杯になったらどうなるのか。rsyslogd は送信リトライ10回毎に $ActionResumeInterval (秒)を延ばしながら、最大 $ActionResumeRetryCount 回まで送信先の復帰を待つ。そしていよいよメモリキューがいっぱいになると、rsyslogd はまずログの受け入れ速度を落とし(スロットル)、ログのシビアリティなどに基づいて古いエントリを捨てつつ、どんどん補助キューへエントリを吐き出す。しかし、いつまでも logソケットなどをスロットルし続ければシステムのストールにつながりかねない。メモリキューも補助キューも満杯のまま状況が改善せず $ActionQueueTimeoutEnqueue ミリ秒 (デフォルト 2000) 経過すると、遂に最後の手段として、新着のログを破棄し始める。