Друзья, сегодня мы закроем один важный пробел. В прошлой статье я рассказал про Docker logs вообще — про драйверы, ротацию, централизованный сбор. А сегодня давайте сфокусируемся на самом главном: как правильно смотреть логи прямо сейчас, в консоли, когда контейнер падает и нужно срочно понять почему.

Потому что знать docker logs — мало. Нужно знать, как вытащить из этой команды максимум, не утонуть в потоке и увидеть именно то, что нужно.

База: что такое docker logs и откуда оно берётся

Напомню базовый принцип: Docker перехватывает всё, что процесс внутри контейнера пишет в stdout (стандартный вывод) и stderr (стандартный вывод ошибок). Команда docker logs просто показывает этот поток.

```bash

Показать все логи контейнера

docker logs my-container

Показать последние 50 строк

docker logs --tail 50 my-container

Следить за новыми строками (как tail -f)

docker logs -f my-container

Добавить временные метки к каждой строке

docker logs -t my-container ```

Это база, которую нужно знать наизусть.

Почему docker logs может не работать

Прежде чем мы углубимся в тонкости, давайте разберём ситуацию: вы запускаете docker logs, а там пусто. Или не то, что ожидали.

Причины: 1. Приложение пишет не в stdout/stderr. Например, настроено логирование в файл внутри контейнера. Это частая ошибка новичков. Исправляется настройкой приложения. 2. Используется другой драйвер логирования. Если контейнер запущен с драйвером syslog или fluentd, docker logs ничего не покажет . 3. Контейнер уже удалён. Если контейнер запускался с --rm, после остановки он исчезает вместе с логами.

Проверить драйвер: bash docker inspect --format='{{.HostConfig.LogConfig.Type}}' my-container

Если там не json-file и не local, docker logs вам не поможет.

Продвинутая фильтрация: таймстемпы — наше всё

Самое мощное, что есть в docker logs — фильтрация по времени .

```bash

Логи за последние 5 минут

docker logs --since 5m my-container

Логи за последние 2 часа

docker logs --since 2h my-container

Логи с конкретного момента

docker logs --since "2026-03-04T14:30:00" my-container

Логи до конкретного момента

docker logs --until "2026-03-04T15:00:00" my-container

Окно: с 14:30 до 15:00

docker logs --since "2026-03-04T14:30:00" --until "2026-03-04T15:00:00" my-container ```

Это невероятно удобно, когда ошибка случилась 10 минут назад, и вы не хотите листать тысячи строк.

Поддерживаются форматы: - RFC3339: 2026-03-04T14:30:00Z - RFC3339 с наносекундами: 2026-03-04T14:30:00.123456789Z - Относительные: 30m, 2h, 1d, 1w, 1y

Поиск и grep: джедайские техники

docker logs не умеет фильтровать по содержимому, но Unix умеет. Используем grep.

```bash

Найти все ошибки

docker logs my-container 2>&1 | grep ERROR

Найти все ошибки, игнорируя регистр

docker logs my-container 2>&1 | grep -i error

Найти все ошибки и показать контекст (2 строки до и после)

docker logs my-container 2>&1 | grep -B2 -A2 ERROR

Исключить шум

docker logs my-container 2>&1 | grep -v "health check"

Подсветка найденного

docker logs my-container 2>&1 | grep --color=always ERROR

Следить и фильтровать одновременно

docker logs -f my-container 2>&1 | grep --line-buffered ERROR ```

Флаг --line-buffered критически важен для grep в реальном времени — без него вывод может буферизоваться и приходить пачками, а не мгновенно.

Если grep сложный, используем awk

```bash

Вывести только время и сообщение об ошибке

docker logs my-container 2>&1 | awk '/ERROR/ {print $1, $2, $NF}'

Посчитать количество ошибок по типам

docker logs my-container 2>&1 | awk '/ERROR/ {count[$NF]++} END {for (e in count) print e, count[e]}' ```

Работа с несколькими контейнерами

Когда сервисов много, хочется видеть всё сразу.

Docker Compose

Если контейнеры описаны в docker-compose.yml:

