Что делать при запуске Java приложения без логов?
Что проверяют
Умеете ли вы искать причину, когда привычный источник информации пуст, и понимаете ли, что «логов нет» почти всегда значит «логи есть, но не там, где вы смотрите». Для инженера эксплуатации это вопрос про весь путь записи от процесса до места, где вы её читаете.
Как отвечать
Идти с двух концов. Сначала жив ли процесс: состояние контейнера или пода и код выхода. Код 137 означает остановку по нехватке памяти, 143 корректное завершение по сигналу. Если контейнер падает сразу, смотреть вывод прошлого запуска (kubectl logs --previous), потому что текущий уже пустой.
Дальше по шагам:
- пишет ли приложение в stdout. В контейнере это единственный рабочий вариант, а типовая ошибка в том, что вывод настроен в файл внутри контейнера, и лог лежит там, куда никто не смотрит. Проверяется заходом внутрь и поиском файла;
- стартовала ли вообще JVM. Отсутствие главного класса, нехватка памяти или неверный аргумент уходят в stderr до инициализации логгера: в выводе контейнера это видно, в системе сбора логов нет;
- какая конфигурация подхватилась. Полезно передать путь явно и поднять уровень, например
-Dlogging.level.root=DEBUG, и проверить, не переопределяет ли профиль переменная окружения; - доехали ли записи до хранилища. Смотрят агент сбора, его очередь и ошибки отправки, а также время в записях: при сбитых часах или таймзоне они попадают вне окна поиска.
Где спотыкаются
Смешивают фасад и реализацию. SLF4J сам ничего не пишет, это интерфейс, пишет подключённая реализация. Классическая картина: в сборке нет ни одной реализации или их сразу две, и вывод пропадает целиком или наполовину.
Второе: правят конфигурацию в репозитории и ждут эффекта на стенде. Образ собран раньше, внутри него старый файл, а внешняя конфигурация не смонтирована. Проверять надо то, что реально лежит в запущенном контейнере.
Третье: ищут причину в приложении, когда дело в правах и ротации. Процесс под непривилегированным пользователем не создаёт каталог логов и молча остаётся без файла, а на узле файл контейнера ротируется по размеру, и нужные строки уже вытеснены новыми.