docker コンテナ内で動作している python アプリのログをホストの syslog に追加します。
Ubuntu 20.04 で作業しましたが、rsyslog は最初からインストールされていました。
概要
Python 標準の logging モジュールに syslog 出力用のハンドラ SysLogHandler
があるので、アプリ側ではそれを指定するだけで OK です。
Syslog はホストに対して UDP でログを送信して追加します。
理由は以下です。
- docker コンテナ内でアプリを動かしているので、今後コンテナが増えたときコンテナごとに rsyslog を設定してやるのが面倒そう
- 各コンテナのログを一箇所に集約したい
- syslog の記録には TCP or UDP のポート 514 が使用されるらしいが、
SysLogHandler
では UDP しか対応していないよう
rsyslog の設定変更
UDP のポート514 でログを待ち受けるように設定を変更します。
/etc/rsyslog.conf
を編集します。
$ sudo gedit /etc/rsyslog.conf
以下の2行のコメントを外します。
module(load="imudp")
input(type="imudp" port="514")
変更後は再起動します。
$ sudo systemctl restart rsyslog
アプリ側の実装
ログに関する設定を logging.yaml
に切り出しています。
その前提のうえで、以下のように指定するだけでログが UDP で送信されるようになります。
root:
level: DEBUG
handlers: [syslog]
handlers:
syslog:
class: logging.handlers.SysLogHandler
formatter: syslog_format
address: ['host.docker.internal', 514]
#address: '/dev/log'
level: INFO
formatters:
syslog_format:
format: 'appname: %(module)s %(message)s'
IPアドレスについては、docker コンテナからホストのIPアドレスを参照する必要があるので host.docker.internal
を指定します。
(localhost はコンテナ自身を指すので使えない)
ちなみに host.docker.internal
はもともと Windows と Mac でしか使えませんでしたが、最近 Linux でも使えるようになったそうです。
これ使えなかったら直接IPアドレスを指定しないといけなくなり、ホストのIPアドレスが変わるたびに修正しないといけなくてマジ困ります。 ってかこれを知るまでずっと困ってました。