Docker: ログ記録と監視
最終更新:2026-08-26
深夜 3 時にコンテナがクラッシュした——そんなとき、ログと監視が根本原因を素早く特定する唯一の手段です。
1. 学べること
- 4 種類のログドライバーとそれぞれの適用シーン
- リアルタイムログの確認とフィルタリングのコツ
- コンテナリソースの監視手法
- ログローテーション戦略
- 集中ログ収集のアプローチ
2. 運用エンジニアの実話
(1) 悩み: 深夜 3 時の OOM アラートに手がかりなし
深夜 3 時、本番環境のコンテナが突然メモリ使用量を急増させ OOM エラーを起こしました。Charlie はアラートで叩き起こされますが、原因がわかりません。ログファイルは 2 GB、docker logs は流れるのが速すぎて肝心な情報を探せず、過去のリソース監視データもない——手探り状態でした。
(2) ログフィルタリングとリソース監視による解決
Charlie は docker logs --since と grep を組み合わせて、30 秒で異常リクエストを突き止めました。
BASH
# 直近 2 時間の OOM 関連ログを探す
docker logs --since 2h --tail 500 app 2>&1 | grep -i "oom\|memory\|error"
# リソース使用履歴を確認
docker stats --no-stream
(3) 効果: 30 秒で根本原因を特定
2 GB のログの中から、30 秒で OOM イベントと異常リクエストを特定しました。Charlie はその後ログローテーションと Prometheus アラートを設定し、次回以降の深夜アラートには自動的に根本原因が含まれるようにしました。
3. Docker のログドライバー
(1) 4 種類のログドライバー
graph LR
CTN["コンテナ<br/>stdout/stderr"] --> DRV["ログドライバー"]
DRV --> JSON["json-file<br/>デフォルト、ローカルファイル"]
DRV --> JRN["journald<br/>systemd ログ"]
DRV --> SYS["syslog<br/>リモートログサーバー"]
DRV --> GELF["gelf<br/>ELK/Loki"]
| ドライバー | 保存場所 | ローテーション | 集中管理 | ユースケース |
|---|---|---|---|---|
| json-file(デフォルト) | /var/lib/docker/containers/ |
手動設定が必要 | ❌ | スタンドアロン開発 |
| journald | systemd ジャーナル | ✅ 自動 | ❌ | systemd 環境 |
| syslog | リモート syslog サーバー | ✅ サーバー側 | ✅ | 従来のログ基盤 |
| gelf | ELK / Loki | ✅ サーバー側 | ✅ | 集中ログプラットフォーム |
| local | ローカルファイル(最適化形式) | ✅ 自動 | ❌ | 軽量なローカルログ |
| なし | ログを記録しない | - | - | 高性能 / 機密データ |
(2) ログドライバーの設定
BASH
# コンテナ個別: 起動時にログドライバーを指定
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name app myapp:1.0
JSON
// グローバル: /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
4. docker logs の高度な使い方
▶ サンプル: --since で時間フィルタ (難易度: ⭐⭐)
BASH
# 直近 2 時間のログを表示
docker logs --since 2h app
# 特定の時刻以降のログを表示
docker logs --since "2024-01-15T03:00:00" app
# 2 つのタイムスタンプ間のログを表示
docker logs --since "2024-01-15T03:00:00" --until "2024-01-15T04:00:00" app
▶ サンプル: --tail で行数を制限 (難易度 ⭐)
BASH
# 末尾 100 行を表示
docker logs --tail 100 app
# 末尾 100 行をリアルタイムで追跡
docker logs -f --tail 100 app
▶ サンプル: docker stats でリアルタイム監視 (難易度: ⭐⭐)
BASH
# 全コンテナのリソース統計をリアルタイム表示
docker stats
# ワンショットスナップショット(ストリームなし)
docker stats --no-stream
# 特定コンテナの統計
docker stats app db --no-stream
# カスタムフォーマット
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
💻 出力:
TEXT
📖 参照専用
NAME CPU % MEM USAGE / LIMIT
app 2.35% 150MiB / 512MiB
db 0.50% 85MiB / 256MiB
▶ サンプル: docker events でイベント追跡 (難易度: ⭐⭐)
BASH
# Docker デーモンのイベントをストリーム
docker events
# イベントタイプでフィルタ
docker events --filter type=container
# 特定のイベントでフィルタ
docker events --filter event=oom --filter event=die
# 時間帯でフィルタ
docker events --since "2024-01-15T03:00:00" --until "2024-01-15T04:00:00"
💻 出力:
TEXT
📖 参照専用
2024-01-15T03:24:15Z container oom 67890... (name=app, image=myapp)
2024-01-15T03:24:15Z container die 67890... (exitCode=137, name=app)
2024-01-15T03:24:25Z container start 67890... (name=app, image=myapp)
5. ログローテーション戦略
(1) json-file のログローテーション
| パラメーター | 機能 | 推奨値 |
|---|---|---|
max-size |
単一ログファイルの最大サイズ | 10m |
max-file |
保持するログファイルの最大数 | 3 |
labels |
ログに付与するラベル | - |
tag |
ログタグのテンプレート | - |
▶ サンプル: ログローテーションの設定 (難易度: ⭐⭐)
BASH
# コンテナ起動時にログローテーションを設定
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name app myapp:1.0
💡 ヒント: ログローテーションを設定していないコンテナは「時限爆弾」です——ログファイルは無限に増え続け、ディスクを埋め尽くします。本番環境では必ず
max-size と max-file を設定するか、ローテーションを内蔵した local ログドライバーを使ってください。
(2) Compose でのログ設定
YAML
services:
api:
image: myapp:1.0
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
6. 集中ログ収集ソリューション
(1) 3 つの選択肢の比較
| ソリューション | 構成要素 | 複雑度 | 適用規模 |
|---|---|---|---|
| docker logs | 組み込み | ⭐ | 単一マシン / 開発 |
| ELK スタック | Elasticsearch + Logstash + Kibana | ⭐⭐⭐ | エンタープライズ規模 |
| Loki + Grafana | Loki + Promtail + Grafana | ⭐⭐ | 中小規模 / クラウドネイティブ |
7. 完全なサンプル: ログローテーションと監視の設定
BASH
# ============================================
# 完全なウォークスルー: ログローテーション + 監視
# 内容: ログローテーション、stats、events、OOM 診断
# ============================================
# 1. ログローテーション付きでアプリを起動
docker run -d \
--name app \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--memory=256m \
--restart=on-failure:5 \
-p 5000:5000 \
myapp:1.0
# 2. リソース使用量を監視
docker stats app --no-stream
# 3. シミュレーション: メモリ超過で OOM を発生させる
docker exec app python -c "
import numpy as np
x = np.zeros((50000, 50000)) # 約 20GB の割り当てを試行
"
# 4. OOM イベントをキャプチャ
docker events --filter event=oom --since 1m
# 5. ログから OOM をタイムスタンプ付きで探す
docker logs --since 5m --tail 200 app 2>&1 | grep -i "oom\|memory\|killed"
# 6. 終了コードを確認
docker inspect app --format='ExitCode: {{.State.ExitCode}}, OOMKilled: {{.State.OOMKilled}}'
# 7. 直近 1000 行をエクスポートして解析
docker logs --tail 1000 app > app-debug.log 2>&1
# 8. ログローテーションが動作していることを確認
ls -la /var/lib/docker/containers/$(docker inspect app --format='{{.Id}}')/
❓ よくある質問
Q ログファイルが大きすぎるとディスクに影響しますか?
A はい、影響します。デフォルトの json-file ドライバーはログをローテーションしないため、ログファイルは無限に増大します。本番環境で 1 つのコンテナのログファイルが 50 GB に達した事例もあります。起動時に必ず
--log-opt max-size=10m --log-opt max-file=3 を設定するか、デーモン.json でグローバルにデフォルトローテーションを設定してください。Q ログローテーションを設定するには?
A 2 つの方法があります: ① コンテナ起動時に
--log-opt max-size=10m --log-opt max-file=3 を指定する; ② /etc/docker/daemon.json のグローバル設定に "log-opts": {"max-size": "10m", "max-file": "3"} を記述する。本番環境では設定漏れを防ぐためグローバル設定を推奨します。Q 複数コンテナのログを集中収集するには?
A gelf または syslog ログドライバーを使い、全コンテナのログを集中 ELK / Loki プラットフォームへ送信します。より推奨される方法: json-file ドライバーのまま、Filebeat / Promtail でログファイルを収集します——そうすれば
docker logs も引き続き使えます。Q コンテナ再起動後もログは残っていますか?
A はい、残っています。コンテナ再起動ではログファイルは削除されません。ただし
docker rm でコンテナを削除するとログも消えます。ログを永続化するには: ① アプリケーションログをファイルに書いてボリュームにマウントする; ② 集中ログプラットフォームでリアルタイム収集する。Q
docker stats のメモリ表示はコンテナのものかプロセスか?A コンテナ全体です。
docker stats はコンテナ内全プロセスの cgroup メモリ使用量合計を表示します。LIMIT は --memory で設定した上限です。--memory を設定していない場合、LIMIT はホストの全メモリが表示されます。📖 まとめ
- 4 種類のログドライバー: json-file(デフォルト)、journald、syslog、gelf——本番環境ではローテーション設定が必須
docker logsの高度フィルタリング:--since/--untilで時間フィルタ、--tailで行数制限、-fでリアルタイム追跡docker statsは CPU、メモリ、I/O をリアルタイム監視、--no-streamでワンショットスナップショットdocker eventsはコンテナのライフサイクルイベントを追跡、OOM / die / restart などの重要イベントも含む- ログローテーション:
max-size=10m max-file=3でディスク満杯を防ぐ - 集中ログ: ELK(エンタープライズ規模)または Loki + Grafana(軽量 / クラウドネイティブ)
📝 練習問題
- 基本練習 (難易度 ⭐): コンテナを起動し
--log-opt max-size=5m --log-opt max-file=2を設定、その後docker logsでログを確認し、ローテーションが効いているか検証してください。 - 応用問題 (難易度 ⭐⭐): 負荷テスト中に
docker statsでコンテナを監視し、CPU とメモリのピーク使用量を記録してください。 - 挑戦 (難易度: ⭐⭐⭐):
docker eventsでコンテナの OOM イベントをキャプチャし、docker logs --sinceを組み合わせて OOM を引き起こしたリクエストまたは処理を特定してください。