Логи на сервере и диагностика: как найти причины падений

Логи на сервере и диагностика: как найти причины падений

Логи и диагностика на сервере: как найти причину падений

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

Ниже — практичный подход, который подходит для Linux-серверов с systemd и типичными сервисами (веб, очереди, базы, фоновые процессы). Если у вас другая платформа, принципы всё равно сохраняются: смотреть логи системы, логи приложения и признаки нагрузки.

Определите, что именно “упало”: падение процесса, зависание или перезагрузка

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

Соберите базовые ответы:

  • Что произошло: процесс завершился, сервис рестартнулся, сервер перезагрузился, узел стал недоступен?
  • Когда это началось и когда закончилось (точный таймштамп важнее слов “примерно”).
  • Какой компонент пострадал: nginx, приложение, база, агент, очередь, планировщик.
  • Есть ли паттерн: только в пике нагрузки, после деплоя, по расписанию, только на одном сервере.

Если проблема повторяется, фиксируйте ещё и последовательность событий: “сначала выросла задержка, потом 5xx, затем сервис умер”. Это потом ускорит поиск в логах.

Соберите контекст до анализа логов: таймзона, версии и изменения

Логи могут запутывать из‑за банальных причин: рассинхрон времени, разные таймзоны, изменения конфигурации или версии бинарника.

Сделайте минимальную “подготовку”:

  • Проверьте системное время и синхронизацию: если NTP/chrony ломались, таймштампы в разных источниках будут расходиться.
  • Зафиксируйте версию сервиса и время деплоя/конфиг‑маппинга.
  • Определите пользователя и права, от имени которых работает сервис (это влияет на доступ к файлам, сокетам, ключам).

Практическое наблюдение: чаще всего причина падений лежит в изменениях за 1–3 часа до инцидента. Это не правило “всегда”, но хорошая рабочая гипотеза.

Системные логи: где искать причину падений на уровне ОС

Если процесс “умирает”, ОС почти всегда оставляет след. На Linux базовые источники — journald/systemd, syslog и kernel ring buffer.

systemd-journald: сообщения сервисов, статусы рестартов и ошибки

Для большинства серверов с systemd самый полезный старт — journalctl.

Типовые запросы по времени: «`bash journalctl —since «2026-05-04 12:00:00» —until «2026-05-04 12:20:00» «`

Чтобы точнее сузить поиск, используйте единицу systemd (например, имя сервиса): «`bash journalctl -u myapp.service —since «2026-05-04 12:00:00» —until «2026-05-04 12:20:00» «`

Обратите внимание на строки вокруг моментов:

  • “Starting … / Started …”
  • “Stopping … / Stopped …”
  • “Main process exited …”
  • “Service restart scheduled…”
  • ошибки модулей (например, systemd-resolved, sshd, nginx)

Если сервис рестартится по кругу, это обычно видно по сериям сообщений за короткий промежуток. В таких случаях “первое падение” и “первая ошибка” важнее, чем последнее.

syslog и отдельные демоны

В некоторых системах часть сообщений пишется в /var/log/syslog или /var/log/messages (или через rsyslog).

Проверьте:

  • есть ли файлы syslog и как они роутятся;
  • доступны ли ротации (нужные записи могли оказаться в .1/.gz).

Например: «`bash grep -R «2026-05-04 12:0» /var/log/syslog* «`

Не пытайтесь прочитать весь лог глазами. Лучше сначала определить тип события и уже потом расширять окно поиска.

kernel logs (dmesg): OOM killer, диски, драйверы, тайминги

Kernel ring buffer помогает, когда падение связано с железом или ресурсами.

Смотрите “всё важное” прямо за время инцидента: «`bash

  • dmesg —ctime: grep -iE «oom; killed process; ext4; nvme; error; fail; i/o; reset; watchdog»

«`

Иногда причина падений действительно “лежит” в ядре:

  • OOM killer (убийство процесса из-за нехватки памяти)
  • ошибки диска/контроллера NVMe/SATA
  • watchdog reset, аппаратные ошибки
  • проблемы с драйверами или интерфейсами

Если dmesg не хранит нужную историю (маленький ring buffer, перезагрузка), переходите к более долгим источникам: journald с kernel.* или системным отчётам.

journalctl по категориям ядра

В journald kernel сообщения маркируются как kernel, иногда с подсказками уровня.

Попробуйте: «`bash journalctl -k —since «2026-05-04 12:00:00» —until «2026-05-04 12:20:00» «`

И параллельно по конкретным паттернам:

  • oom
  • watchdog
  • i/o error
  • nvme
  • ext4
  • netlink
  • link down/up

