[Java, API] Как трассировка запросов сломала API
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
TL;DR;История провала со счастливым концом о том, как команда узнала о трассировке запросов, AOP, а потом сломала 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 для решения поставленной задачи. Отдает свой код команде на ревью. Команда узнала что-то новое. Команда рада. Тимлид доволен. Ревью проходит успешно и код вливается в основную ветку.Условный вторникТимлид просит свою команду сделать по аналогии логирование еще для нескольких важных мест в проекте. Команда задачу поняла. Команда сделала. Все довольны.Условная средаДавящее чувство, связанное с дублированием кода в нескольких местах (для установки сгенерированного уникального идентификатора, а потом для его очистки) гложет команду и подрывает моральный дух. Вроде проблему решили, но как-то не круто.На обеденном перерыве тимлид вспоминает, что есть такая штука как AOP. Тимлид знает, что это особая эльфийская магия и что надо ей пользоваться аккуратно. Но тимлид верит в свою команду. Что вообще может пойти не так?Условный четвергКоманда узнает от тимлида про AOP и о том, как это может помочь решить проблему дублирования кода. Один из разработчиков получает задание внедрить Spring AOP и прикрутить логирование запросов. Получилось что-то такое:
@Around("execution(public * super.pupper.web.api.*.*Api.*(..))")
public void aroundApi(ProceedingJoinPoint jp) throws Throwable {
LogUtil.initTraceId();
jp.proceed()
LogUtil.clearTraceId();
}
Для команды AOP штука новая. Команда смотрит на код, выглядит ок. Мерджим.Условная пятницаПятница день самый приятный. Потому что самое большое количество новой информации на квадратную секунду времени узнается именно в пятницу. После обеда фронт приходит к бекенду и говорит, что, мол, я конечно всё понимаю, но бекенд ничего не отвечает. На бекенд команду заводят задачку “ничо не работает”. Внимательный читатель уже знает в чем причина, давайте уже наконец раскроем карты. Все дело в коде (естественно):
@Around("execution(public * super.pupper.web.api.*.*Api.*(..))")
public void aroundApi(ProceedingJoinPoint jp) throws Throwable {
LogUtil.initTraceId();
jp.proceed();
LogUtil.clearTraceId();
}
Вся ошибка в том, что результат вызова тихо мирно умалчивается, и API метод ничего в буквально смысле не возвращает. Заголовок 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();
}
}
Разработчик заливает фикс. Все рады. Успехов вам на код-ревью и на отладке! :)
===========
Источник:
habr.com
===========
Похожие новости:
- [Тестирование IT-систем, Программирование, Java, Тестирование веб-сервисов] AspectJ в автоматическом тестировании — несколько практических примеров
- [Информационная безопасность, Google API] Как я воровал данные с пользовательских аккаунтов в Google (перевод)
- [Python, Data Mining, API, Big Data] Как лайкать четыре тысячи девушек в час
- [Python, Data Mining, API] Как лайкать 4000 тысячи девушек в час
- [Java] Разбираемся, как работает Spring Data Repository, и создаем свою библиотеку по аналогии
- [Java, Разработка мобильных приложений, Разработка под Android] Android Bluetooth Low Energy (BLE) – готовим правильно, часть #4 (bonding) (перевод)
- [PHP, PostgreSQL, SQL] Установка Redmine за 15 минут (RVM + RoR + Unicorn + Nginx)
- [Информационная безопасность, Разработка веб-сайтов, JavaScript] Опасная уязвимость в популярной библиотеке Sequelize
- [Open source, Java, API, Apache, Natural Language Processing] Поиск по синонимам — контролируем процесс или доверяемся нейросетям
- [Программирование, Java, API, Хакатоны] Тривиальная и неправильная «облачная» компиляция
Теги для поиска: #_java, #_api, #_api, #_trassirovka (трассировка), #_blog_kompanii_programmnyj_produkt (
Блог компании Программный Продукт
), #_java, #_api
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:08
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
TL;DR;История провала со счастливым концом о том, как команда узнала о трассировке запросов, AOP, а потом сломала 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 @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(); } @Around("execution(public * super.pupper.web.api.*.*Api.*(..))")
public Object aroundApi(ProceedingJoinPoint jp) throws Throwable { LogUtil.initTraceId(); try { return jp.proceed(); } finally { LogUtil.clearTraceId(); } } =========== Источник: habr.com =========== Похожие новости:
Блог компании Программный Продукт ), #_java, #_api |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:08
Часовой пояс: UTC + 5