rsyslog のログフォーマットを変更する

こんにちは。サイオステクノロジー OSS サポート担当 山本 です。

今回は rsyslog のログフォーマットを変更する方法と、どんなフォーマットが存在するのかをお話ししてみます。

■おさらい:rsyslog って?

rsyslog はログに関する様々な処理を行うことができるソフトウェアで、例えば systemd のロギングを担当するコンポーネント systemd-journald (journald) のログを読み取って /var/log/messages に記録する……というようなことなどができます。

一部の Linux ディストリビューションでは、システム全体のロギングに使用するためにデフォルトでインストールされています。

もう少し詳しくは、過去の記事にてお願いします。

参考:/var/log/messages を知りたい:rsyslog 編

■ログのフォーマットを変更する意味と変更方法

さて、まず今回のお題目であるログフォーマットを変更する意味についてですが……
明確にメリットと言えるものはとくにありません

むしろ、考えなしにログフォーマットを変えてしまうと、場合によっては必要な情報が出力されないような設定にしてしまう可能性もなくはありません。
基本的にはそんなことにはならないでしょうが。

しかし、ログは基本的には人が見るもの。
環境や運用方法などに合わせて、必要な情報が見やすいログフォーマットを作成しておくと、何かしらの理由でログを見る際に少し快適になる……こともあるかもしれません。

また、「プログラムの入力として使用する」「syslog として転送する」「データベースに保存する」などのように明確な目的決められたフォーマットが必要である場合などには、それに合わせたログフォーマットを準備する必要があります。

rsyslog のログフォーマットは、”テンプレート” という機能で変更できます。
テンプレートの設定は、rsyslog の設定ファイル rsyslog.conf 内で行います。
実際に設定する箇所は使用するモジュールや用途によってまちまちですが、基本的に rsyslog の出力周りの設定箇所で設定できるもの、と思っておけば大丈夫……のはずです。

例えば “RSYSLOG_FileFormat” というテンプレートを適用する場合、
ログファイルに記録するための出力モジュール “omfile” を使用しているならば、この “omfile” モジュールの読み込み箇所で以下のように設定することができます。

module(load="builtin:omfile" Template="RSYSLOG_FileFormat")

または、以下のような各種出力先の設定箇所で、出力先の後ろに “;” と併せて繋げることでも設定できます。
双方設定していた場合はこちらの設定が優先されます。

*.info;mail.none;authpriv.none;cron.none                /var/log/messages;RSYSLOG_FileFormat

設定変更後、rsyslog を再起動すると変更が適用されます。

$ sudo systemctl restart rsyslog

■確認:デフォルトで用意されているテンプレート

rsyslog には、複数のテンプレートがデフォルトで用意されています。

ここでは Red Hat Enterprise Linux 9 の検証環境で “omfile” モジュールを使って、いくつかのデフォルトテンプレートの出力内容を確認してみます。
それぞれのテンプレートで、以下のようなコマンドでログを出力させた場合の例を掲載していきます。

$ sudo logger -p user.info (テンプレート名)

・RSYSLOG_FileFormat
記事執筆時点での標準的なファイル出力向けフォーマット。

2023-10-05T17:07:48.579056+09:00 localhost root[1470]: RSYSLOG_FileFormat

・RSYSLOG_TraditionalFileFormat
ファイル出力向けフォーマット。日時の部分の形式・精度が異なる以外は、基本的には RSYSLOG_FileFormat とほぼ同じです。

Oct  5 17:08:41 localhost root[1488]: RSYSLOG_TraditionalFileFormat

・RSYSLOG_TraditionalForwardFormat
メッセージ転送向けフォーマット。ファシリティ・プライオリティの情報があったり、一度に読み取られたメッセージ間の改行がなかったりします。

Oct  5 17:10:02 localhost root[1516]: RSYSLOG_TraditionalForwardFormat1Oct  5 17:10:06 localhost root[1519]: RSYSLOG_TraditionalForwardFormat2