Логи приложения и сервиса: как добраться до “истины” за ошибкой

Системные логи покажут, что процесс завершился. Но причина обычно прячется в прикладных логах: исключение, таймаут, отказ от подключения к БД, неверная конфигурация, ошибка сериализации.

Где обычно лежат прикладные логи

Варианты зависят от того, как сервис запускается:

  • в journald (если stdout/stderr направлены туда через systemd)
  • в отдельных файлах (например, /var/log/myapp/app.log)
  • в логах контейнера (если Docker/Kubernetes)
  • в stdout/stderr, но забираются агентом (fluent-bit, filebeat)

Если вы используете systemd, чаще всего проще начать с journalctl для unit сервиса: «`bash journalctl -u myapp.service —since «…» —no-pager «`

Если приложение пишет в файл, привяжитесь к точному времени: «`bash tail -n 200 /var/log/myapp/app.log

затем: меньше окно, больше точность

sed -n ‘/2026-05-04 12:00/,/2026-05-04 12:20/p’ /var/log/myapp/app.log «`

Важное правило: не ищите “последнюю” ошибку. Ищите первую ошибку, которая началась до момента падения и логически ведёт к ней.

Как читать stack trace и отличать “симптом” от “причины”

Стек вызовов часто содержит:

  • корневое исключение (root cause) с сообщением;
  • каскад “переупаковок” (вызовы оборачиваются друг в друга).

Обычно полезнее искать:

  • “Caused by” / “Root cause” (если язык/фреймворк это поддерживает)
  • сообщения уровня error непосредственно перед падением
  • ошибки конфигурации (“failed to bind”, “cannot open file”, “permission denied”)
  • ошибки внешних зависимостей (“connection refused”, “timeout”, “authentication failed”)

Типичная ловушка: видеть в конце “broken pipe” или “client disconnected” и считать это причиной падения. Часто это просто следствие того, что приложение уже сломалось раньше.

Проверка конфигов и миграций: “работало вчера, сломалось сегодня”

Если падение совпало с деплоем, полезно проверить:

  • какие файлы конфигурации подменились;
  • нет ли несовместимости версии (например, новый формат таблицы/очереди);
  • корректность переменных окружения.

Практический метод: сравните конфиги из “рабочего” и “проблемного” времени, особенно если конфиги обновлялись автоматически.

Метрики и ресурсные признаки: CPU, память, диск и сеть

Логи отвечают на вопрос “что было написано”. Метрики отвечают на “почему это произошло”. Для поиска причины падений ресурсные признаки часто важнее текста исключения.

Память и OOM killer: самая частая причина “внезапных” смертей

Если процесс резко завершился без явного exception, проверьте память и наличие убийств.

Что искать в kernel/journal:

  • “Out of memory”
  • “Killed process”
  • SIGKILL вместо нормального завершения

Дополнительно проверьте:

  • свободное место swap (иногда его нет или он не помогает)
  • лимиты cgroup (если сервис в контейнере, ограничение может быть ниже, чем ожидается)

В системе:

  • если память “проседает” перед падением, почти всегда это основная версия причины
  • если память стабильна, смотрим дальше по логам зависимостей

Диск: заполнение, ошибки файловой системы, I/O stalls

Диск может ломать приложение тихо и постепенно. Симптомы:

  • приложение не может записать кэш, лог, временные файлы
  • база “зависает” на операциях
  • сервисы начинают рестартиться из‑за отказа писать на диск

Ищите признаки:

  • “No space left on device”
  • “read-only file system”
  • ошибки ext4/xfs в kernel logs
  • рост задержек на диске (если мониторинг есть)

Если у вас есть доступ к метрикам, проверьте:

  • процент занятого пространства на нужных разделах
  • рост latency для диска
  • ошибки в iostat/smart (если доступно)

CPU и таймауты: зависание из-за перегрузки

Высокий CPU сам по себе не всегда причина. Но он часто ведёт к каскаду:

  • потоки заканчиваются, таймауты растут
  • очередь задач переполняется
  • внешний API отвечает медленнее
  • приложение накапливает ресурсы и падает

В логах это может проявляться как серии таймаутов к зависимым сервисам или как “request queue is full”.

Сеть: разрывы, DNS, проблемы с портами

Сеть часто создаёт “падения через зависимости”. Примеры:

  • “connection refused” (служба не слушает порт)
  • “timeout” (нет маршрута/файрвол/плохая деградация)
  • проблемы DNS (NXDOMAIN, SERVFAIL)
  • ошибки TLS/сертификатов (если истёк срок)

При этом важно отличить:

  • падение из‑за сетевой ошибки (приложение не умеет деградировать)
  • падение независимо от сети, а сеть уже вторичным эффектом

