動機
大学の研究で、ファイルを変えながら連続でDockerビルドをするって事をやりました。
その時にいちいち各コマンドの所要時間とか全体のビルド時間とかメモするが面倒だったので、適当なファイルにビルドログを出力して後で見たいなと思ったんです。
その方法を調べても、なんかコンテナ内部の標準出力を外部に吐き出す系の情報しかHITしませんでした。
多分もっとスマートな方法があるとかDockerの機能であるとかいう可能性もありますが、探しても見つからないので、急ごしらえではありますがビルドログを外部ファイルに残す方法をメモとして残します。
方法
最初は普通にリダイレクトさせれば外部ファイルに出力できると思って実行→ダメでした……
scriptを使えば、一応全てのビルドログを残す事ができました。
script buildlog.txt
引数に出力先ファイルを指定(なければ新規作成される)
exit
scriptによるログ記録の終了コマンド
2回やるとログアウトしてしまうので注意
script~exitの間に実行した全てのログが外部ファイルに出力されているはずです。
データ処理
scriptで処理ログを出力してみると、ビルド完了時に出てくるあの画面かと思いきや、余計な情報が入ってしまっています。
・特殊文字がかなり入り込んでる
・BuildがFINISHEDした時のビルドログ(Build終了時に見える画面)ではなく、途中経過まで残っている
理想:
Building 5.4s (15/15) FINISHED [internal] load build definition from Dockerfile 0.2s
transferring dockerfile: 5.15kB 0.0s
[internal] load .dockerignore 0.1s
transferring context: 2B 0.0s
resolve image config for docker.io/docker/dockerfile:1 1.8s
CACHED docker-image://docker.io/docker/dockerfile:1@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50 0.0s
[internal] load build definition from Dockerfile 0.0s
[internal] load metadata for docker.io/library/node:19-bullseye 2.0s
[internal] load .dockerignore 0.0s
[1/6] FROM docker.io/library/node:19-bullseye@sha256:92f06fc13bcc09f1ddc51f6ebf1aa3d21a6532b74f076f224f188bc6 0.0s
[internal] load build context 0.1s
=> transferring context: 4.73MB 0.1s
[CACHED [2/6] WORKDIR /app 0.0s
CACHED [3/6] COPY [package.json, package-lock.json*, ./] 0.0s
CACHED [4/6] RUN npm install 0.0s
CACHED [5/6] COPY index.js 0.0s
[6/6] COPY . . 0.5s
exporting to image 0.3s
=> exporting layers 0.2s
=> writing image sha256:933692fe58d2bb9392b4ec8c4f14506f9f8530b4c293b98c5aae36f3efa8e31a 0.0s
=> naming to docker.io/library/**** 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
現実:
[?25h[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[1A[0G[?25l[+] Building 5.0s (13/14)
[34m => [internal] load build definition from Dockerfile 0.2s
[0m[34m => => transferring dockerfile: 5.15kB 0.0s
[0m[34m => [internal] load .dockerignore 0.1s
[0m[34m => => transferring context: 2B 0.0s
[0m[34m => resolve image config for docker.io/docker/dockerfile:1 1.8s
[0m[34m => CACHED docker-image://docker.io/docker/dockerfile:1@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50 0.0s
[0m[34m => [internal] load build definition from Dockerfile 0.0s
[0m[34m => [internal] load metadata for docker.io/library/node:19-bullseye 2.0s
[0m[34m => [internal] load .dockerignore 0.0s
[0m[34m => [1/6] FROM docker.io/library/node:19-bullseye@sha256:92f06fc13bcc09f1ddc51f6ebf1aa3d21a6532b74f076f224f188bc6 0.0s
[0m[34m => [internal] load build context 0.1s
[0m[34m => => transferring context: 4.73MB 0.1s
[0m[34m => CACHED [2/6] WORKDIR /app 0.0s
[0m[34m => CACHED [3/6] COPY [package.json, package-lock.json*, ./] 0.0s
[0m[34m => CACHED [4/6] RUN npm install 0.0s
[0m[34m => CACHED [5/6] COPY index.js Dockerfile bare/EncodeProtocol.mjs bare/Example.mjs bare/HeaderUtil.mjs bare/LICEN 0.0s
[0m => [6/6] COPY . . 0.4s
動画が静止画の連続で構成されているように、ビルドログを高速で表示・削除を行っているため、途中経過の画面を表示する用ログまでscriptで保存していることでこの現象が発生している模様。
そのため、途中経過ではなく最終結果のログだけ欲しい場合は、データを整形させてあげる必要があります。
今回私は各ビルドの所要時間を抜き出すために、次のようなプログラムを書いてみました。
import re
import csv
with open("TEST/buildlog.txt", newline='', mode='r') as f:
reader = f.readlines() #scriptで記録したファイルを配列に読み込む
finished = []
for row in reader:
if ("FINISHED" in row): #最終結果には先頭の文字列にFINISHEDが含まれることを利用
time = re.search('\d+'"."'\d+', row)
finished.append(time.group())
with open("TEST/buildtime.csv", newline='', mode='w') as f:
writer = csv.writer(f)
writer.writerow(finished)
これで、scriptで記録した全Buildのビルド時間をCSVファイルに書き出すことができて、ようやく私が欲しかったデータが手に入りました。