JavaRush /Курсы /Spring Boot /Startup logs: карта поднятого приложения

Startup logs: карта поднятого приложения

Spring Boot
5 уровень , 4 лекция
Открыта

1. Startup logs не «шум в консоли»

К этому моменту цепочка старта уже собрана: SpringApplication.run(...) поднимает приложение, внутри него выбирается WebApplicationType, а в ветке SERVLET Boot создаёт веб-контекст и запускает embedded Tomcat. Startup logs полезны тем, что показывают весь этот маршрут снаружи. Они не открывают новую механику, а дают внешний след уже знакомого процесса.

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

В обычной Java-программе вы часто точно знаете, что происходит: вот main(), вот new, вот вызовы методов. В Spring Boot всё наоборот: вы написали совсем немного кода, а происходит много. И это нормально — Boot для этого и существует. Но за этим «много происходит» обязательно должна быть наблюдаемость: где-то же вам нужно увидеть, что приложение действительно стартовало, что оно в веб-режиме, что сервер слушает порт, что контекст успел собраться.

Startup logs — это первая и очень честная версия такой наблюдаемости. Они дают ответы на простые вопросы: какой класс стартовал, в каком режиме живёт приложение, поднялся ли встроенный сервер, на каком порту он слушает, дошли ли мы до финальной строки «Started … in … seconds». Если вы научитесь видеть эти маркеры, то перестанете относиться к запуску как к гаданию на кофейной гуще: «вроде работает… или нет…».

И ещё одна важная мысль. Логи — это не только про успех. Логи особенно полезны, когда что-то сломалось. В этом случае они превращаются в дорожные знаки: по последней «успешной» строке можно понять, на каком шаге запуск остановился. Это намного лучше, чем стратегия «добавить ещё одну аннотацию и посмотреть, что будет» — спойлер: будет грустно.

2. Разбор старта catalog-service

Чтобы логи действительно помогали, нужно знать, что именно в них искать. Мы не будем разбирать каждую строку и каждый внутренний класс Spring Boot 4 — это путь к грусти и внезапной философии. Вместо этого возьмём реальный запуск catalog-service и выделим несколько «маячков», которые быстро дают картину старта.

Ниже — сокращённый и упрощённый фрагмент типичных startup logs. В реальности строк будет больше, но смысловые маркеры очень похожи. Считайте это «картой метро», а не фотографией каждого кирпича в стене.

# Ключевые маркеры, которые стоит заметить глазами: Starting..., Tomcat started..., Started ... in ... seconds
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ... banner ... )

2026-03-19T10:00:00.120  INFO 12345 --- [main] c.e.c.CatalogServiceApplication : Starting CatalogServiceApplication using Java 25 with PID 12345
2026-03-19T10:00:00.121  INFO 12345 --- [main] c.e.c.CatalogServiceApplication : No active profile set, falling back to 1 default profile: "default"

2026-03-19T10:00:01.050  INFO 12345 --- [main] o.s.b.w.e.t.TomcatWebServer      : Tomcat initialized with port 8080 (http)
2026-03-19T10:00:01.120  INFO 12345 --- [main] o.a.catalina.core.StandardService: Starting service [Tomcat]
2026-03-19T10:00:01.330  INFO 12345 --- [main] o.s.b.w.s.c.ServletWebServerAppCtx: Root WebApplicationContext: initialization completed in 640 ms
2026-03-19T10:00:01.450  INFO 12345 --- [main] o.s.b.w.e.t.TomcatWebServer      : Tomcat started on port 8080 (http) with context path ""
2026-03-19T10:00:01.470  INFO 12345 --- [main] c.e.c.CatalogServiceApplication : Started CatalogServiceApplication in 1.52 seconds (process running for 1.70)

Теперь важный навык: не пытайтесь впитать всё сразу. В начале достаточно выучить несколько точек привязки.