Для уточнения смотрите порядок событий по времени: что началось раньше.

Дампы, трассировка и “снимки” процесса: диагностика после или во время проблемы

Иногда логов недостаточно: процесс падает без информативного сообщения или падает только под нагрузкой. Тогда помогают дампы и инструментальная диагностика.

Core dumps: когда нужен post-mortem разбор

Если приложение падает с segfault/abort, core dump может дать точный стек. Проверьте, включены ли core dumps:

  • лимит ulimit для systemd сервиса
  • настройки ядра (fs.suid_dumpable и подобные параметры)
  • наличие каталогов и прав на запись

На стороне systemd это может требовать настройки для unit файла, чтобы core dump сохранялся.

Если дампы есть, используйте анализатор:

  • gdb для C/C++
  • специализированные инструменты для конкретных runtime

Здесь ключевой момент: core dump даёт “где” и “что” сломалось, а логи — “почему могли дойти до этого”.

Стек из журналов и runtime logs

Для managed‑языков полезны:

  • JVM heap/thread dumps
  • .NET crash dumps
  • пулы ошибок runtime (например, записи о GC, отказе аллокатора, загрузке классов)

Если вы не собираете дампы в момент падений, в будущем расследование будет сильно дольше.

Инструменты “по месту”: strace, lsof, ss, perf

Когда падение связано с системными вызовами или зависанием, помогают:

  • strace: увидеть, на каких вызовах процесс “залип” или с чем падает
  • lsof: какие файлы/сокеты реально открыты
  • ss: какие соединения открыты и в каком состоянии
  • perf/top: куда уходит CPU
  • tcpdump: если нужно понять, что именно происходит на уровне пакетов (обычно только точечно)

Пример сценария с strace (подходит, если процесс ещё жив): «`bash strace -ff -p <pid> -s 200 -o /tmp/strace.out «`

Дальше вы ищете паттерны:

  • повторяющиеся таймауты на connect/read
  • ожидание на futex/clock_nanosleep (зависание)
  • EACCES/EPERM (права)
  • ENOSPC (диск)
  • попытки открыть файл, который не существует или недоступен

Иногда достаточно 30–60 секунд трассировки в проблемном состоянии, чтобы понять направление.

Автоматизация сбора логов: чтобы расследование не зависело от внимательности

Ручной поиск в журналах быстро становится хаотичным. Если вы хотите стабильно находить причины падений, нужна привычка и небольшой “набор” команд/скриптов.

Соберите стандартный пакет при инциденте

Пакет должен включать:

  • системные события: journald за окно вокруг падения
  • kernel logs за то же окно
  • логи приложения за то же окно
  • список рестартов systemd (если был)
  • состояние дисков (хотя бы df -h и сообщения об ошибках)
  • состояние памяти (например, free -m в момент до/после)

Если у вас есть мониторинг, добавьте snapshot метрик (CPU/RAM/Disk/Network) за период до падения.

Корреляция по времени: главный способ связать всё в одну картину

Чаще всего разные логи используют разные форматы и иногда разные таймзоны. Правило простое:

  • берите одно и то же временное окно
  • расширяйте окно назад на 30–120 минут, если падение “внезапное”
  • смотрите сначала на то, что произошло раньше (например, рост ошибок внешней зависимости)

Когда вы видите “в 12:03 сервис потерял соединение”, а “в 12:04 он упал”, вы почти всегда найдёте мостик между событиями в логах.

Архивируйте, а не только смотрите

Если сервер перезагрузился, часть источников может исчезнуть (например, ring buffer dmesg). Поэтому при повторяющихся инцидентах полезно сохранять:

  • вывод journalctl (лучше в файл)
  • ключевые секции логов приложения
  • логи kernel за окно

Это экономит время на следующей попытке расследования.

Типичные причины падений и быстрые сценарии проверки

Ниже — набор частых сценариев, которые встречаются в реальных инцидентах. В каждом сценарии есть “быстрая проверка” и что считать убедительным доказательством.

Сценарий 1: сервис рестартится и затем падает из-за конфигурации или зависимостей

Быстрая проверка:

  • journalctl -u <service> за окно падения
  • поиск строк “failed”, “cannot”, “permission”, “bind”, “configuration”
  • совпадение по времени с деплоем

Убедительные признаки:

  • “Main process exited” с конкретной ошибкой
  • ошибки подключения к БД/очереди/API с таймаутами и ретраями
  • ошибки сертификатов TLS

Сценарий 2: OOM killer — процесс убили из-за памяти

