概要
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の場合
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
$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-text
がdaemon
で、$programname
にsample-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
に指定した文字列。
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に以下のように設定する。
$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
としてマッチしないようにしてみる。
$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**.log
、ZERO
の場合は0.log
がファイル名となる。BLANK
の場合はログファイルが出力されない。