Что мы хотим понять Какая строка обычно об этом говорит Как это интерпретировать
Старт вообще начался banner или первая строка Starting ... Процесс жив, Boot начал запуск
Какое приложение стартует Starting CatalogServiceApplication ... Это ваш главный класс; если не он — вы запускаете не то
Что с профилями No active profile set ... или The following profiles are active ... Это подсказка о «режиме окружения»; сейчас достаточно заметить сам факт
Есть ли веб-сервер строки про Tomcat или про другой контейнер Если они есть — приложение поднялось как веб-сервис
Контекст собрался Root WebApplicationContext: initialization completed ... Контейнер бинов дошёл до состояния «готово»
Сервер слушает порт Tomcat started on port ... Можно пытаться ходить на http://localhost:<port>
Запуск завершился успешно Started ... in ... seconds Это финальная галочка: приложение поднялось

Теперь разберём, что вообще означает «форма» одной строки. Обычно она выглядит примерно так:

# Самое полезное на старте — смотреть на <сообщение>: оно обычно содержит “маячки”
<время>  <уровень> <pid> --- [поток] <имя логгера> : <сообщение>

На старте вам важнее всего последняя часть — сообщение. Время, PID и имя логгера полезны, но они понадобятся чуть позже, когда вид логов Spring перестанет пугать.

Очень практическая привычка: вы глазами ищете в логе пары слов, а не читаете его как книгу. В нашем случае это Starting, profiles, Tomcat, port, Root WebApplicationContext, Started. Это и есть «маячки».

Banner: удобный маркер старта

Banner в Spring Boot любят по-разному: кто-то считает его милой заставкой, а кто-то — лишним ASCII-артом, который мешает жить. На самом деле баннер — просто маркер «вот тут начался запуск». Полезно понимать, что он не влияет на работу приложения и может быть отключён одним методом.

Частая ловушка новичка: «баннер показался — значит приложение работает». Увы, баннер может показаться и перед красивым падением приложения через две секунды. Поэтому баннер — это не тест успешности, а только визуальная точка «старт начался».

Если вам хочется сделать логи компактнее — например, когда вы десятый раз перезапускаете приложение и уже знаете этот ASCII-арт наизусть, — баннер можно отключить прямо в main() через объект SpringApplication.

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;

public static void main(String[] args) {
    // Фрагмент внутри вашего главного класса приложения (например, CatalogServiceApplication)
    SpringApplication app = new SpringApplication(CatalogServiceApplication.class);

    // Отключаем ASCII-баннер: это влияет только на вывод в консоль, не на работу приложения
    app.setBannerMode(Banner.Mode.OFF);

    // Запускаем приложение (после этого в логах сразу пойдут строки Starting...)
    app.run(args);
}

После этого стартовые логи будут начинаться сразу со строк Starting .... То есть «информации» в логах не станет меньше — просто исчезнет декоративная часть. Примерно так:

2026-03-19T10:10:00.120  INFO ... : Starting CatalogServiceApplication using Java 25 with PID 12345
2026-03-19T10:10:00.121  INFO ... : No active profile set, falling back to 1 default profile: "default"
...

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

3. Tomcat и порт в логах

В servlet-ветке встроенный сервер живёт внутри того же процесса, и это обязательно отражается в startup logs. Теперь закрепим это глазами: по каким строкам понять, что сервер не просто «создался», а реально начал слушать порт. Это важная привычка, когда вы проверяете, что сервис жив.

Самая прикладная часть startup logs для веб-сервиса — это строки про сервер и порт. В типичном случае вы увидите не одну строку, а небольшой «мини-сюжет»: сервер создаётся, запускается и начинает слушать порт.

Вот набор строк, которые чаще всего встречаются. Возможны небольшие отличия по формату, но смысл тот же:

# Важно различать: initialized (создали) vs started on port (слушаем порт)
Tomcat initialized with port 8080 (http)
Starting service [Tomcat]
Starting Servlet engine: [Apache Tomcat/...]
Tomcat started on port 8080 (http) with context path ""

