rsyslogでタブ文字が反映されない
タブ文字だけじゃなくて他のエスケープシーケンスでも同様。今回自分がハマった原因は
- テンプレートの記述形式が古いため、反映されなかった
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
はいわゆる固定の要素で、どのログでも共通する部分、property
がtimereported
やhostname
などを記述する部分に当たる。具体的な記述例や使用可能な主なエスケープシーケンス(ドキュメントに明示的な記載はないが、タブ文字も使えた)、propertyの名前は公式ドキュメントに書いてあるので参考にしてほしい。最後の方にExampleという章で、色々な書き方を紹介してくれている。古い書き方はいい加減やめよう。
EscapeControlCharactersOnReceive
これは、syslogのメッセージに他では表示不可能な可能性のある文字の混入を防ぐため、制御文字(ざっくり言うとエスケープシーケンス)を別の文字に置き換える機能のことである。
RSyslog Documentation - $EscapeControlCharactersOnReceive
例えば、\t
を\011
や#011
なんかに置き換える。これによって、他のシステムとの互換性が担保されるわけだが、そんなことよりエスケープシーケンスの表示を優先したい場合は、これをoffにすれば良い。rsyslogのconfigファイル中に以下のように記述する。
$EscapeControlCharactersOnReceive off
まとめ
rsyslogでエスケープシーケンスを表示するためには
- 古いテンプレート記述方式はやめて、現行のテンプレート記述方式を採用する
- EscapeControlCharactersOnReceiveをoffにする
でした。