Я работаю над отдыхом API с весенней загрузки. Мне нужно регистрировать все запросы с входными параметрами (с помощью методов, например, GET, POST и т. Д.), Пути запроса, строки запроса, соответствующего метода класса этого запроса, а также ответа на это действие, как успеха, так и ошибок.
Для примера:
успешный запрос:
http://example.com/api/users/1
Лог должен выглядеть примерно так:
{
HttpStatus: 200,
path: "api/users/1",
method: "GET",
clientIp: "0.0.0.0",
accessToken: "XHGu6as5dajshdgau6i6asdjhgjhg",
method: "UsersController.getUser",
arguments: {
id: 1
},
response: {
user: {
id: 1,
username: "user123",
email: "user123@example.com"
}
},
exceptions: []
}
Или запрос с ошибкой:
http://example.com/api/users/9999
Журнал должен быть примерно таким:
{
HttpStatus: 404,
errorCode: 101,
path: "api/users/9999",
method: "GET",
clientIp: "0.0.0.0",
accessToken: "XHGu6as5dajshdgau6i6asdjhgjhg",
method: "UsersController.getUser",
arguments: {
id: 9999
},
returns: {
},
exceptions: [
{
exception: "UserNotFoundException",
message: "User with id 9999 not found",
exceptionId: "adhaskldjaso98d7324kjh989",
stacktrace: ...................
]
}
Я хочу, чтобы Запрос / Ответ был единым объектом, с пользовательской информацией, связанной с этим объектом, как в успешных, так и в случаях ошибок.
Что лучше всего делать весной, чтобы достичь этого, может быть с фильтрами? Если да, можете ли вы привести конкретный пример?
(Я играл с @ControllerAdvice и @ExceptionHandler, но, как я уже говорил, мне нужно обрабатывать все запросы об успехе и ошибках в одном месте (и в одном журнале)).
источник
HandlerInterceptor
но это может не сработать при регистрации ответа, как указано в ответе: concretepage.com/spring/spring-mvc/… - HandlerInterceptor имеет доступ к методу (метод: «UsersController.getUser»), хотя. Это не известно в фильтре сервлетов.LogClass{ getRequestAndSaveIt()} Gson.toJson(LogClass)
как псевдокодОтветы:
Не пишите никаких перехватчиков, фильтров, компонентов, аспектов и т. Д., Это очень распространенная проблема, которая решалась много раз.
Spring Boot имеет модули под названием Actuator , которые обеспечивают вход HTTP-запросов из коробки. Есть конечная точка, сопоставленная с
/trace
(SB1.x) или/actuator/httptrace
(SB2.0 +), которая покажет вам последние 100 HTTP-запросов. Вы можете настроить его для регистрации каждого запроса или записи в БД.Чтобы получить нужные конечные точки, вам понадобится зависимость spring-boot-starter-actator, а также «белый список» конечных точек, которые вы ищете, и, возможно, настройка или отключение защиты для них.
Кроме того, где будет работать это приложение? Будете ли вы использовать PaaS? Хостинг-провайдеры, например Heroku, обеспечивают ведение журнала запросов как часть своей услуги, и вам не нужно вообще ничего кодировать.
источник
Spring уже предоставляет фильтр, который выполняет эту работу. Добавьте следующий bean в ваш конфиг
Не забудьте изменить уровень журнала
org.springframework.web.filter.CommonsRequestLoggingFilter
наDEBUG
.источник
Вы можете использовать,
javax.servlet.Filter
если нет необходимости регистрировать выполненный Java-метод.Но с этим требованием , вы должны доступ к информации , хранящейся в
handlerMapping
оDispatcherServlet
. Тем не менее, вы можете переопределить,DispatcherServlet
чтобы выполнить регистрацию пары запрос / ответ.Ниже приведен пример идеи, которая может быть усовершенствована и адаптирована к вашим потребностям.
HandlerExecutionChain
- содержит информацию об обработчике запроса.Затем вы можете зарегистрировать этого диспетчера следующим образом:
А вот образец логов:
ОБНОВИТЬ
В случае ошибок Spring выполняет автоматическую обработку ошибок. Следовательно,
BasicErrorController#error
отображается как обработчик запросов. Если вы хотите сохранить оригинальный обработчик запросов, то вы можете изменить это поведение наspring-webmvc-4.2.5.RELEASE-sources.jar!/org/springframework/web/servlet/DispatcherServlet.java:971
перед тем#processDispatchResult
называется, кэшировать оригинальный обработчик.источник
Библиотека Журнала специально создана для регистрации HTTP-запросов и ответов. Он поддерживает Spring Boot с использованием специальной стартовой библиотеки.
Чтобы включить ведение журнала в Spring Boot, все, что вам нужно сделать, это добавить библиотеку в зависимости вашего проекта. Например, если вы используете Maven:
По умолчанию вывод журнала выглядит так:
Однако он не выводит имя класса, который обрабатывает запрос. Библиотека имеет некоторые интерфейсы для написания пользовательских регистраторов.
источник
logging.level.org.zalando.logbook=TRACE
в свойapplication.properties
(как указано вReadme
)Я определил уровень входа в систему
application.properties
для печати запросов / ответов, метод URL в файле журналаЯ использовал Spring Boot.
источник
Вот как я делаю это весной, используя данные
org.springframework.web.util.ContentCachingRequestWrapper
иorg.springframework.web.util.ContentCachingResponseWrapper
источник
Если вы не возражаете попробовать Spring AOP, это то, что я исследовал для целей ведения журналов, и это работает довольно хорошо для меня. Это не будет регистрировать запросы, которые не были определены, и неудачные попытки запроса, хотя.
Добавьте эти три зависимости
Добавьте это в ваш конфигурационный файл xml
<aop:aspectj-autoproxy/>
Создайте аннотацию, которую можно использовать как pointcut
Теперь аннотируйте все остальные методы API, которые вы хотите зарегистрировать
Теперь перейдем к Аспекту. компонентное сканирование пакета, в котором находится этот класс.
Если вы хотите прочитать подробно прочитайте это. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
источник
После добавления Actuators в основанное на весенней загрузке приложение, вам
/trace
доступна конечная точка с информацией о последних запросах. Эта конечная точка работает на основе TraceRepository, а реализацией по умолчанию является InMemoryTraceRepository, которая сохраняет последние 100 вызовов. Вы можете изменить это, реализовав этот интерфейс самостоятельно и сделав его доступным в виде bean-компонента Spring. Например, чтобы регистрировать все запросы на запись (и при этом использовать реализацию по умолчанию в качестве основного хранилища для предоставления информации о/trace
конечной точке), я использую этот вид реализации:Эта
traceInfo
карта содержит основную информацию о запросе и ответ в таком роде виде:{method=GET, path=/api/hello/John, headers={request={host=localhost:8080, user-agent=curl/7.51.0, accept=*/*}, response={X-Application-Context=application, Content-Type=text/plain;charset=UTF-8, Content-Length=10, Date=Wed, 29 Mar 2017 20:41:21 GMT, status=200}}}
. Здесь нет НИКАКОГО содержания ответа.РЕДАКТИРОВАТЬ! Регистрация данных POST
Вы можете получить доступ к данным POST, переопределив WebRequestTraceFilter , но не думайте, что это хорошая идея (например, все загруженное содержимое файла попадет в журналы). Вот пример кода, но не используйте его:
источник
TraceRepository
, как мы можем получить к нему доступ?protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
но я не уверен, когда этот фильтр выполняется - может быть на этапе запроса, поэтому тело ответа там не будет готово.Этот код работает для меня в приложении Spring Boot - просто зарегистрируйте его как фильтр
источник
В настоящее время Spring Boot имеет функцию Actuator для получения журналов запросов и ответов.
Но вы также можете получить журналы, используя Aspect (AOP).
Аспект дает вам аннотацию , как:
@Before
,@AfterReturning
, и@AfterThrowing
т.д.@Before
регистрирует запрос,@AfterReturning
регистрирует ответ и@AfterThrowing
регистрирует сообщение об ошибке. Вам может не понадобиться журнал всех конечных точек, поэтому вы можете применить некоторые фильтры к пакетам.Вот несколько примеров :
Для запроса:
Здесь
@Before("within(your.package.where.endpoints.are..*)")
есть путь к пакету. Все конечные точки в этом пакете будут генерировать журнал.Для ответа:
Здесь
@AfterReturning("within(your.package.where.endpoints.are..*)")
есть путь к пакету. Все конечные точки в этом пакете будут генерировать журнал. ТакжеObject returnValue
содержит ответ.Для исключения:
Здесь
@AfterThrowing(pointcut = ("within(your.package.where.endpoints.are..*)"), throwing = "e")
есть путь к пакету. Все конечные точки в этом пакете будут генерировать журнал. ТакжеException e
содержит ответ об ошибке.Вот полный код:
Здесь с помощью
@ConditionalOnExpression("${endpoint.aspect.enabled:true}")
вы можете включить / отключить журнал. просто добавитьendpoint.aspect.enabled:true
вapplication.property
и контролировать журналБольше информации о посещении АОП здесь:
Весенние доки про АОП
Пример статьи об АОП
источник
new ObjectMapper()
дорого, лучше поделитесь одним картографом на всехВот мое решение (Spring 2.0.x)
Добавьте зависимость maven:
Отредактируйте файл application.properties и добавьте следующую строку:
Как только ваше весеннее загрузочное приложение запущено, вы можете отследить последние 100 http-запросов, вызвав этот URL: http: // localhost: 8070 / activator / httptrace
источник
Вы также можете настроить пользовательский перехватчик Spring
HandlerInterceptorAdapter
для упрощенной реализации перехватчиков только до / после:Затем вы регистрируете столько перехватчиков, сколько хотите:
Примечание: так же, как заявлено @Robert , вам нужно обратить внимание на конкретные реализации и ваше приложение использует.
HttpServletRequest
HttpServletResponse
Например, для приложений, использующих
ShallowEtagHeaderFilter
, реализация ответа будет выглядетьContentCachingResponseWrapper
так:источник
Ответ @ хана потребовал небольшой модификации, чтобы он работал для меня, но это, безусловно, самая настраиваемая вещь, которую я мог получить.
Это не сработало для меня, вероятно, потому что у меня также есть HandlerInterceptorAdapter [??], но я продолжал получать плохой ответ от сервера в этой версии. Вот моя модификация этого.
источник
Если кому-то все еще это нужно, здесь простая реализация с Spring HttpTrace Actuator. Но, как они сказали наверху, это не регистрирует тела.
источник
Пожалуйста, обратитесь к ссылке ниже для фактического ответа https://gist.github.com/int128/e47217bebdb4c402b2ffa7cc199307ba
Внесенные некоторые изменения из вышеупомянутого решения, запрос и ответ войдут в консоль и в файл, если уровень логгера - информация. мы можем напечатать или в консоли или в файле.
Вывод в файл:
источник
Если вы видите только часть полезной нагрузки вашего запроса, вам нужно вызвать
setMaxPayloadLength
функцию, поскольку по умолчанию в теле запроса отображается только 50 символов. Кроме того, установкаsetIncludeHeaders
в false является хорошей идеей, если вы не хотите регистрировать свои заголовки аутентификации!источник
Если вы используете Tomcat в своем загрузочном приложении, вы
org.apache.catalina.filters.RequestDumperFilter
найдете путь к классу. (но это не даст вам «исключений в одном месте»).источник
код, вставленный ниже, работает с моими тестами и может быть загружен из моего [github project] [1], предоставляя общий доступ после применения решения, основанного на этом, в производственном проекте.
источник
Чтобы регистрировать все запросы с входными параметрами и телом, мы можем использовать фильтры и перехватчики . Но при использовании фильтра или перехватчика мы не можем напечатать тело запроса несколько раз. Лучше всего использовать Spring-AOP. Используя это, мы можем отделить механизм регистрации от приложения. АОП может использоваться для регистрации входных и выходных данных каждого метода в приложении.
Мое решение:
}
источник
Если у вас настроен Spring boot Config server, то просто включите Debug logger для класса:
Http11InputBuffer.Http11InputBuffer.java
Отладки будут регистрировать все запросы и ответы для каждого запроса
источник
Для регистрации запросов, которые приводят только к 400:
источник