```bash

Логи всех сервисов

docker-compose logs

Логи всех сервисов, последние 100 строк

docker-compose logs --tail=100

В реальном времени

docker-compose logs -f

Логи конкретного сервиса

docker-compose logs web ```

Несколько контейнеров без Compose

```bash

Логи всех запущенных контейнеров (как получится)

docker logs $(docker ps -q)

С именами контейнеров для ясности

for c in $(docker ps -q); do echo "=== $c ===" docker logs --tail 10 $c done ```

multitail для Docker

Есть специальная утилита docker-multitail, но можно обойтись стандартным multitail:

bash multitail -l 'docker logs -f container1' -l 'docker logs -f container2'

Форматирование вывода: когда нужно больше деталей

Иногда стандартного docker logs мало. Хочется видеть имя контейнера, его ID, временные метки. Тут помогает шаблонизация.

Шаблоны в docker inspect

Узнать путь к файлу с логами на хосте: bash docker inspect --format='{{.LogPath}}' my-container

docker logs --details

Если контейнеру при запуске передавались --log-opt с тегами, их можно показать:

bash docker logs --details my-container

Использование docker events

Для отладки можно смотреть события самого Docker:

bash docker events --filter 'container=my-container'

Но это про события (старт, стоп, смерть), а не про логи приложения.

Цветной вывод: чтобы глаза не болели

Чёрно-белые логи утомляют. Давайте добавим цвета.

Самый простой способ — через grep

```bash

Подсветка всех вхождений ERROR красным

docker logs -f my-container | grep --color=always -E "ERROR|$" ```

Хитрость с |$ заставляет grep выводить все строки, но подсвечивать только ERROR.

Используем ccze

Если установить ccze, можно получить красивую раскраску:

bash docker logs my-container | ccze -A

Используем multitail с цветами

multitail умеет раскрашивать по паттернам:

