Логи и диагностика на сервере: как найти причину падений
Когда сервер “падает”, это не одна проблема. Обычно это цепочка: ресурс заканчивается, сервис зависает, конфиг меняется, сеть рвётся, а дальше события фиксируются в разных местах. Чтобы найти причину падений, нужно действовать по одной схеме: зафиксировать контекст, собрать логи из нескольких источников, связать события по времени и только потом переходить к углублённой диагностике.
Ниже — практичный подход, который подходит для 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 с таймаутами)
- рост времени обработки запросов в приложении
- очереди/блокировки в логике сервиса
Убедительные признаки:
- метрики показывают рост задержек ещё до “клиентских” ошибок
- приложение перестаёт писать нормальные логи, но не завершает процесс
—
Чек-лист расследования по шагам: от первой версии до точного ответа
Ниже — компактный алгоритм, который помогает пройти путь “от симптома к причине” без пропусков.
- Зафиксируйте временное окно: от начала симптома до ближайшего подтверждённого восстановления.
- Определите тип инцидента: падение процесса, рестарт, зависание, перезагрузка, аппаратный reset.
- Соберите системные логи за окно:
- journalctl по unit сервиса
- kernel logs (dmesg/journalctl -k)
- Найдите первое “реальное” событие, а не последнюю строку перед концом:
- ошибка запуска
- проблема внешней зависимости
- убийство OOM
- ошибка файловой системы
- Сопоставьте с изменениями: деплой, конфиг, сертификаты, миграции.
- Проверьте ресурсные метрики до падения:
- память (OOM)
- диск (ENOSPC, I/O error)
- CPU (переизбыток и таймауты)
- сеть (timeout, DNS)
- Если логов недостаточно:
- ищите core dumps
- используйте strace/lsof/ss точечно
- собирайте дампы runtime при следующих повторениях
- Зафиксируйте доказательства: 3–7 строк из логов + метрика/событие системы, которые объясняют последовательность.
- После обнаружения причины проверьте воспроизводимость: иногда проблема проявляется только при конкретной нагрузке или данных.
- Только потом переходите к исправлению: правка конфигурации, лимитов, ретраев, обработчиков ошибок или восстановления целостности данных.
Такой порядок обычно быстрее, чем “читать лог глазами от начала до конца”. И он же лучше документируется для команды.
—
Итог: как быстро прийти к причине падений через логи и диагностику
Причина падений редко находится в одном файле. Чаще всего она складывается из двух вещей: системные события (ядро, systemd, ресурсы) показывают, что стало “триггером”, а прикладные логи объясняют, что именно сделал сервис в этот момент.
Начинайте с узкого окна времени, затем расширяйте назад. Первым делом ищите OOM killer, ошибки диска и сигналы о рестартах systemd. После этого переходите к прикладным stack trace и ошибкам зависимостей. Если проблема повторяется, настройте сбор core dumps и стандартный пакет логов при инциденте.
Если вы внедрите этот процесс в ежедневную практику, расследования станут короче: вы меньше времени будете тратить на догадки и больше — на конкретные доказательства, которые можно превратить в устойчивые правки.