Быстрая проверка:

  • kernel/journald по “oom” и “killed process”
  • метрики памяти до инцидента
  • наличие/отсутствие swap и ограничений cgroup

Убедительные признаки:

  • строка об Out of memory в kernel logs
  • резкое завершение без информативного stack trace приложения

Частая ошибка: “мы поставили лимит, значит всё ок”. На деле лимит может быть ниже реального потребления на пики, или приложение держит память “всплесками” при загрузке.

Сценарий 3: “Нет места на диске” ломает запись логов и временных данных

Быстрая проверка:

  • поиск “No space left on device” в логах
  • df -h для раздела, куда пишет приложение
  • наличие переполненных каталогов temp/cache

Убедительные признаки:

  • приложение падает после попытки записать файл
  • в логе есть ошибки записи или ошибки файловой системы

Частая ошибка: смотреть только общий df -h “на сервере”. Часто проблема в конкретном mount point, где лежат логи или временные файлы.

Сценарий 4: проблемы файловой системы: read-only, повреждения, флап диска

Быстрая проверка:

  • kernel logs по ext4/xfs “error”, “I/O error”, “remount-ro”
  • SMART/контроллер (если доступно)
  • наличие watchdog reset

Убедительные признаки:

  • remount-ro
  • серия I/O ошибок рядом по времени с падениями сервисов

Сценарий 5: сеть и DNS: приложение не переживает отказ и падает

Быстрая проверка:

  • lsof/ss на момент проблемы (если процесс жив)
  • логи с “timeout”, “connection refused”, “SERVFAIL”
  • события на уровне системы (если sshd/resolve/resolved тоже страдают)

Убедительные признаки:

  • ошибки внешней зависимости появляются раньше падения
  • после падения зависимость недоступна или DNS нестабилен

Частая ошибка: считать, что падение вызвано внешним сервисом, а не нашим обработчиком ошибок. Иногда достаточно улучшить ретраи, добавить timeouts и fallback.

Сценарий 6: зависание вместо падения

Если процесс не завершился, но сервер “не отвечает”, ищите признаки зависания:

  • высокий CPU или нулевой прогресс
  • активные ожидания в strace (futex, read с таймаутами)
  • рост времени обработки запросов в приложении
  • очереди/блокировки в логике сервиса

Убедительные признаки:

  • метрики показывают рост задержек ещё до “клиентских” ошибок
  • приложение перестаёт писать нормальные логи, но не завершает процесс

Чек-лист расследования по шагам: от первой версии до точного ответа

Ниже — компактный алгоритм, который помогает пройти путь “от симптома к причине” без пропусков.

  1. Зафиксируйте временное окно: от начала симптома до ближайшего подтверждённого восстановления.
  2. Определите тип инцидента: падение процесса, рестарт, зависание, перезагрузка, аппаратный reset.
  3. Соберите системные логи за окно:
  4. journalctl по unit сервиса
  5. kernel logs (dmesg/journalctl -k)
  6. Найдите первое “реальное” событие, а не последнюю строку перед концом:
  7. ошибка запуска
  8. проблема внешней зависимости
  9. убийство OOM
  10. ошибка файловой системы
  11. Сопоставьте с изменениями: деплой, конфиг, сертификаты, миграции.
  12. Проверьте ресурсные метрики до падения:
  13. память (OOM)
  14. диск (ENOSPC, I/O error)
  15. CPU (переизбыток и таймауты)
  16. сеть (timeout, DNS)
  17. Если логов недостаточно:
  18. ищите core dumps
  19. используйте strace/lsof/ss точечно
  20. собирайте дампы runtime при следующих повторениях
  21. Зафиксируйте доказательства: 3–7 строк из логов + метрика/событие системы, которые объясняют последовательность.
  22. После обнаружения причины проверьте воспроизводимость: иногда проблема проявляется только при конкретной нагрузке или данных.
  23. Только потом переходите к исправлению: правка конфигурации, лимитов, ретраев, обработчиков ошибок или восстановления целостности данных.

Такой порядок обычно быстрее, чем “читать лог глазами от начала до конца”. И он же лучше документируется для команды.

Итог: как быстро прийти к причине падений через логи и диагностику

Причина падений редко находится в одном файле. Чаще всего она складывается из двух вещей: системные события (ядро, systemd, ресурсы) показывают, что стало “триггером”, а прикладные логи объясняют, что именно сделал сервис в этот момент.

Начинайте с узкого окна времени, затем расширяйте назад. Первым делом ищите OOM killer, ошибки диска и сигналы о рестартах systemd. После этого переходите к прикладным stack trace и ошибкам зависимостей. Если проблема повторяется, настройте сбор core dumps и стандартный пакет логов при инциденте.

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