Здесь важна разница между двумя словами, которые внешне похожи:

initialized означает, что сервер создали и подготовили. Это ещё не гарантия, что он слушает сеть.

started on port означает, что сервер реально запущен и начал слушать порт. Вот это уже момент «можно идти в браузер, в Postman или хотя бы в curl».

Если у вас пока нет ни одного контроллера — а на этом этапе курса его обычно ещё нет, — попытка открыть http://localhost:8080 может закончиться 404 Not Found. И это нормально: 404 означает «сервер жив, но не нашёл обработчик для этого пути». Это намного лучше, чем «браузер не может подключиться», потому что последнее обычно означает, что сервер не стартовал или слушает другой порт.

Ещё один полезный приём, который связывает эту лекцию с WebApplicationType. Если мы явно переведём приложение в режим NONE, то признаки Tomcat исчезнут из логов. Это хороший способ увидеть зависимость «режим запуска ↔ картина логов» буквально на глазах.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;

public static void main(String[] args) {
    // Фрагмент внутри вашего главного класса приложения (например, CatalogServiceApplication)
    SpringApplication app = new SpringApplication(CatalogServiceApplication.class);

    // Явно отключаем web-режим: Boot не будет поднимать embedded server (Tomcat)
    app.setWebApplicationType(WebApplicationType.NONE);

    // Запускаем приложение: в логах пропадут строки про Tomcat и порт
    app.run(args);
}

И после этого вы увидите, что «история с Tomcat» пропала. Логи будут короче и не будут содержать строк про порт:

2026-03-19T10:20:00.120  INFO ... : Starting CatalogServiceApplication using Java 25 with PID 12345
2026-03-19T10:20:00.121  INFO ... : No active profile set, falling back to 1 default profile: "default"
2026-03-19T10:20:01.470  INFO ... : Started CatalogServiceApplication in 1.10 seconds

Кстати, маленький момент, который часто удивляет начинающих. В веб-режиме процесс обычно продолжает жить — ведь есть серверные потоки, которые слушают порт. В NONE-режиме приложение может быстро стартовать и тут же завершиться, потому что ему, по сути, нечего «держать включённым». Это не ошибка, а следствие того, что веб-сервер больше не удерживает процесс живым.

4. Логи как таймлайн и диагностика

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

Очень удобно держать в голове простой образ: запуск Boot-приложения — не один прыжок, а последовательность шагов. Если вы визуально уложите эти шаги в голову, логи начнут читаться легче, потому что каждая строка «приклеивается» к своей фазе.

Вот простая схема — сильно упрощённая, но полезная именно для уровня junior:

flowchart TD
    A["main()"] --> B["SpringApplication.run(...)"]
    B --> C["Подготовка запуска"]
    C --> D["Создание ApplicationContext"]
    D --> E["Инициализация контекста"]
    E --> F{"WebApplicationType = SERVLET?"}
    F -->|Да| G["Старт embedded server (Tomcat)"]
    F -->|Нет| H["Нет web-сервера"]
    G --> I["Started ... in ... seconds"]
    H --> I

Теперь главный практический навык диагностики: если запуск упал, не нужно сразу читать весь stack trace как роман. В Spring Boot обычно есть очень полезный блок, который выглядит примерно так:

# Boot часто пишет “человеческий” диагноз: сначала Description/Action, а уже потом длинный stack trace
APPLICATION FAILED TO START

Description:
Web server failed to start. Port 8080 was already in use.

Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

Вот это — золото. Boot буквально говорит вам человеческим языком, что случилось и что делать. И только после этого обычно идёт большой stack trace. Stack trace тоже важен, но порядок такой: сначала читаем Description и Action, а уже потом ныряем глубже, если информации не хватило.

Ещё одна хитрость, которая спасает время: ищите в логах финальную строку

Started CatalogServiceApplication in ...