・RSYSLOG_SysklogdFileFormat
Sysklogd 互換のフォーマット。

Oct  5 17:11:11 localhost root[1537]: RSYSLOG_SysklogdFileFormat

・RSYSLOG_ForwardFormat
メッセージ転送向けフォーマット。日時部分が高精度な仕様です。

2023-10-05T17:13:27.885552+09:00 localhost root[1556]: RSYSLOG_ForwardFormat12023-10-05T17:13:29.345266+09:00 localhost root[1559]: RSYSLOG_ForwardFormat2

・RSYSLOG_SyslogProtocol23Format
RFC5424 で提唱されている syslog 標準の元となった、draft-ietf-syslog-protocol-23 (RFC3164) に準拠しているフォーマット。

1 2023-10-05T17:14:23.036526+09:00 localhost root 1577 - - RSYSLOG_SyslogProtocol23Format

・RSYSLOG_DebugFormat
デバッグ向けフォーマット。メッセージの詳細情報がログとして見れます。

Debug line with all properties:
FROMHOST: 'localhost', fromhost-ip: '127.0.0.1', HOSTNAME: 'localhost', PRI: 14,
syslogtag 'root[1598]:', programname: 'root', APP-NAME: 'root', PROCID: '1598', MSGID: '-',
TIMESTAMP: 'Oct  5 17:15:29', STRUCTURED-DATA: '-',
msg: 'RSYSLOG_DebugFormat'
escaped msg: 'RSYSLOG_DebugFormat'
inputname: imjournal rawmsg: 'RSYSLOG_DebugFormat'
$!:{ "PRIORITY": "6", "_UID": "0", "_GID": "0", "_CAP_EFFECTIVE": "1ffffffffff", "_BOOT_ID": "fbce3ad9615f45a8ac9993712fc70471", "_MACHINE_ID": "ec2c11400b83ffad7cf987a814357b32", "_HOSTNAME": "localhost", "_RUNTIME_SCOPE": "system", "_TRANSPORT": "syslog", "_AUDIT_LOGINUID": "1000", "_SYSTEMD_OWNER_UID": "1000", "_SYSTEMD_SLICE": "user-1000.slice", "_SYSTEMD_USER_SLICE": "-.slice", "_SELINUX_CONTEXT": "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023", "_AUDIT_SESSION": "1", "_SYSTEMD_CGROUP": "\/user.slice\/user-1000.slice\/session-1.scope", "_SYSTEMD_SESSION": "1", "_SYSTEMD_UNIT": "session-1.scope", "_SYSTEMD_INVOCATION_ID": "3a4d5789be63415bb097619a80873398", "SYSLOG_FACILITY": "1", "SYSLOG_IDENTIFIER": "root", "_COMM": "logger", "SYSLOG_TIMESTAMP": "Oct  5 17:15:29 ", "MESSAGE": "RSYSLOG_DebugFormat", "_PID": "1598", "_SOURCE_REALTIME_TIMESTAMP": "1696493729391167" }
$.:
$/:

■テンプレートを自作する

先述のとおり、rsyslog には通常の使用方法であれば大体カバーできるであろう様々なテンプレートがデフォルトで提供されていますが、テンプレート機能では独自のテンプレートを作ることもできます。

独自のテンプレートを作る場合、rsyslog.conf 内で “template()” を使って設定していきます。
template() の基本的な書式は、主に以下の 2種類です。

●List 形式

元のメッセージから特定の要素を取り出す “property()” と、固定文字列 “constant()” を複数組み合わせてテンプレートを定義する方式。

例えば、先述のデフォルトテンプレート “RSYSLOG_FileFormat” はこの形式で書かれており、その内容は以下のようになっています。

template(name="RSYSLOG_FileFormat" type="list") {
     property(name="timereported" dateFormat="rfc3339")
     constant(value=" ")
     property(name="hostname")
     constant(value=" ")
     property(name="syslogtag")
     property(name="msg" spifno1stsp="on")
     property(name="msg" droplastlf="on")
     constant(value="\n")
}

