Поиск и устранение неисправностей: читаем логи конвейера

Рейтинг: 67.6% · 8 голосов
Подробный курс по Jenkins и CI/CD: установка и настройка, плагины и Configuration as Code, конвейеры (pipeline) и Jenkinsfile, declarative и scripted, агенты, Docker и Kubernetes, общие библиотеки на Groovy, безопасность и credentials, интеграции (SonarQube, артефакты), траблшутинг. Актуально на 2026.
Ответить
Аватара пользователя
Andrey_CICD
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Поиск и устранение неисправностей: читаем логи конвейера

Сообщение Andrey_CICD »

Оглавление курса (47)
  1. Что такое Jenkins и зачем нужен CI/CD
  2. Jenkins в 2026: версии, экосистема и сравнение с GitLab CI и GitHub Actions
  3. Архитектура Jenkins: контроллер, агенты, узлы и исполнители
  4. Установка Jenkins: пакеты, Docker и Kubernetes
  5. Первичная настройка Jenkins: мастер, плагины, пользователи
  6. Плагины Jenkins: установка, обновление и ключевой набор
  7. Configuration as Code (JCasC): настройка Jenkins декларативно
  8. Конвейеры Jenkins и Jenkinsfile: pipeline as code
  9. Scripted против Declarative: два синтаксиса конвейера
  10. Структура конвейера: node, stage, steps и первый pipeline
  11. Генератор сниппетов, запуск конвейера и Replay
  12. Типы заданий Jenkins: Freestyle, Pipeline, Multibranch и Organization
  13. Декларативный конвейер: структура pipeline, agent, stages
  14. agent, environment и переменные в конвейере
  15. tools, options, parameters и triggers в декларативном конвейере
  16. stages, parallel и matrix: организация этапов
  17. Условное выполнение when и блок post
  18. Триггеры сборки: webhook от GitHub, SCM polling и расписание
  19. Параметры сборки и пользовательский ввод
  20. Управление потоком: timeout, retry, sleep и waitUntil
  21. Параллелизм и блокировки: parallel, lock, milestone
  22. Постобработка и уведомления о результате сборки
  23. Groovy для Jenkins: основы скриптового конвейера
  24. Скриптовый конвейер: логика, циклы и функции
  25. Общие библиотеки Jenkins: Shared Libraries
  26. Подключение и загрузка общих библиотек
  27. Шаги оболочки: sh, bat, powershell и коды возврата
  28. Переменные среды, withEnv и рабочие пространства
  29. Работа с файлами, артефактами и отпечатками
  30. Сборка проектов в конвейере: Maven, Gradle, npm
  31. Качество кода: SonarQube и покрытие тестами
  32. Управление артефактами: публикация в Nexus и Artifactory
  33. Docker в Jenkins: образы как агенты сборки
  34. Сборка и публикация Docker-образов из конвейера
  35. Jenkins в Kubernetes: динамические pod-агенты
  36. Развёртывание в Kubernetes из конвейера
  37. Безопасность Jenkins: аутентификация и матрица прав
  38. Учётные данные Jenkins: credentials в конвейере
  39. Безопасность сценариев: Groovy sandbox и Vault
  40. Уведомления и отчёты: email, Slack, Telegram, HTML
  41. Blue Ocean и интерфейс Jenkins в 2026
  42. Автоматизация Jenkins: CLI, REST API и script console
  43. Поиск и устранение неисправностей: читаем логи конвейера (вы здесь)
  44. Типичные ошибки конвейера: сериализация и неутверждённый код
  45. Эксплуатация Jenkins: бэкап, обновление, масштабирование
  46. Конвертация и миграция: от Freestyle к Jenkinsfile
  47. Итог: сквозной CI/CD конвейер и Jenkins против альтернатив в 2026
Конвейер упал. Красный шарик, письмо "build failed", в чате уже спрашивают "почему не собралось". И вот тут начинается то, что отличает джуна от инженера: один паникует и жмёт Rebuild наугад, а второй открывает лог и за минуту показывает пальцем в строку, где всё сломалось. Этот урок про второй путь. Разберём системно, как читать jenkins логи, как локализовать сбой по коду возврата и как не утонуть в простыне Console Output.

