Docker 로깅 기본
Docker 컨테이너의 stdout/stderr 출력은 로그 드라이버를 통해 수집됩니다. 기본 로그 드라이버는 json-file로, 호스트 파일시스템에 JSON 형태로 저장합니다.
# 컨테이너 로그 확인
docker logs my-app
# 2026-03-11T14:00:00.000Z info Server started on port 3000
# 2026-03-11T14:00:01.234Z info Connected to database
# 2026-03-11T14:00:05.678Z warn High memory usage: 85%
# 최근 100줄만 확인
docker logs --tail 100 my-app
# 실시간 로그 스트리밍
docker logs -f my-app
# 타임스탬프 포함
docker logs -t my-app
# 2026-03-11T14:00:00.000000000Z info Server started on port 3000
# 시간 범위 필터
docker logs --since "2026-03-11T14:00:00" --until "2026-03-11T15:00:00" my-app
# 로그 파일 위치 확인
docker inspect --format='{{.LogPath}}' my-app
# /var/lib/docker/containers/abc123.../abc123...-json.log
기본 설정에서 로그 파일은 무한히 커질 수 있습니다. 프로덕션에서는 반드시 로그 로테이션을 설정해야 합니다.
로그 드라이버 설정
Docker는 다양한 로그 드라이버를 지원합니다.
| 드라이버 | 저장 위치 | docker logs 지원 | 주요 특징 |
|---|---|---|---|
| json-file | 로컬 JSON 파일 | 지원 | 기본값, 로테이션 설정 가능 |
| local | 최적화된 로컬 파일 | 지원 | json-file보다 효율적 |
| syslog | syslog 서버 | 미지원 | 중앙 로그 서버로 전송 |
| journald | systemd journal | 지원 | systemd 환경에 적합 |
| fluentd | Fluentd 수집기 | 미지원 | EFK 스택과 연동 |
| awslogs | CloudWatch | 미지원 | AWS 환경에 적합 |
json-file 로그 로테이션
// /etc/docker/daemon.json — 전역 로그 설정
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "5",
"compress": "true",
"tag": "{{.ImageName}}/{{.Name}}"
}
}
# 설정 적용
sudo systemctl restart docker
# 컨테이너별 개별 설정 (전역 설정 오버라이드)
docker run -d \
--name api \
--log-driver json-file \
--log-opt max-size=100m \
--log-opt max-file=10 \
my-app:latest
# Docker Compose에서 로그 설정
# docker-compose.yml
# services:
# api:
# image: my-app:latest
# logging:
# driver: json-file
# options:
# max-size: "50m"
# max-file: "5"
local 드라이버 (권장)
local 드라이버는 json-file보다 디스크 사용이 효율적이며, 기본적으로 로테이션이 설정되어 있습니다.
// /etc/docker/daemon.json
{
"log-driver": "local",
"log-opts": {
"max-size": "50m",
"max-file": "5"
}
}
구조화된 로그 출력
애플리케이션에서 JSON 형태로 로그를 출력하면 로그 분석과 검색이 쉬워집니다.
// Node.js 구조화된 로그 예제 (pino 라이브러리)
const pino = require('pino');
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
// JSON 형식으로 출력 (Docker 로그 드라이버와 호환)
formatters: {
level: (label) => ({ level: label }),
},
// 타임스탬프 포함
timestamp: pino.stdTimeFunctions.isoTime,
});
// 사용 예
logger.info({ userId: 123, action: 'login' }, '사용자 로그인');
// {"level":"info","time":"2026-03-11T14:00:00.000Z","userId":123,"action":"login","msg":"사용자 로그인"}
logger.error({ err: error, requestId: 'abc' }, '요청 처리 실패');
// {"level":"error","time":"2026-03-11T14:00:01.000Z","err":{"message":"...","stack":"..."},"requestId":"abc","msg":"요청 처리 실패"}
cAdvisor — 컨테이너 리소스 모니터링
cAdvisor(Container Advisor)는 Google이 개발한 컨테이너 모니터링 도구입니다. 각 컨테이너의 CPU, 메모리, 네트워크, 디스크 사용량을 실시간으로 수집합니다.
# cAdvisor 실행
docker run -d \
--name cadvisor \
--privileged \
-p 8080:8080 \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker:ro \
-v /dev/disk/:/dev/disk:ro \
gcr.io/cadvisor/cadvisor:latest
# 웹 UI 접근: http://localhost:8080
# API로 메트릭 조회: http://localhost:8080/api/v1.3/docker/
# Prometheus 메트릭 엔드포인트: http://localhost:8080/metrics
cAdvisor는 자체 웹 UI도 제공하지만, Prometheus와 연동하여 장기간 데이터를 저장하고 Grafana로 시각화하는 것이 일반적입니다.
Prometheus + Grafana 모니터링 스택
Prometheus(메트릭 수집/저장) + Grafana(시각화) + cAdvisor(컨테이너 메트릭)를 Docker Compose로 구성합니다.
# monitoring/docker-compose.yml
# 컨테이너 모니터링 스택
services:
# Prometheus — 메트릭 수집 및 저장
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
# 메트릭 보존 기간: 30일
- '--storage.tsdb.retention.time=30d'
networks:
- monitoring
# Grafana — 대시보드 시각화
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
volumes:
- grafana-data:/var/lib/grafana
depends_on:
- prometheus
networks:
- monitoring
# cAdvisor — 컨테이너 메트릭 수집
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
privileged: true
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
networks:
- monitoring
# Node Exporter — 호스트 시스템 메트릭
node-exporter:
image: prom/node-exporter:latest
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
networks:
- monitoring
networks:
monitoring:
driver: bridge
volumes:
prometheus-data:
grafana-data:
Prometheus 설정
# monitoring/prometheus.yml
# Prometheus 수집 대상 설정
global:
# 15초마다 메트릭 수집
scrape_interval: 15s
# 평가 주기
evaluation_interval: 15s
scrape_configs:
# Prometheus 자체 메트릭
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# cAdvisor 컨테이너 메트릭
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
# Node Exporter 호스트 메트릭
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
# 애플리케이션 메트릭 (앱에서 /metrics 엔드포인트 제공 시)
- job_name: 'my-app'
static_configs:
- targets: ['api:3000']
metrics_path: '/metrics'
# 모니터링 스택 실행
cd monitoring
docker compose up -d
# Prometheus 접속: http://localhost:9090
# Grafana 접속: http://localhost:3000 (admin / 설정한 비밀번호)
# Prometheus에서 컨테이너 CPU 사용량 쿼리 (PromQL)
# rate(container_cpu_usage_seconds_total{name=~".+"}[5m])
# 컨테이너 메모리 사용량 쿼리
# container_memory_usage_bytes{name=~".+"}
알림 설정
Prometheus Alertmanager로 임계값 초과 시 알림을 보냅니다.
# monitoring/alert-rules.yml
# Prometheus 알림 규칙
groups:
- name: container-alerts
rules:
# 컨테이너 다운 알림
- alert: ContainerDown
# 5분 동안 컨테이너가 실행되지 않으면 알림
expr: absent(container_last_seen{name=~"myapp_.+"})
for: 5m
labels:
severity: critical
annotations:
summary: "컨테이너 다운: {{ $labels.name }}"
# CPU 사용률 80% 초과
- alert: HighCpuUsage
expr: rate(container_cpu_usage_seconds_total{name=~".+"}[5m]) > 0.8
for: 10m
labels:
severity: warning
annotations:
summary: "높은 CPU 사용률: {{ $labels.name }} ({{ $value }})"
# 메모리 사용률 90% 초과
- alert: HighMemoryUsage
expr: container_memory_usage_bytes{name=~".+"} / container_spec_memory_limit_bytes{name=~".+"} > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "높은 메모리 사용률: {{ $labels.name }}"
# 디스크 사용률 85% 초과
- alert: HighDiskUsage
expr: (node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes > 0.85
for: 10m
labels:
severity: warning
annotations:
summary: "디스크 사용률 85% 초과: {{ $labels.mountpoint }}"
docker stats — 간단한 실시간 모니터링
별도 도구 없이 Docker CLI만으로 컨테이너 리소스를 확인할 수 있습니다.
# 실시간 리소스 모니터링
docker stats
# CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
# abc123 api 2.50% 256MiB / 512MiB 50% 1.2MB / 800kB 5MB / 2MB
# def456 db 1.20% 128MiB / 1GiB 12% 500kB / 1MB 50MB / 20MB
# ghi789 redis 0.10% 32MiB / 256MiB 12% 100kB / 50kB 0B / 0B
# 특정 컨테이너만 (비스트리밍, 현재 상태만)
docker stats --no-stream api db
# 커스텀 포맷
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}"
# NAME CPU % MEM USAGE / LIMIT MEM %
# api 2.50% 256MiB / 512MiB 50.00%
# db 1.20% 128MiB / 1GiB 12.50%
정리
- 로그 로테이션 필수: 프로덕션에서 로그 로테이션 없이 운영하면 디스크가 가득 차서 서비스가 중단됩니다.
daemon.json에max-size와max-file을 반드시 설정하세요.local드라이버는 기본 로테이션이 적용되어 편리합니다. - 구조화된 로그: JSON 형태의 로그를 출력하면 EFK/ELK 스택이나 CloudWatch 같은 로그 분석 도구에서 필드별 검색과 필터링이 가능합니다. 평문 로그보다 운영 효율이 높습니다.
- Grafana 대시보드: Docker 모니터링용 커뮤니티 대시보드(ID: 193, 1860 등)를 임포트하면 별도 설정 없이 바로 사용할 수 있습니다. Grafana 접속 후 Dashboards → Import에서 ID를 입력하세요.
- 알림 채널: Alertmanager와 Slack, PagerDuty, 이메일 등을 연동하여 장애 알림을 받으세요. 알림 없는 모니터링은 대시보드를 계속 쳐다보고 있어야 하므로 의미가 반감됩니다.
- 보존 기간과 스토리지: Prometheus 메트릭 보존 기간(
--storage.tsdb.retention.time)을 서비스 규모에 맞게 설정하세요. 30일이면 대부분 충분하며, 장기 분석이 필요하면 Thanos나 Mimir로 원격 스토리지를 구성합니다.