rsyslogで信頼性のあるログ転送について調べたメモ

事の発端は fluentd を使ってみようかと思って fluentd(td-agent)のインストールと設定 を読んだことで す。fluentd のデメリットのところを読んで、ちょっと気になりました。

Goで書かれたmoriyoshi/ikも気になったのですが、最近話聞かないし最終コミットも3ヶ月前だったので、今回は見送りました。

そこで、rsyslogでのログ転送について調査してみようと思いました。

rsyslog自体についてはこちらのスライド#logstudy 01 rsyslog入門が分かりやすかったです。

syslog形式での出力サポート

nginx

Apache HTTP server

Apache Traffic Server

Cのsyslog出力関数

Goのsyslogクライアントライブラリ

loggerコマンド (シェルスクリプトから出力したい時に使用)

信頼性のあるログ転送のためのRELPプロトコル

UDPで転送するとパケットロスしてログが消失する恐れがあります。

#logstudy 01 rsyslog入門81枚目のスライドによると、TCPで転送しておけば、転送先のsyslogサーバがダウンしたら、キューイングして、復活したら再送するそうです。

これで十分そうな気もしたのですが、syslog forwardでググっていると[SOLVED] Rsyslog forward log to other syslog serverというページからリンクされているRainer's Blog: On the (un)reliability of plain tcp syslog...という記事を見つけました。

さらにそこからリンクされているRainer's Blog: why you can't build a reliable TCP protocol without app-level acks...という記事も読んでみました。

一言で言うと、信頼性の有るログ転送を実現するためには、TCPレベルでACKがあってもだめで、アプリケーションレベルのACKが必要ということです。

アプリケーションレベルのACKが無いと、サーバのバッファスペースが溢れてもクライアントが気づけないというのが問題の本質のようです。

これを解決するために作られたのが、Rainer's Blog: RELP - the reliable event logging protocolです。

librelp - a reliable logging libraryというのがCの実装で、ソースを見るとライセンスはGPLv3でした。

RELPはrsyslogdにすでに取り込まれていました。

ただし、imrelpの Ruleset パラメータはrsyslogdのバージョン7.5.0以降が必要らしいです。CentOS 7のrsyslogdは yum info rsyslogd によると 7.4.7 なのでこれは使えないようです。

CentOS 7では rsyslog-relp.x86_64 : RELP protocol support for rsyslog というパッケージをインストールすればRELPが使えるようです (まだ試してないです)。

参考: goで書かれたrsyslogサーバ

mcuadros/go-syslogというgoで書かれたrsyslogサーバも見つけました。

UDP、TCP、Unixソケットでの受信が出来るそうです。READMEに"using RFC3164, RFC6587 or RFC5424"とありますが、どこまで対応しているかは未調査です。

RELPは非対応のようです。ソースコードで大文字小文字無視でrelpで検索してヒットしなかったので。

軽く試してみた結果をgistに貼りました。 https://gist.github.com/hnakamur/75385e5572262b5ce9f6