Если её нет — запуск не завершился успешно. Тогда смотрите, какая была последняя понятная успешная стадия. Например, если вы видите Starting ..., но не видите Tomcat started on port ..., значит проблема произошла где-то до момента, когда сервер начал слушать порт. Если видите Tomcat initialized, но не видите Tomcat started on port, значит сервер не смог нормально запуститься. А если видите Tomcat started on port, но потом пошли ошибки, значит сервер успел подняться, а приложение упало на дальнейших шагах. Так тоже бывает.

Если хочется ещё раз привязать логи к самому механизму старта, можно сделать маленький «детектор старта» прямо в main(): взять ApplicationContext, который вернулся из run(...), и просто вывести количество зарегистрированных бинов.

import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;

public static void main(String[] args) {
    // SpringApplication.run(...) возвращает уже собранный контекст
    ApplicationContext ctx = SpringApplication.run(CatalogServiceApplication.class, args);

    // Быстрая проверка: если эта строка напечаталась — контекст реально успел собраться
    System.out.println("Bean count = " + ctx.getBeanDefinitionCount());

    // Пример вывода: Bean count = 150+ (точное число зависит от зависимостей и версии Boot)
}

Если вы видите в консоли эту строку, значит run(...) дошёл до момента, когда контекст собран и управление вернулось в ваш main. А если приложение при этом остаётся «живым», то обычно это значит, что веб-сервер поднялся и держит процесс.

Раз уж таймлайн старта читается по логам, следующий инженерный вопрос уже не про чтение чужой работы, а про собственное участие в ней: где вообще уместно выполнять свой код на старте, как получить аргументы и как реагировать на lifecycle-события без хаоса в main.

5. Типичные ошибки при чтении startup logs

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

Ошибка №1: смотреть только на banner и успокаиваться.
Баннер — это как заставка сериала: приятно, но сюжет начинается после неё. Приложение может успешно напечатать баннер и упасть дальше. Поэтому критерий успеха — не баннер, а наличие финальной строки Started ... и, для веб-режима, строки про Tomcat started on port ....

Ошибка №2: путать “initialized” и “started”.
Строка Tomcat initialized ... часто выглядит как «ну всё, сервер поднялся». Нет. Она означает, что сервер создали. Самое важное — Tomcat started on port ...: вот это маркер того, что он слушает порт. На старте полезно прямо приучить себя искать слово started в контексте порта.

Ошибка №3: читать stack trace снизу вверх… но не в ту сторону.
Интуитивно хочется скроллить в самый низ и брать последнюю строку. Но в Boot обычно есть APPLICATION FAILED TO START с Description и Action — это ваш быстрый рецепт. Дальше, если нужно, в stack trace ищите понятное сообщение и первые Caused by:. Не пытайтесь сразу разбирать 200 строк внутренних вызовов Spring — это похоже на попытку научиться водить машину, изучая схему производства шин.

Ошибка №4: не различать вывод Gradle/IDE и вывод приложения.
При запуске через IDE или ./gradlew bootRun рядом с логами приложения может быть вывод сборки, тасков и прочих служебных сообщений. Новичок иногда начинает «лечить Spring» по строке Gradle или наоборот. Хорошая привычка: глазами находить блок, где начинается Starting ... — это и есть начало логов приложения.

Ошибка №5: считать строку про profiles «шумом».
Даже если вы пока не используете профили осознанно, строка про них — очень полезный факт. Она говорит, в каком режиме приложение стартует — хотя бы default. Когда поведение неожиданно отличается от ожиданий, эта строка часто оказывается первым объяснением: «ага, старт был не в том режиме, который я ожидал».

1
Задача
Spring Boot, 5 уровень, 4 лекция
Недоступна
Карта старта в одном файле
Карта старта в одном файле
1
Задача
Spring Boot, 5 уровень, 4 лекция
Недоступна
Тихий non-web старт без banner
Тихий non-web старт без banner
1
Опрос
Spring Boot, 5 уровень, 4 лекция
Недоступен
Spring Boot
Запуск и автонастройка приложения
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