Модуль 12 / 18
Логи, метрики, events і системна діагностика
Зміст
1. Цілі та сигнали спостережуваності
Після модуля ви зможете пов’язати logs, metrics, events, inspect і daemon journal в одну часову шкалу та зібрати evidence до зміни системи.
- logs пояснюють повідомлення процесу
- metrics показують ресурси
- events фіксують зміни Engine
- inspect зберігає config і state
- daemon logs описують control plane
2. Теорія: stdout, stderr і logging driver
Docker захоплює stdout/stderr PID 1 і передає записи logging driver. docker logs працює лише коли driver підтримує читання; внутрішні файли container не мають бути єдиним джерелом.
json-file без rotation може зростати. Local driver має rotation; max-size і max-file обмежують зберігання. Нові daemon defaults діють лише для нових containers.
3. Теорія: якість логів
Структурований запис містить timestamp, level, service, request/trace ID та event. Не записуйте passwords, tokens і персональні дані; контролюйте cardinality та payload.
Application timestamp і синхронізований UTC потрібні для correlation навіть за runtime timestamp.
4. Теорія: stats і cgroups
docker stats показує CPU, memory, network, block I/O та PIDs. Це operational snapshot, а не довготривалий monitoring; trends потребують scraper, storage, dashboards та alerts.
Linux CLI віднімає cache від memory usage, API/cgroup можуть показувати total. PIDS включає threads.
5. Теорія: Engine events і timeline
docker events — best-effort потік create, start, die, destroy та health. Filters і timeNano допомагають correlation.
Events не є довготривалим audit log; потрібний потік зберігайте зовні.
6. Теорія: системна діагностика
Порядок: context і час → object → state → logs → events → resources → daemon/host. Restart і prune до evidence руйнують картину.
Daemon failures шукають у journal, disk/inodes, kernel OOM та network. Debug вмикають обмежено через обсяг і sensitive metadata.
7. Методичні вказівки
- Зафіксуйте UTC і context
- Використовуйте ownership labels
- Обмежуйте log retention
- Не парсьте кольорові таблиці
- Зберігайте inspect JSON до rm
- Зіставляйте два незалежні сигнали
- Не запускайте prune під час investigation
- Спочатку сформулюйте гіпотезу
8. Лабораторна робота
Створіть процес із local logging та rotation, дослідіть logs і metrics.
docker run --detach --name docker-m12-app --label course.module=12 --memory 64m --cpus 0.5 --log-driver local --log-opt max-size=10k --log-opt max-file=2 alpine:3.21 sh -c 'i=0; while [ "$i" -lt 2000 ]; do i=$((i+1)); printf "ts=%s level=info request_id=req-%04d message=working payload=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" "$(date -u +%FT%TZ)" "$i"; [ $((i%500)) -eq 0 ] && echo "level=warn checkpoint=$i" >&2; done; sleep 300'
docker inspect docker-m12-app --format '{{json .HostConfig.LogConfig}}' | jq
docker inspect docker-m12-app --format 'log_path={{.LogPath}}'
docker logs --tail 10 --timestamps docker-m12-app
docker logs --since 5m --until 0s docker-m12-app 2>&1 | tail -20docker stats docker-m12-app --no-stream
docker stats docker-m12-app --no-stream --format '{{json .}}' | jq
docker top docker-m12-app
docker inspect docker-m12-app --format '{{json .State}}' | jq '{Status,Pid,StartedAt,OOMKilled,Error}'
docker system df
docker system df --verboseЗапишіть events failed container і відновіть timeline.
timeout 10s docker events --since 0s --filter type=container --filter container=docker-m12-event --format '{{json .}}' > /tmp/docker-m12-events.jsonl &
event_pid=$!
sleep 1
docker run --name docker-m12-event alpine:3.21 sh -c 'echo event-demo; exit 42' || true
docker rm docker-m12-event
wait "$event_pid" || true
jq -s 'map({action:.Action,timeNano:.timeNano})' /tmp/docker-m12-events.jsonldocker run --name docker-m12-failure --log-driver local alpine:3.21 sh -c 'echo "fatal: dependency unavailable" >&2; exit 42' || true
docker ps -a --filter name=docker-m12-failure
docker logs --timestamps docker-m12-failure
docker inspect docker-m12-failure --format '{{json .State}}' | jq
docker events --since 10m --until 0s --filter container=docker-m12-failureКритерій: options підтверджені inspect; stats отримані як JSON; exit 42 є в logs, inspect та events.
9. Діагностика Engine і host
Перевіряйте control plane окремо від застосунку. Journal може вимагати permissions.
docker info --format 'logging={{.LoggingDriver}} cgroup={{.CgroupVersion}} driver={{.Driver}}'
docker version
systemctl --no-pager --full status docker.service | sed -n '1,25p'
journalctl -u docker.service --since '10 minutes ago' --no-pager | tail -50
df -h /var/lib/docker
df -i /var/lib/docker- помилка до API — context/transport
- created, не started — runtime/mount/security
- exited — State, logs, OOM, events
- daemon unavailable — journal/socket/disk
- latency — CPU, memory, I/O, network
- disk full — images, layers, volumes, logs
10. Контроль і cleanup
- Що читає docker logs?
- Навіщо rotation?
- Чому defaults не змінюють старі containers?
- Чому stats і cgroup memory різні?
- Що означає PIDS?
- Чи events є audit log?
- Які evidence до rm?
- Коли debug?
docker rm --force docker-m12-app docker-m12-failure 2>/dev/null || true
rm -f /tmp/docker-m12-events.jsonl
docker ps -a --filter name=docker-m12
docker system dfМодуль засвоєно, якщо ви будуєте timeline без здогадок і локалізуєте failure до безпечної зміни.