bash multitail -c /var/lib/docker/containers/*/*-json.log

Работа с большими логами: когда всё плохо

Бывает, что контейнер навалил столько логов, что docker logs виснет или выдаёт мегабайты текста.

Стратегия 1: не используйте docker logs

Обращайтесь напрямую к файлу:

```bash

Получаем путь к файлу лога

LOG_PATH=$(docker inspect --format='{{.LogPath}}' my-container)

Смотрим последние 100 строк

tail -n 100 $LOG_PATH

Ищем ошибки

grep ERROR $LOG_PATH

Следим

tail -f $LOG_PATH ```

Это быстрее, потому что минуется прослойка Docker.

Стратегия 2: пагинация через less

bash docker logs my-container | less

В less можно искать, листать, и это не повесит терминал.

Стратегия 3: экспорт в файл

bash docker logs my-container > /tmp/my-container.log

Потом можно анализировать любимыми инструментами.

Интерактивная отладка: логи + процесс

Иногда нужно не просто смотреть логи, а одновременно видеть, что происходит с контейнером.

docker attach

Команда docker attach подключает ваш терминал к консоли контейнера — вы видите логи и можете отправлять сигналы (Ctrl+C остановит контейнер!).

bash docker attach my-container

Внимание: если нажать Ctrl+C, сигнал уйдёт в контейнер. Если хотите просто отсоединиться, нажмите Ctrl+P Ctrl+Q.

docker exec для диагностики

Пока смотрите логи, можно залезть внутрь и посмотреть процессы:

```bash

В одном терминале

docker logs -f my-container

В другом

docker exec -it my-container ps aux ```

Сравнение логов разных версий контейнера

При обновлении версии образа полезно сравнить логи до и после.

```bash

Логи старого контейнера (ещё живого)

docker logs old-container > old.log

Логи нового

docker logs new-container > new.log

Сравниваем

diff -u old.log new.log | less ```

Частые сценарии и их решения

Сценарий 1: Контейнер постоянно перезапускается и быстро падает

```bash

Смотрим последние строки перед смертью

docker logs --tail 50 --timestamps my-container

Если контейнера уже нет, но он не удалён

docker logs --tail 50 my-container

Если контейнер удаляется, используем --rm, логи потеряны — меняем политику

```

Лучшее решение: временно убрать --rm, запустить контейнер без него, дать упасть, потом посмотреть логи.

Сценарий 2: Логов слишком много, глаза разбегаются

```bash

Оставляем только ошибки и предупреждения

docker logs my-container 2>&1 | grep -E "ERROR|WARN|FATAL"

Считаем частоту ошибок

docker logs my-container 2>&1 | grep ERROR | awk '{print $NF}' | sort | uniq -c | sort -rn ```

Сценарий 3: Нужно понять, что было до ошибки

```bash

10 строк до и после каждого вхождения ERROR

docker logs my-container 2>&1 | grep -B10 -A10 ERROR | less ```

Сценарий 4: Логи в реальном времени, но только интересное

bash docker logs -f my-container 2>&1 | while read line; do if [[ "$line" == *"ERROR"* ]] || [[ "$line" == *"Exception"* ]]; then echo "$(date +%H:%M:%S) $line" fi done

Сценарий 5: Мониторинг нескольких контейнеров в реальном времени

Скрипт, который показывает логи всех контейнеров с префиксом:

```bash

!/bin/bash

for c in $(docker ps -q); do name=$(docker inspect --format='{{.Name}}' $c | sed 's/\///') docker logs -f $c 2>&1 | sed "s/^/[$name] /" & done wait ```

Логи и деплой: что делать перед обновлением

Перед тем как обновлять контейнер, сохраните логи старой версии:

bash docker logs my-app > my-app-$(date +%Y%m%d-%H%M%S).log

Если после обновления всё сломалось, у вас будет с чем сравнивать.

Производительность: сколько можно смотреть

docker logs -f практически не грузит систему, если контейнер пишет немного. Но если логов миллион строк в минуту, даже простой вывод в терминал может загрузить процессор.

В таких случаях: - Используйте фильтры - Не выводите в терминал, пишите в файл - Используйте прямой доступ к файлам

Типичные ошибки при работе с docker logs

Ошибка 1: Забыть про 2>&1

```bash

Так вы увидите только stdout, stderr потеряется

docker logs my-container | grep ERROR

Надо так

docker logs my-container 2>&1 | grep ERROR ```

Ошибка 2: Ждать мгновенной реакции от grep без --line-buffered

```bash

Неправильно — вывод будет пачками

docker logs -f my-container | grep ERROR

Правильно

docker logs -f my-container | grep --line-buffered ERROR ```

Ошибка 3: Пытаться открыть гигабайтный лог в less без ограничений

```bash

Плохо — less загрузит всё

docker logs huge-container | less

Хорошо — только последние 1000 строк

docker logs --tail 1000 huge-container | less ```

Ошибка 4: Игнорировать таймстемпы при расследовании

Всегда используйте --timestamps, чтобы понимать хронологию.

Ошибка 5: Не проверять драйвер логирования

Убедитесь, что docker logs вообще может работать с этим контейнером.

Коротко: шпаргалка

| Задача | Команда | |--------|---------| | Последние N строк | docker logs --tail N контейнер | | Следить в реальном времени | docker logs -f контейнер | | С определённого времени | docker logs --since 10m контейнер | | До определённого времени | docker logs --until 2026-03-04T15:00 контейнер | | С таймстемпами | docker logs -t контейнер | | Найти ошибки | docker logs контейнер 2>&1 \| grep ERROR | | Найти ошибки и следить | docker logs -f контейнер 2>&1 \| grep --line-buffered ERROR | | Получить путь к файлу лога | docker inspect --format='{{.LogPath}}' контейнер | | Логи всех сервисов в compose | docker-compose logs -f |

Вместо заключения

docker logs — это, пожалуй, самая часто используемая команда при работе с контейнерами. И при этом самая недооценённая. Многие знают только docker logs -f и на этом останавливаются.

А ведь умение быстро вытащить логи за нужный промежуток, отфильтровать лишнее, подсветить важное — это разница между "я ищу ошибку час" и "я нашёл ошибку за минуту".

Освойте эти приёмы. Они не сложные, но каждый из них экономит время. А время, как известно, единственный невосполнимый ресурс.