ServerHttpObservationFilter
是一个继承自 OncePerRequestFilter
的Spring框架过滤器类。这个过滤器的目的是用于观察和记录HTTP请求和响应的相关数据,通常用于监控、日志记录、性能评估等场景。它使用 ObservationRegistry
来注册和存储观察结果,并可以自定义观察约定(ServerRequestObservationConvention
)。
业务场景:
在一个大型的分布式系统中,服务之间的调用非常频繁,监控这些服务的性能和行为对于维护整个系统的稳定性和可靠性至关重要。ServerHttpObservationFilter
可以帮助开发者实现以下目标:
性能监控:记录请求处理时间,分析慢请求。
错误跟踪:捕获和记录服务器端的异常,帮助快速定位问题。
安全审计:记录关键请求和响应,用于安全分析和合规性检查。
流量分析:观察请求模式和流量分布,以优化资源分配。
关键处理代码:
以下是 ServerHttpObservationFilter
类的一些关键处理代码:
构造函数:接收
ObservationRegistry
和ServerRequestObservationConvention
对象,用于记录观察结果和定义观察细节。
public ServerHttpObservationFilter(ObservationRegistry observationRegistry, ServerRequestObservationConvention observationConvention) { this.observationRegistry = observationRegistry; this.observationConvention = observationConvention; }
doFilterInternal
方法:实现过滤器的主要逻辑,创建或获取Observation
对象,并在请求处理过程中进行观察。
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { Observation observation = createOrFetchObservation(request, response); try (Observation.Scope scope = observation.openScope()) { filterChain.doFilter(request, response); } catch (Exception ex) { observation.error(unwrapServletException(ex)); response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); throw ex; } finally { // 处理异步请求和观察结束 } }
createOrFetchObservation
方法:创建或获取与当前请求关联的Observation
对象。
private Observation createOrFetchObservation(HttpServletRequest request, HttpServletResponse response) { Observation observation = (Observation) request.getAttribute(CURRENT_OBSERVATION_ATTRIBUTE); if (observation == null) { ServerRequestObservationContext context = new ServerRequestObservationContext(request, response); observation = ServerHttpObservationDocumentation.HTTP_SERVLET_SERVER_REQUESTS.observation(this.observationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> context, this.observationRegistry).start(); request.setAttribute(CURRENT_OBSERVATION_ATTRIBUTE, observation); } return observation; }
异常处理:在
doFilterInternal
方法中,通过catch
块捕获异常,并使用Observation
对象记录错误信息。请求结束后的处理:在
finally
块中,如果请求不是异步的,结束Observation
并记录任何异常。
启用方式
1. 创建 ObservationRegistry
Bean
ObservationRegistry
是用于注册和存储观察结果的组件。你需要在你的 Spring 配置类中创建它的 Bean:
@Bean public ObservationRegistry observationRegistry() { return new ObservationRegistry(); }
2. 配置 ServerHttpObservationFilter
创建 ServerHttpObservationFilter
的 Bean,并注入 ObservationRegistry
。你还可以提供一个自定义的 ServerRequestObservationConvention
,用于定义如何命名和标记观察结果:
@Bean public ServerHttpObservationFilter serverHttpObservationFilter(ObservationRegistry observationRegistry) { return new ServerHttpObservationFilter(observationRegistry); }
3. 注册过滤器
将 ServerHttpObservationFilter
注册为应用程序的一个过滤器。如果你使用的是 Servlet API,可以在 web.xml
中注册,或者使用 FilterRegistrationBean
:
@Configuration public class FilterConfig { @Bean public FilterRegistrationBean<ServerHttpObservationFilter> serverHttpObservationFilterRegistration( ServerHttpObservationFilter serverHttpObservationFilter) { FilterRegistrationBean<ServerHttpObservationFilter> registrationBean = new FilterRegistrationBean<>(serverHttpObservationFilter); registrationBean.addUrlPatterns("/*"); return registrationBean; } }
4. 使用观察上下文
在应用程序的其他部分,你可能需要访问当前请求的观察上下文。可以使用 ServerHttpObservationFilter
提供的静态方法来获取:
public void someBusinessLogic(HttpServletRequest request) { ServerRequestObservationContext observationContext = ServerHttpObservationFilter.findObservationContext(request) .orElse(null); if (observationContext != null) { // 使用 observationContext 进行业务逻辑 } }
目的:
ServerHttpObservationFilter
的使用目的在于为基于Spring框架的Web应用程序提供一种机制,以便于捕获和记录HTTP请求和响应的详细信息,从而帮助开发者更好地理解和优化应用程序的行为。通过这种方式,可以提高应用程序的可观测性,增强其稳定性和性能。