Сразу о главном страхе: jenkins error 503 при заходе в интерфейс или при обращении агента к контроллеру. Это не про твой Jenkinsfile - это про сам сервер или прокси перед ним. Разберём и это тоже, потому что спрос на "почему 503" огромный, а причина почти всегда одна и та же.

Где именно упало: анатомия лога сборки

Любой troubleshooting в Jenkins начинается с одного вопроса - на каком шаге оборвалось выполнение. Конвейер declarative исполняется сверху вниз по стадиям, и в момент падения Jenkins останавливается ровно на провалившемся шаге. Твоя задача - найти эту точку.

Открывай Console Output - полный сырой лог сборки. Он линейный: команды, их вывод, служебные сообщения Jenkins. Самое полезное - искать с конца. Падение почти всегда сопровождается строкой вида:

Код: Выделить всё

+ npm run build
sh: 1: npm: not found

script returned exit code 127
Три строки - и вся картина. Знак + в начале - это echo команды от шага sh: Jenkins показывает, что именно он запустил. Ниже - вывод самой команды (stderr тоже сюда летит). И финальный приговор: script returned exit code 127. Код возврата - твой главный диагностический сигнал. Запомни базовый набор:
  • exit code 0 - успех, всё хорошо;
  • exit code 1 - generic ошибка, смотри вывод команды выше;
  • exit code 2 - часто синтаксис в bash или misuse шелла;
  • exit code 126 - файл найден, но не исполняемый (нет +x или это не бинарь);
  • exit code 127 - команда не найдена (нет инструмента в PATH);
  • exit code 137 - процесс убит сигналом 9 (128+9), почти всегда OOM - не хватило памяти;
  • exit code 143 - убит сигналом 15 (128+15), обычно таймаут или отмена сборки.
Половину инцидентов закрывает уже эта таблица. Видишь 127 - инструмента нет на агенте. Видишь 137 - агенту мало памяти, особенно актуально для эфемерных pod-агентов в Kubernetes, где ты сам задаёшь resources.limits.memory. Видишь 143 - кто-то отменил или сработал timeout.

В Pipeline лог Jenkins заботливо разбивает на сворачиваемые блоки по стадиям и шагам - это представление Pipeline Steps (старый Pipeline Steps view плюс встроенная подсветка стадий в современном UI). Провалившаяся стадия подсвечена красным, можно сразу провалиться внутрь и увидеть лог конкретного шага, не листая весь Console Output. На больших конвейерах это экономит минуты.

Изображение

Jenkins build failed: типичные причины и как их опознать

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

Команда вернула ненулевой код. Базовый случай. Шаг sh падает, если процесс завершился не нулём. Лог покажет вывод и exit code. Лечится починкой самой команды. Подводный камень: пайп. В строке

Код: Выделить всё

sh 'cat file | grep foo'
по умолчанию код возврата берётся от последней команды пайпа. Если хочешь ловить падение любого звена - включай pipefail явно.

Не найден инструмент или агент. Сигнатура - exit code 127 и "not found", либо сборка вечно висит в очереди с надписью про отсутствие подходящего агента. Первое - проблема окружения агента (нет node, docker, jdk), второе - неправильный label в директиве agent. Проверь, что лейбл в Jenkinsfile реально существует на каком-то агенте.

Нет прав. "Permission denied", exit code 126 или 13. Частая боль - доступ к docker.sock внутри агента или запись в чужую директорию. В Kubernetes сюда же относятся отказы RBAC service account.

Таймаут. Сборка обрывается по времени с явным сообщением про timeout. Это не баг, а твоя же директива options { timeout(...) }, отрабатывающая по плану. Если таймаут ложный - команда реально медленная, не вешай костыль, разбирайся с причиной.

