はじめに
dockerのログは放っておくとどんどん溜まります。
そのうち、ホストを圧迫して・・・死にます。
ということで、docker-composeをつかっているなら、docker-compose.yamlに次のように書いてログをローテーションしましょう。
services:
my-app:
build: .
logging:
driver: json-file
options:
max-size: 1m
max-file: '3'
説明
logging
のoptions
にmax-size
とmax-file
を指定します。
max-size
あたりでログがロールオーバーされ、max-file
の数だけログ保持されます。
疑問点
ログは、docker-compose logs
やdocker logs
コマンドで確認しますが、ロールオーバーされた古いログはどう扱われるのでしょうか。
検証
とりあえず、stdoutにベラベラ出力するコンテナを作成します。
FROM alpine
CMD seq 100000001 100500000; sleep 300
100000001から100500000まで9桁の数字を出力するので、出力1行あたり10Byteです。
500000行出力するので、出力は5MBになるはずです。
ビルドして実行してみます。
docker-compose build
docker-compose up -d
ログの実体を確認してみましょう。
# cd /var/lib/docker/containers/5671d9b180b36d67e0d7aa4418b2f91d7249e163829016c37b927871b3d696f7/
# ls -lh *log*
-rw-r----- 1 root root 921K Jan 17 15:44 5671d9b180b36d67e0d7aa4418b2f91d7249e163829016c37b927871b3d696f7-json.log
-rw-r----- 1 root root 977K Jan 17 15:44 5671d9b180b36d67e0d7aa4418b2f91d7249e163829016c37b927871b3d696f7-json.log.1
-rw-r----- 1 root root 977K Jan 17 15:44 5671d9b180b36d67e0d7aa4418b2f91d7249e163829016c37b927871b3d696f7-json.log.2
977KBでロールオーバーされて、現行のログファイルも含めて3つのログファイルが残っています。
一番古いファイルの先頭を見てみると、
# tail -n 3 5671d9b180b36d67e0d7aa4418b2f91d7249e163829016c37b927871b3d696f7-json.log.2
{"log":"100463168\n","stream":"stdout","time":"2023-01-17T06:44:26.117807532Z"}
{"log":"100463169\n","stream":"stdout","time":"2023-01-17T06:44:26.118047805Z"}
{"log":"100463170\n","stream":"stdout","time":"2023-01-17T06:44:26.118051124Z"}
こんな感じのJSONで保存されていました。
1MBでローテーションというのは、このJSON形式になったときのサイズで、stdoutに出力されたサイズではないようです。
では、logを見るコマンドではどのログが見えるのでしょうか。
# docker-compose logs | head -n 3
docker-log-test-log-test-1 | 100463168
docker-log-test-log-test-1 | 100463169
docker-log-test-log-test-1 | 100463170
3つのファイルのうち一番古いものから取り出しているようです。
では、最後はどうでしょうか。
# docker-compose logs | tail -n 3
docker-log-test-log-test-1 | 100499998
docker-log-test-log-test-1 | 100499999
docker-log-test-log-test-1 | 100500000
こちらは最新のログファイルの最後です。
ということで、docker-compose logsコマンドは、ロールオーバーの結果分割されたログを結合していい感じに見せてくれるようです。
では、docker logsコマンドはどうでしょうか。
# docker logs 56 | head -n 3
100463168
100463169
100463170
# docker logs 56 | tail -n 3
100499998
100499999
100500000
はい。こちらも、同様に分割されたログを結合していい感じに見せてくれるようです。
まとめ
docker-compose.yamlに
logging:
driver: json-file
options:
max-size: 1m
max-file: '3'
と書いておくと、1MB毎にログをロールオーバーして、3つのファイルだけ残してくれる。
docker-compose logs
やdocker logs
コマンドは分割されたログを結合していい感じに処理してくれる。