ТЛ;ДР; История неудач со счастливым концом о том, как команда узнала о трассировке запросов, АОП, а затем сломала API.
Невинное начало
Каждый проект содержит журналирование.В нашем проекте использовался Lombok и его аннотация @Slf4j. Мы протоколировали выполнение бизнес-операций, но нам не хватало контекста.
В логах было что-то вроде этого:
Но мы хотели увидеть, что это относится к конкретному запросу.Create order Create order Order created. Failed to create order
Чтобы мы понимали, пришел запрос и вот как он прошел и вот чем закончился.
Мы хотели что-то вроде этого: REQ#1 Create order
REQ#2 Create order
REQ#2 Order created.
REQ#1 Failed to create order
А теперь детектив.
Добро пожаловать в текстовый микрокомикс :)
Условный понедельник
Итак, задача ясна.Идея решения тоже.
В начале каждого метода API мы генерируем уникальный идентификатор запроса и сохраняем его до завершения метода.
В дальнейшем, где бы ни происходило журналирование, мы используем этот сгенерированный уникальный идентификатор запроса и выводим его в журнал перед основным сообщением.
Короче говоря, все согласно характеристикам.
Ну ок, поехали.
Тимлид в отдельном треде добавляет в одно из занятий пример использования MDC для решения проблемы.
Передает ваш код команде на рассмотрение.
Команда узнала что-то новое.
Команда счастлива.
Руководитель группы доволен.
Проверка прошла успешно, и код был добавлен в основную ветку.
Условный вторник
Руководитель группы просит свою команду провести аналогичное логирование еще для нескольких важных мест проекта.Команда поняла задачу.
Команда сделала это.
Все довольны.
Условная среда
Гнетущее ощущение дублирования кода в нескольких местах (чтобы установить сгенерированный уникальный идентификатор, а затем его очистить) гложет команду и подрывает моральный дух.Вроде проблема решилась, но как-то не круто.
Во время обеденного перерыва тимлид вспоминает, что есть такое понятие, как АОП.
Тимлид знает, что это особая эльфийская магия и пользоваться ею нужно осторожно.
Но лидер команды верит в свою команду.
Что возможно могло пойти не так?
Условный четверг
Команда узнает от руководителя группы об АОП и о том, как он может помочь решить проблему дублирования кода.Один из разработчиков получает задачу реализовать Spring AOP и подключить логирование запросов.
Получилось примерно так: @Around("execution(public * super.pupper.web.api.*.
*Api.*(.
))")
public void aroundApi(ProceedingJoinPoint jp) throws Throwable {
LogUtil.initTraceId();
jp.proceed()
LogUtil.clearTraceId();
}
Это новая вещь для команды АОП.
Команда смотрит на код, он выглядит нормально.
Мерджим.
Условная пятница
Пятница – самый приятный день.Потому что наибольшее количество новой информации на квадратную секунду времени усваивается в пятницу.
После обеда фронт приходит на бэкенд и говорит, что я, конечно, все понимаю, но бэкенд ничего не отвечает. Бэкэнд-команде поставлена задача «ничего не работает».
Внимательный читатель уже знает, в чем причина, давайте наконец раскроем карты.
Это все в коде (конечно): @Around("execution(public * super.pupper.web.api.*.
*Api.*(.
))")
public void aroundApi(ProceedingJoinPoint jp) throws Throwable {
LogUtil.initTraceId();
jp.proceed();
LogUtil.clearTraceId();
}
Вся ошибка в том, что результат вызова тихо молчит, а метод API буквально ничего не возвращает. Header Content-Length: 0. Правильная реализация должна быть примерно такой: @Around("execution(public * super.pupper.web.api.*.
*Api.*(.
))")
public Object aroundApi(ProceedingJoinPoint jp) throws Throwable {
LogUtil.initTraceId();
try {
return jp.proceed();
} finally {
LogUtil.clearTraceId();
}
}
Разработчик загружает исправление.
Все довольны.
Удачи в проверке кода и отладке! :) Теги: #api #java #tracing
-
Thinkpad R31: Пятиугольное Ретро
19 Oct, 24 -
Почему Falcon 9Ft — Шедевр
19 Oct, 24 -
Dns-Серверы Ntp.org Недоступны.
19 Oct, 24 -
Субстики №142
19 Oct, 24 -
Лень – Двигатель Прогресса.
19 Oct, 24 -
Старикам Нравится Сервис Presto
19 Oct, 24