設定自体は長くなりがちですが、設定から内容を読み取りやすい形式と言えます。
“property()” で取得できる内容については、以下のドキュメントを参照してください。

参考:rsyslog Properties

●String 形式

内部パーサによって元のメッセージの特定の要素に置き換えられる “%” で挟まれたプロパティを使いながら、一つの文字列でテンプレートを定義する旧型の形式。

例えば、先述のデフォルトテンプレート “RSYSLOG_TraditionalFileFormat” はこの形式で書かれており、その内容は以下のようになっています。

template(name="RSYSLOG_TraditionalFileFormat" type="string"
     string="%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n")

内部パーサで変換されるプロパティについては、以下のドキュメントを参照してください。

参考:The Property Replacer

●やってみる

一例として、rsyslog での日時の出力フォーマットを確認するだけのテンプレートを作成してログを出してみます。

まず、以下のような設定を rsyslog.conf に追加します。
なお、このテンプレートは日付以外何も出力しないテンプレートなので検証環境以外では使用しないでください。

template(name="TestDate" type="list") {
     constant(value="Default: ")
     property(name="timereported")
     constant(value="\nmysql: ")
     property(name="timereported" dateFormat="mysql")
     constant(value="\nrfc3164: ")
     property(name="timereported" dateFormat="rfc3164")
     constant(value="\nrfc3164-buggyday: ")
     property(name="timereported" dateFormat="rfc3164-buggyday")
     constant(value="\nrfc3339: ")
     property(name="timereported" dateFormat="rfc3339")
     constant(value="\nunixtimestamp: ")
     property(name="timereported" dateFormat="unixtimestamp")
     constant(value="\nTest: ")
     property(name="timereported" dateFormat="year")
     constant(value="/")
     property(name="timereported" dateFormat="month")
     constant(value="/")
     property(name="timereported" dateFormat="day")
     constant(value=" ")
     property(name="timereported" dateFormat="wdayname")
     constant(value=" ")
     property(name="timereported" dateFormat="hour")
     constant(value=":")
     property(name="timereported" dateFormat="minute")
     constant(value=":")
     property(name="timereported" dateFormat="second")
     constant(value="\n\n")
}

*.*        /var/log/test.log;TestDate

設定変更後、rsyslog を再起動します。

$ sudo systemctl restart rsyslog

その後、このテンプレートで出力するように設定した “/var/log/test.log” を確認して、意図したとおりのログフォーマットになっているかを確認します。

Default: Oct  5 17:20:35
mysql: 20231005172035
rfc3164: Oct  5 17:20:35
rfc3164-buggyday: Oct  5 17:20:35
rfc3339: 2023-10-05T17:20:35.395633+09:00
unixtimestamp: 1696494035
Test: 2023/10/05 Thu 17:20:35

■最後に

今回は rsyslog のログフォーマットを変更する、テンプレート機能についてお話ししました。

明確な目的がない限りは基本的には好みの範疇の機能ですが、場合によっては利便性を向上させることができる……かもしれないものなので、「そういう機能がある」ということだけ覚えておいて損はないはずです。
尤も、特に外部サポートなどに頼る可能性がある場合には、独自にカスタムしたテンプレートのログだけだと不都合が生じる可能性も考えられます。もしも独自のテンプレートを使う場合は、デフォルトのテンプレートでのログも別途出力・記録しておくことも合わせて検討するようにしてください。

関連する他の回:
/var/log/messages を知りたい:journald 編
/var/log/messages を知りたい:rsyslog 編
journald のログを永続化したい
ログ “Suppressed X messages” とログの抑制について (journald)
Short Tips:journald のログ抑制の設定 おまけ
ログ “X messages lost due to rate-limiting” とログの抑制について (rsyslog)
journald をログファイルに記録させずに rsyslog のログファイルに記録する

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です