Проблема с кредами. Самое коварное, потому что Jenkins маскирует секреты в логе звёздочками, и ты видишь "authentication failed" без значения. Признаки: 401/403 от registry или git, "could not read Username", "Bad credentials". Проверяй ID credentials в блоке environment и то, что биндинг реально подставился.

Вот компактный пример с диагностикой, который ловит и логирует код возврата руками, не давая Jenkins молча упасть:

Код: Выделить всё

pipeline {
    agent { label 'linux' }
    options {
        timeout(time: 15, unit: 'MINUTES')
        timestamps()
    }
    environment {
        REG = credentials('docker-registry-creds')
    }
    stages {
        stage('Build') {
            steps {
                script {
                    def code = sh(
                        script: 'set -o pipefail; npm ci && npm run build 2>&1 | tee build.log',
                        returnStatus: true
                    )
                    if (code != 0) {
                        echo "Шаг сборки упал, exit code ${code}"
                        sh 'tail -n 40 build.log || true'
                        error("Build failed with code ${code}")
                    }
                }
            }
        }
    }
    post {
        failure {
            archiveArtifacts artifacts: 'build.log', allowEmptyArchive: true
        }
    }
}
Здесь returnStatus: true возвращает код вместо немедленного падения, мы его логируем, выводим хвост лога и архивируем артефакт даже при провале через post { failure }. Это превращает невнятное "build failed" в понятный отчёт.

Временные метки, системные журналы и воспроизведение через Replay

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

Временные метки (timestamps). По умолчанию строки лога без времени, и понять "что тут зависло на 8 минут" невозможно. Опция timestamps() из плагина Timestamper добавляет к каждой строке отметку времени. Включается на конвейер в options или глобально для всех сборок. После этого в логе видно

Код: Выделить всё

[2026-06-15T10:42:13.880Z]
перед строкой, и затыки находятся глазами за секунды.

Системные журналы Jenkins. Если проблема не в твоём коде, а в самом Jenkins - смотри Manage Jenkins -> System Log. Это внутренние логи контроллера: ошибки плагинов, отвалы агентов, проблемы с потоками. На сервере те же события пишутся в обычный лог процесса. Под systemd достаточно:

Код: Выделить всё

journalctl -u jenkins -f --since "10 min ago"
И вот здесь живёт тот самый jenkins error 503. Если интерфейс отдаёт 503 Service Unavailable, в 99% случаев это не Jenkins сломался, а reverse proxy (nginx) перед ним не дождался ответа от ещё стартующего или перегруженного Jenkins. Типичная картина после рестарта: nginx уже принимает соединения, а Jenkins ещё разворачивает плагины. Смотри лог nginx и сам Jenkins одновременно:

Код: Выделить всё

# в логе nginx
upstream prematurely closed connection ... 503

# в это же время в journalctl jenkins
Jenkins is fully up and running   <- появится позже
Лечится тремя вещами: дождаться полной загрузки (строка "fully up and running"), поднять proxy_read_timeout в nginx, проверить heap - если контроллеру не хватает памяти и идёт постоянный GC, он отвечает медленно и прокси отдаёт 503. Память контроллера и есть корень большинства долгих 503.

Воспроизведение через Replay. Лучший инструмент отладки самого Jenkinsfile. В меню сборки слева есть Replay - он открывает редактор с тем же самым сценарием, что выполнялся, ты правишь любую строку и запускаешь заново, не делая коммит в git. Идеально для отладки сломанной логики: добавил echo, поменял команду, прогнал, повторил. Replay работает и на падавших сборках, и итеративно сколько угодно раз. Когда нашёл рабочий вариант - переносишь правку в репозиторий уже осознанно.

Отдельный навык - поиск строки сценария, вызвавшей ошибку. Если упал не sh, а сам Groovy (например, обращение к null), Jenkins выдаёт stack trace, и в нём есть строки вида

Код: Выделить всё

at WorkflowScript.run(WorkflowScript:23)
. Число 23 - это номер строки в твоём Jenkinsfile (как его видит Pipeline, то есть в Replay-редакторе нумерация совпадает). Открываешь Replay, идёшь на строку 23 - вот она, виновница.

