Как определить причину кратковременных сбоев, если к моменту расследования всё уже работает

8 минут чтения
Средний рейтинг статьи — 4.8

Одна из самых неприятных ситуаций для инженера — узнать, что сервис «только что не работал», когда проблема уже исчезла. Логи без очевидных ошибок, графики вернулись к норме, пользователи снова работают.

Это не редкий сценарий, а самый частый. За последние 12 месяцев в Statuser закрылось около 115 тысяч инцидентов, и почти половина из них — 48% — длились меньше пяти минут, две трети уложились в десять. Медиана — примерно пять минут. Оговорка о методике: длительность считается по результатам проверок, а шаг у большинства мониторов пятиминутный, поэтому реальная продолжительность самых коротких сбоев может быть ещё меньше измеренной.

Другими словами, типичный сбой заканчивается раньше, чем человек успевает открыть графики. Разберём, где остаются следы такого инцидента и что настроить заранее, чтобы следующий не остался загадкой.

Почему короткий сбой почти не оставляет следов

Дело не в том, что данных нет. Дело в том, что они усредняются и удаляются раньше, чем к ним обращаются:

  • Агрегация. Всплеск на 40 секунд, усреднённый до пятиминутной точки, превращается в едва заметный бугорок.
  • Ротация логов. На нагруженном сервере журнал доступа может перезаписываться несколько раз в сутки.
  • Счётчики без истории. netstat, ss и большинство статусных страниц показывают состояние на момент запроса, а не на момент сбоя.
  • Сэмплирование трассировок. Если сохраняется 1% запросов, то из сотни ошибок в трассировках останется одна — или ни одной.
  • Непостоянный journald. По умолчанию в ряде дистрибутивов журнал живёт в /run и очищается при перезагрузке.

Отсюда практическое правило: расследование короткого сбоя — это на 80% то, что было настроено до него.

Начните с точного окна времени

Формулировки «утром» или «пару минут назад» бесполезны. Нужны три значения: время начала, время восстановления и продолжительность — и всё это с указанием часового пояса, потому что метрики, логи ядра и облачная консоль легко окажутся в разных.

Дальше все запросы делаются по окну «сбой плюс-минус 15 минут»: причина почти всегда предшествует симптому.

Где следы остаются дольше всего

Даже если приложение ничего не записало, о коротком сбое обычно помнят как минимум четыре источника.

Журнал ядра. Хранит именно те события, которые приложение зафиксировать не в состоянии:

dmesg -T | grep -iE 'oom|conntrack|segfault|blocked for more than'

Строка nf_conntrack: table full, dropping packet объясняет минутную «сетевую аномалию» без единой ошибки в логах приложения, а срабатывание OOM killer — внезапный перезапуск процесса.

Systemd и journald. Показывают рестарты сервисов, в том числе автоматические:

journalctl -u app --since '2026-07-22 13:40' --until '2026-07-22 14:10'
systemctl show app -p NRestarts

Рост NRestarts — прямое доказательство того, что процесс падал, даже если в его собственных логах пусто. Подробнее о фильтрации по времени и приоритетам — в разборе работы с journalctl.

Исторические системные метрики. Пакет sysstat собирает нагрузку с шагом 10 минут и хранит её неделями — это единственные ретроспективные данные на многих серверах:

sar -q -f /var/log/sa/sa22    # очередь и load average за 22-е число
sar -n DEV -f /var/log/sa/sa22

Тот же принцип у atop: atop -r открывает запись за прошедший день с точностью до процессов, а не только до общей загрузки.

Счётчики сетевого стека. Они не сбрасываются и накапливаются с момента загрузки:

nstat -az | grep -E 'TcpExtListenDrops|TcpExtTCPSynRetrans|TcpRetransSegs'

Регулярно растущие ListenDrops означают, что очередь на приём переполнялась, и часть клиентов не получила ответа — деталь, которую видно только здесь. Подробности — в статье про мониторинг TCP-соединений.

В Kubernetes к этому набору добавляются события кластера и предыдущий контейнер: kubectl get events --sort-by=.lastTimestamp, kubectl describe pod (там будет OOMKilled или срабатывание liveness probe) и kubectl logs --previous.

Пять типичных причин коротких сбоев

Короткие инциденты повторяются гораздо чаще, чем кажется, и укладываются в небольшое число сценариев. Проверять их стоит именно в таком порядке.

  1. Перезапуск или выкатка. Rolling update, при котором graceful shutdown не отработал, обрывает соединения на несколько секунд. Проверяется по времени деплоя и счётчику рестартов.
  2. Пауза в рантайме. Длинная сборка мусора или залипший event loop выглядят снаружи как полная недоступность, а внутри — как отсутствие записей в логах за этот интервал. Пустота в логах сама по себе улика.
  3. Исчерпание пула на пике. Пул соединений с базой кончается на минуту, запросы встают в очередь, потом всё рассасывается. В логах — таймауты, а не ошибки.
  4. Сеть и DNS. Всплеск ретрансмиссий, смена маршрута, истёкший кэш DNS с медленным резолвером. Внутренние метрики приложения при этом остаются идеальными.
  5. Фоновые задания. Бэкап, ротация логов, autovacuum, тяжёлый cron. Характерный признак — сбой повторяется в одно и то же время суток или в один и тот же день недели.

Проверка на регулярность вообще самый дешёвый шаг: если наложить все инциденты за месяц на часовую сетку и увидеть пик в 03:15, дальше искать нужно не в приложении, а в расписании.

Был ли сбой вообще у пользователей

Отдельный вопрос, на который внутренние данные не отвечают: пострадали ли клиенты. Если проблема была на маршруте, у провайдера, в CDN или DNS, серверные метрики останутся в норме — сервер честно обслуживал те запросы, которые до него дошли.

Здесь помогают только независимые проверки снаружи. По истории внешнего мониторинга видно время начала и восстановления, длительность недоступности, код ответа и время отклика в момент сбоя — то есть ровно те данные, которых не хватает, чтобы сопоставить жалобу пользователя с внутренними логами.

Полезно и обратное: внешние проверки помогают отсеять ложные срабатывания — если из пяти локаций сбой видела одна, проблема была в сети между этой точкой и сервисом, а не в самом сервисе.

Что настроить заранее

Чек-лист, который превращает следующий короткий сбой из загадки в обычное расследование:

  • Шаг метрик 10–15 секунд с хранением хотя бы две недели. На пятиминутном шаге минутный сбой не виден в принципе.
  • Постоянный journald: Storage=persistent и осмысленный SystemMaxUse в /etc/systemd/journald.conf, иначе после перезагрузки следов не останется.
  • Пакет sysstat с включённым сбором — ретроспектива по CPU, диску и сети без всякого Prometheus.
  • Тайминги в логах веб-сервера ($request_time, $upstream_response_time) — по ним восстанавливается картина даже при отсутствии метрик приложения.
  • Разумная ротация логов — чтобы журнал доступа переживал хотя бы неделю.
  • Heartbeat-проверки для фоновых задач — иначе о том, что ночной cron не отработал, вы узнаете от бизнеса.
  • Внешний мониторинг с минутным интервалом — чем чаще проверки, тем точнее граница инцидента и тем меньше окно, которое придётся просматривать в логах. Как выбрать интервал, разбирали отдельно.

Частые вопросы

Стоит ли заводить алерты на сбои длительностью меньше минуты?

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

Что делать, если в логах за время сбоя вообще пусто?

Пустота — это тоже информация. Она означает, что процесс не обрабатывал запросы: пауза сборщика мусора, блокировка на диске, зависание на syscall или остановленный контейнер. Дальше проверяются журнал ядра, счётчик рестартов и метрики хоста за то же окно.

Как понять, что сбой был на стороне сети, а не сервиса?

По совпадению признаков: время ответа выросло у всех эндпоинтов сразу, ошибки видны не из всех локаций внешнего мониторинга, а на сервере растут ретрансмиссии и ListenDrops при нормальных метриках приложения.

Заключение

Кратковременные инциденты расследуются не хуже длинных — при условии, что данные до расследования дожили. Порядок действий простой: зафиксировать точное окно, снять показания с четырёх источников, которые переживают сбой (журнал ядра, systemd, sysstat, счётчики сети), проверить пять типичных сценариев и подтвердить факт недоступности внешними проверками.

Если же сервис не падал, а просто стал медленным, работает другой алгоритм — мы разобрали его в статье о расследовании деградации по метрикам.

Опубликовано 22 июля 20268 минут чтенияГригорий Чалый
Средний рейтинг статьи — 4.8

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний