ゼッタノート

ゼッタが勉強したことをまとめたノート代わりのブログ。たまに日記になるかも。

rsyslogでタブ文字が反映されない

タブ文字だけじゃなくて他のエスケープシーケンスでも同様。今回自分がハマった原因は

  1. テンプレートの記述形式が古いため、反映されなかった
  2. EscapeControlCharactersOnReceiveがOnになっているため、メッセージ部分で#011みたいに8進数になっていた

でした。以下、詳細。

テンプレート記述形式とエスケープシーケンス

rsyslogのテンプレート記述形式をググると、次のような書き方がよくヒットする。 $template templateName, "%timereported% %hostname% %msg%\n"

この書き方はいわゆるLEGACY statementと呼ばれるやつで、古い書き方である。エスケープシーケンスについて、ORACLEのman pagesに次のような記述がある。

The backslash is an escape character. For example, \7 rings the bell (this is an ASCII value), \n is a new line. The set in rsyslog is a bit restricted currently.

ORACLE man pages section 5: File Formats rsyslog.conf (5)

「rsyslogで使えるエスケープシーケンスの種類には制限がある」と書かれている。具体的にどこまで対応しているのかは分からないが、確かに\nはしっかり改行されるが、\tと記述しても、出力されるのはバックスラッシュのみがエスケープされたtの1文字だけである。また、後述するが、現代的なテンプレートの書き方で対応している\xhhという、文字コードを16進数で記述するやり方も、LEGACY statementでは反映されない。

所望のエスケープシーケンスを反映するためには、公式ドキュメントに書かれている現代的なテンプレートの書き方をすれば良い。

RSyslog Documentation - Templates

書き方は4つあるようだが、公式が推しているのはList形式のようだ。私はList形式でタブ文字の反映を確認した。一応簡単に書き方を書いておくと、

template(name="テンプレート名", type="テンプレート定義の記述方式、今回はlist")

という形で宣言を開始し、中括弧の中に、具体的なテンプレートを記述していく。constantはいわゆる固定の要素で、どのログでも共通する部分、propertytimereportedhostnameなどを記述する部分に当たる。具体的な記述例や使用可能な主なエスケープシーケンス(ドキュメントに明示的な記載はないが、タブ文字も使えた)、propertyの名前は公式ドキュメントに書いてあるので参考にしてほしい。最後の方にExampleという章で、色々な書き方を紹介してくれている。古い書き方はいい加減やめよう。

EscapeControlCharactersOnReceive

これは、syslogのメッセージに他では表示不可能な可能性のある文字の混入を防ぐため、制御文字(ざっくり言うとエスケープシーケンス)を別の文字に置き換える機能のことである。

RSyslog Documentation - $EscapeControlCharactersOnReceive

例えば、\t\011#011なんかに置き換える。これによって、他のシステムとの互換性が担保されるわけだが、そんなことよりエスケープシーケンスの表示を優先したい場合は、これをoffにすれば良い。rsyslogのconfigファイル中に以下のように記述する。

$EscapeControlCharactersOnReceive off

まとめ

rsyslogでエスケープシーケンスを表示するためには

  1. 古いテンプレート記述方式はやめて、現行のテンプレート記述方式を採用する
  2. EscapeControlCharactersOnReceiveをoffにする

でした。