LoginSignup
18
17

More than 3 years have passed since last update.

Dockerのログをrsyslogで出力する

Posted at

概要

Dockerのログをrsyslogで出力する方法。

関連

環境

  • CentOS 7.7
  • rsyslog 8.24.0-41.el7_7.2

Dockerの設定

Dockerもしくはdocker-composeで、以下のパラメータを指定し、rsyslogにログが渡るようにする。
ログには、This is a example.という文字列が出力されるようにする。

設定内容 Docker docker-compose
syslogを使う --log-driver=syslog logging.driver
ログの種類の分類 --log-opt syslog-facility={facility名} logging.options.syslog-facility
ログやファイル名に使用する名前 --log-opt tag={任意の文字列} logging.options.tag

dockerコマンドの場合

$ sudo docker run --rm \
    --name sample-container \
    --log-driver=syslog \
    --log-opt syslog-facility=daemon \
    --log-opt tag=sample-app/{{.Name}}/{{.ID}} \
    -it ${Dockerイメージ名} \
    /bin/bash -c 'echo "This is a example."'

docker-composeの場合

docker-compose.yml
version: '3'
services:
  sample-container:
    image: sample-image
    command: 'echo "This is a example."'
    logging:
      driver: syslog
      options:
        syslog-facility: daemon
        tag: sample-app/{{.Name}}/{{.ID}}
変数 意味
{{.Name}} コンテナ名
{{.ID}} コンテナID

rsyslogの設定

rsyslogのtemplateという機能を使って、ログファイル名の指定をする。
/var/log/docker/sample-app_年月日.logというログファイル名になるようにする。

/etc/rsyslog.d/10-docker.conf

/etc/rsyslog.d/10-docker.conf
$template DockerLogs, "/var/log/docker/%programname%_%$year%%$month%%$day%.log"

if $syslogfacility-text == 'daemon' and $programname contains 'sample-app' then -?DockerLogs
& stop
変数 意味
$template templateを使うための宣言
DockerLogs template名。任意の文字列でOK
%programname% ログを出力しているプログラム名
$programname ログを出力しているプログラム名
$syslogfacility-text --log-opt syslog-facility もしくは logging.options.syslog-facility に指定した文字列

その他の変数は以下を参照
rsyslog.confの文法

if $syslogfacility-text == 'daemon' and $programname contains 'sample-app' then -?DockerLogs

$syslogfacility-textdaemonで、$programnamesample-appという文字列が含まれるときのみログを出す。
$syslogfacility-text--log-opt syslog-facility もしくは logging.options.syslog-facilityと、$programname--log-opt tag もしくは logging.options.tag と合わせる必要がある。

rsyslogのrestart

/etc/rsyslog.d/10-docker.confを変更したあとはrestartが必要。

$ sudo systemctl restart rsyslog

出力されるログ

Dockerもしくはdocker-composeを実行。
実際に出力されるログ。

  • Format: /var/log/docker/{%programname%}_{%$year%%$month%%$day%}.log
  • e.g.): /var/log/docker/sample-app_20200218.log

sample-app/{コンテナ名}/{コンテナID}の部分は、--log-opt tag もしくは logging.options.tag に指定した文字列。

/var/log/docker/sample-app_20200218.log
Feb 18 17:03:19 example-hostname sample-app/sample-container/{コンテナID}[{dockerdのプロセスID}]: This is a example.

コンテナIDのみを抽出してログファイル名にする

nomatch-Modeを使って、文字列を抽出してファイル名に使用する方法。
この方法を利用して、コンテナIDのみをログファイル名にしてみる。

rsyslogの設定

/etc/rsyslog.d/10-docker.confに以下のように設定する。

/etc/rsyslog.d/10-docker.conf
$template DockerLogs, "/var/log/docker/%syslogtag:R,ERE,1,FIELD:sample-app/sample-container/(.*)\[(.*)\]:--end%.log"

if $syslogfacility-text == 'daemon' and $programname contains 'sample-app' then -?DockerLogs
& stop