Грабли, мини-лаба и контрольные вопросы

Типичные грабли при чтении логов:
  • Маскировка секретов сбивает с толку - "***" в логе это не баг, Jenkins прячет credentials. Не ищи там реальное значение, проверяй сам биндинг.
  • sh без pipefail прячет падение в середине пайпа - сборка зелёная, а на деле сломалась. Всегда set -o pipefail для критичных пайпов.
  • Лог стадии в Pipeline Steps и общий Console Output - это одно и то же, но в разной нарезке. Не паникуй, что "логи разные".
  • exit code 137 списывают на флапающий тест, а это OOM. Проверь memory limit агента, особенно в Kubernetes.
  • Номер строки из stack trace относится к Jenkinsfile в его исполняемом виде, а не к твоему файлу с комментариями - сверяйся через Replay, там нумерация честная.
  • 503 при заходе путают с упавшей сборкой. 503 - это слой инфраструктуры (proxy + старт + память контроллера), а не твой pipeline.
Мини-лаба (повтори руками):
  • Сделай заведомо падающий шаг

    Код: Выделить всё

    sh 'somecommandthatdoesnotexist'
    и найди в Console Output строку с exit code. Какой код?
  • Включи timestamps() в options и сравни лог до и после - где видны паузы.
  • Вставь в шаг искусственный sleep на минуту и под timeout(time: 30, unit: 'SECONDS') поймай код 143 в логе.
  • Открой Replay, добавь echo перед падающим шагом, запусти и убедись, что коммита в git не было.
  • Зайди в Manage Jenkins -> System Log и найди записи о старте последней сборки.
Контрольные вопросы:
  • Какой exit code говорит "команда не найдена", а какой - "процесс убит по нехватке памяти"?
  • Чем Replay отличается от обычного Rebuild и почему он удобнее для отладки Jenkinsfile?
  • Где смотреть причину, если jenkins error 503 не пускает в интерфейс - в логе сборки или где-то ещё?
  • Зачем нужен set -o pipefail и какую ошибку он помогает не пропустить?
Итог

Чтение логов - это не магия, а алгоритм: открыл Console Output, прокрутил в конец, нашёл exit code, по коду понял класс проблемы, по строке stack trace нашёл место в сценарии, через Replay починил без коммита. Системные журналы и timestamps подключаешь, когда сбой не в коде, а в инфраструктуре. А 503 запомни как отдельную категорию - это почти всегда proxy и память контроллера, а не твой конвейер. Освой этот маршрут до автоматизма, и любой jenkins build failed превращается из паники в пятиминутную диагностику.
👍2 ❤️3 🔥1 😄 🤔5
Аватара пользователя
whisp
Сообщения: 1
Зарегистрирован: 31 май 2026, 01:40

Re: Поиск и устранение неисправностей: читаем логи конвейера

Сообщение whisp »

Спасибо, таблица exit code прямо на стену повесить. Сегодня словил 137 на k8s-агенте, поднял memory limit и собралось. Раньше реально думал что тесты флапают.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
Rotinflames
Сообщения: 1
Зарегистрирован: 08 июн 2026, 06:31

Re: Поиск и устранение неисправностей: читаем логи конвейера

Сообщение Rotinflames »

А Replay сохраняет правку если потом сборку перезапустить через Rebuild, или каждый раз заново вставлять? И работает ли он, если Jenkinsfile тянется из shared library?
👍 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Автоматизация Jenkins: CLI, REST API и script console
Следующая глава →
Типичные ошибки конвейера: сериализация и неутверждённый код

Все главы курса «Jenkins: конвейеры CI/CD от основ до продакшена»

Поделиться темой: ✈ Telegram VK
Похожие запросы: groovy в jenkins scripted pipeline как написатьпараметры и параллельные стейджи в jenkins pipelineструктура declarative pipeline в jenkins: stages, agent, steps

Вернуться в «Jenkins: конвейеры CI/CD от основ до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость