読者です 読者をやめる 読者になる 読者になる

rsyslog のメモ

rsyslogd - reliable and extended syslogd

信頼できる拡張された syslogd

Remote syslogd ではない(syslogd 時代からリモートからの受信は可能)

設定ファイル

設定ファイルは /etc/rsyslog.conf ですが、このファイルで下記の通りに記述されているので、

$IncludeConfig /etc/rsyslog.d/*.conf

/etc/rsyslog.d/ の拡張子 .conf のファイルもマージされます。

/dev/log

/dev/log という Unix ドメインソケットに書き込めばログを送ることができます。

echo "<133>$(LANG=C date '+%b %d %H:%M:%S') oreore: XXX" | nc -Uu /dev/log

CentOS 6 の nc だと -u と -U を同時に指定できなかったので、代わりに socat で送れます。

echo "<133>$(LANG=C date '+%b %d %H:%M:%S') oreore: XXX" | socat STDIN UNIX-SENDTO:/dev/log

<133> の部分はファシリティとプライオリティで、次の計算式で求めます。

facility * 8 + severity

例えば、local0.notice だと次のとおりです。

local0(16) * 8 + info(5) =  133

日時の部分を改ざんしても、実際にログを送信した日時が記録されました。

echo "<133>Apr 01 06:12:34 oreore: uso" | nc -Uu /dev/log
sudo tail -1 /var/log/messages
# Apr 14 09:15:48 ore-no-server oreore: uso
LANG=C date '+%b %d %H:%M:%S'
# Apr 14 09:15:48

ただまあ、普通はこんなことせずに logger コマンドを使います。

logger -p local0.notice -t oreore -i message
sudo tail -1 /var/log/messages
# Apr 14 09:15:48 ore-no-server oreore[1234]: message

なお、CentOS 7 だと実は /dev/log は journald がリッスンしていて、rsyslog は journald からログを取得しています。

UDP

デフォでは UDP でリッスンしていないので /etc/rsyslog.conf の下記をコメントインするか、

$ModLoad imudp
$UDPServerRun 514

/etc/rsyslog.d/udp.conf のような名前で下記のファイルを作成する必要があります。

$ModLoad imudp
$UDPServerRun 514

UDP で送る場合は次の形式です。

echo "<133>$(LANG=C date '+%b %d %H:%M:%S') $(hostname -s) oreore: XXX" | nc -u localhost 514

/dev/log とは異なり、日時を改ざんするとその通りにログが記録されます。

echo "<133>Apr 01 06:12:34 ore-no-server oreore: uso" | nc -u localhost 514
sudo tail -1 /var/log/messages
# Apr  1 06:12:34 ore-no-server oreore: uso
LANG=C date '+%b %d %H:%M:%S'
# Apr 14 09:16:19

journald

systemd から起動するサービスが標準入力や標準出力に書き込むと journald を経由して rsyslog にも出力されます。

プロパティベースのフィルター

rsyslog でログファイルを分けたい場合、設定ファイルで昔ながらの次のようなフィルターが使えますが、

# local1 のログを出さない
*.info;mail.none;authpriv.none;cron.none;local1.none    /var/log/messages

# local1 のログは oreore.log に出す
local1.*                                                /var/log/oreore.log

次のような、プロパティベースのフィルターも使用できます。

/etc/rsyslog.d/oreore.conf

:programname, isequal, "oreore" /var/log/oreore.log

この例だと programnameoreore であるログは /var/log/oreore.log に出力されます。

:programname というのは下記のログの oreore の部分です。

Apr 14 09:15:48 hostname oreore[1234]: message

& は、直前のパターンにマッチしたもの、という意味です。また、ログファイル名に ~ を指定するとログは破棄されます。

なので、次のように指定すると、oreore のログは /var/log/oreore.log に書き込まれて破棄されます(/var/log/messages)には書かれない。

:programname, isequal, "oreore" /var/log/oreore.log
& ~

なお、最近の rsyslog だと ~ を使うと警告が表示されるので代わりに stop を使うのが正しいようです。

:programname, isequal, "oreore" /var/log/oreore.log
& stop

なお :programname は CentOS 6 の rsyslog では使えませんでした、代わりに次のようにすると良いでしょう。

:syslogtag, startswith, "oreore" /var/log/oreore.log
& stop

:syslogtag というのは下記のようなログの oreore[1234] の部分です。

Apr 14 09:15:48 hostname oreore[1234]: message

式ベースのフィルター

式ベースのフィルターというものを使えばもっと複雑なこともできます。

if $programname == 'prog1' then {
   action(type="omfile" file="/var/log/prog1.log")
   if $msg contains 'test' then
     action(type="omfile" file="/var/log/prog1test.log")
   else
     action(type="omfile" file="/var/log/prog1notest.log")
}

が、そこまでやることってあるのだろうか・・・

テンプレート

テンプレート機能を使えばログファイルの形式をカスタマイズできます。

次のようにテンプレートを登録します。

$template oretemplate, "%timestamp% %hostname% %syslogtag% <%syslogfacility-text%.%syslogseverity-text%> %msg%\n"

ログファイル名を指定するときにテンプレート名も一緒に指定します。

:programname, isequal, "oreore" /var/log/oreore.log;oretemplate
& stop

すると、ログに次のようにファシリティとプライオリティも記録されるようになります。

Apr 14 09:15:48 hostname oreore[1234]: <local0.notice> message

参考