"/var/log/docker/%syslogtag:R,ERE,1,FIELD:sample-app/sample-container/(.*)\[(.*)\]:--end%.log"の部分の説明。

変数 意味
/var/log/docker/ ログファイルを出力する場所
%syslogtag% --log-opt tag もしくは logging.options.tag に指定した文字列。正規表現で抽出する対象文字列となる。
R nomatchを利用するときはここはR
ERE 正規表現のタイプ。BRE of ERE。EREはBREを拡張したモード。通常こちらを選択する。
1 submatchの番号
FIELD nomatchモードの指定。枠下参照。
sample-app/sample-container/(.*)\[(.*)\]: 「R」の前の文字列(この場合は%syslogtag%)からこの正規表現で文字列を抽出し、ファイル名に使用する
--end%.log 最後に必ず書く

今回の設定の場合は、%syslogtag%から正規表現sample-app/sample-container/(.*)\[(.*)\]:で抽出した文字列をファイル名として使用するということになる。

nomatchモードについて

正規表現でマッチするものがなかった場合に返す、デフォルトの文字列をModeによって指定する。
各Modeごとに返す文字列は以下のようになっているが、FIELDを指定した場合は、正規表現対象の文字列全てが返される。(この場合は%syslogtag%)

Mode Returned
DFLT "**NO MATCH**"
BLANK "" (empty string)
ZERO "0"
FIELD full content of original field

引用元:Property Replacer nomatch mode

今回のFIELDの正規表現の場合の挙動

%syslogtag% = sample-app/sample-container/f76f6af73829[27081]

から、以下の正規表現で抽出をする。

sample-app/sample-container/(.*)\[(.*)\]:

submatchは1を指定しているため、1つ目の(.*)のみが抽出される。
つまり、コンテナIDであるf76f6af73829が抽出される。

結果、以下がファイル名となる。

/var/log/docker/f76f6af73829.log

rsyslogのrestart

/etc/rsyslog.d/10-docker.confを変更したあとはrestartが必要。

$ sudo systemctl restart rsyslog

出力されるログ

Dockerもしくはdocker-composeを実行。
この設定で実際に出力されるログ。

  • Format: /var/log/docker/sample-app/{コンテナ名}/{コンテナID}.log
  • e.g.): /var/log/docker/f76f6af73829.log

sample-app/{コンテナ名}/{コンテナID}の部分は、--log-opt tag もしくは logging.options.tag に指定した文字列。

Feb 18 17:21:23 example-hostname sample-app/sample-container/f76f6af73829[27081]: This is a example.

正規表現にマッチしない場合

rsyslogの設定

/etc/rsyslog.d/10-docker.confの正規表現の一部を、sample-app_nomatchとしてマッチしないようにしてみる。

/etc/rsyslog.d/10-docker.conf
$template DockerLogs, "/var/log/docker/%syslogtag:R,ERE,1,FIELD:sample-app_nomatch/sample-container/(.*)\[(.*)\]:--end%.log"

if $syslogfacility-text == 'daemon' and $programname contains 'sample-app' then -?DockerLogs
& stop

rsyslogのrestart

/etc/rsyslog.d/10-docker.confを変更したあとはrestartが必要。

$ sudo systemctl restart rsyslog

出力されるログ

Dockerもしくはdocker-composeを実行。
この設定で実際に出力されるログ。

  • Format: /var/log/docker/sample-app/{コンテナ名}/{コンテナID}[{dockerdのプロセスID}].log
  • e.g.): /var/log/docker/sample-app/sample-container/de64dadc7e97\[27081\]\:.log

sample-app/{コンテナ名}/{コンテナID}の部分は、--log-opt tag もしくは logging.options.tag に指定した文字列。

Feb 18 17:21:23 example-hostname sample-app/sample-container/de64dadc7e97[27081]: This is a example

正規表現がマッチせず、FIELDをしているので、%syslogtag%の中身がそのままファイル名となる。
前述したように、DFLTの場合はファイル名が**NO MATCH**.logZEROの場合は0.logがファイル名となる。BLANKの場合はログファイルが出力されない。

参考

18
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
17