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

rsyslog でログを転送するとsyslogtag の一部が無くなる

【環境】
CentOS 6.7
rsyslog-5.8.10

rsyslog のログをリモートのrsyslog へ転送し、転送先でPostgreSQLへ保存したところ、syslogtag の一部が消えて保存された。

転送元のログ(テキストファイル)には、欠落せず正しく記録されている。

SQLで保存されたログを確認すると、以下のような感じ。
syslogtag の列で、数字の一部や閉じ部分( ] )が無い。

Syslog=# SELECT id,syslogtag,message FROM systemevents WHERE syslogtag LIKE '%run-parts%';
   id   |              syslogtag              |             message
--------+-------------------------------------+----------------------------------
     88 | run-parts(/etc/cron.hourly)[1975    |  starting 0anacron
     89 | run-parts(/etc/cron.hourly)[1976    |  finished 0anacron

以下によると、syslog のタグはRFCで32文字を上限としているらしく、rsyslog のテンプレートでそのような制限がかけられているとの事。

Linuxねた帳: rsyslog ログを転送するとTAGがかけてしまう

Sending messages with tags larger than 32 characters


この問題を回避するには、テンプレートを新たに定義して、転送するログに対して適用する。

まず、テンプレートを定義。/etc/rsyslog.conf へ以下を追加する。全て1行で記載。

$template LongTagForwardFormat,"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:64%%msg:::sp-if-no-1st-sp%%msg%"

転送設定の部分を、定義したテンプレートを使うように修正する。
テンプレートの定義より後に記載。

*.*    @@remote.rsyslog;LongTagForwardFormat

設定後はデーモンを再起動して反映。

# /etc/init.d/rsyslog restart


動作確認のため、テンプレートの設定前後に以下を実行。logger コマンドの引数 -t で長いタグを指定。

設定前に実行)
# echo "test before lontag" | logger -p local0.info -t 'longtag-longtag-longtag-longtag-longtag-longtag'
設定後に実行)
# echo "test after lontag"  | logger -p local0.info -t 'longtag-longtag-longtag-longtag-longtag-longtag'

データベースに登録された内容を確認。

Syslog=# SELECT id,syslogtag,message FROM systemevents WHERE syslogtag LIKE '%longtag%' ORDER BY id;
  id  |                    syslogtag                     |                            message
------+--------------------------------------------------+----------------------------------------------------------------
 1111 | longtag-longtag-longtag-longtag-                 |  test before lontag
 1112 | longtag-longtag-longtag-longtag-longtag-longtag: |  test after lontag

syslogtag が途中で切れずに登録されるようになった。
なお、rsyslog-pgsql のデータベースの定義では、syslogtag は varchar(60)になっているので、タグの文字数が60文字を超える場合は、DBの定義を変更する必要がある。

例)
Syslog=# ALTER TABLE systemevents ALTER COLUMN syslogtag TYPE varchar(100);