はじめに
DjangoでDockerコンテナのログをテキストエリアに出力する方法をまとめます。
前提
Dockerコンテナの操作には docker-py
を使います。
django==3.0.8 docker==4.2.0
ビューの実装
ビュー tail_log
を実装します。
このビューは、URLパラメタ container_name
で指定したコンテナのログを docker-py
のContainer.logsで取得し、
StreamingHttpResponseで返します。
import time from datetime import datetime import docker from django.http import StreamingHttpResponse def tail_log(request, container_name): client = docker.from_env() container = client.containers.get(container_name) return StreamingHttpResponse( _stream_docker_logs(container), content_type='text/event-stream' ) def _stream_docker_logs(container): for line in container.logs( stream=True, since=datetime.utcfromtimestamp(time.time())): yield 'data: {}\n\n'.format(line.decode('utf-8')) time.sleep(0.1)
urls.py
にはTemplateViewで画面を描画する index
と、上記の views.tail_log
を呼び出す tail_log
を追記します。
from django.urls import path from django.views.generic.base import TemplateView from .views import tail_log urlpatterns = [ path('<str:container_name>', TemplateView.as_view(template_name='tail_docker_logs/index.html'), name='index'), path('docker/logs/<str:container_name>', tail_log, name='tail_log'), ]
テンプレートの実装
テキストエリア( console
)にEventSource.onmessageで取得したDockerコンテナのログを出力します。
ログにHTML要素が含まれるような場合はエスケープしないと正しく表示されません。
<html> <head> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> </head> <body> <p>> docker logs -f {{ request.resolver_match.kwargs.container_name }}</p> <textarea id="console" rows="30" cols="100" readonly></textarea> <script> $(function() { let ES = new EventSource( "{% url 'tail_log' request.resolver_match.kwargs.container_name %}" ); ES.onmessage = function(e) { $('#console').append(`${e.data}\n`); $('#console').scrollTop( $('#console')[0].scrollHeight - $('#console').height() ); }; }); </script> </body> </html>
実行例
コンテナ ab3c3b9660b0
のログを確認しています。
さいごに
実装したコードは以下のリポジトリに置きました。