Quarkus中MicroProfile健康端点日志拦截失效问题(含@Liveness/@Readiness)
解决MicroProfile健康端点日志拦截失效问题
核心原因
MicroProfile Health的/q/health/ready和/q/health/live属于容器内置系统端点,默认不会触发用户自定义的JAX-RS @Provider过滤器(包括ContainerRequestFilter、ContainerResponseFilter和WriterInterceptor)——这类端点的处理逻辑独立于用户应用的JAX-RS资源链,过滤器默认不覆盖该范围。
针对性解决方案
1. Quarkus环境配置
在application.properties中添加以下配置,强制让自定义JAX-RS过滤器作用于系统端点:
quarkus.jaxrs.filter.include-system-endpoints=true
2. OpenLiberty环境配置
修改server.xml,在应用配置中添加全局过滤器并指定作用于系统资源:
<webApplication id="your-app" location="your-app.war" name="your-app"> <jaxrsFilters> <filter className="com.yourpackage.LoggingFilter" applyToSystemResources="true"/> </jaxrsFilters> </webApplication>
关键是applyToSystemResources="true"属性,确保过滤器覆盖系统端点。
3. 容器原生日志扩展方案
如果上述配置不生效,可直接用容器自带的日志能力监控健康端点:
- Quarkus:配置日志类目追踪健康端点相关日志
quarkus.log.category."io.quarkus.health".level=INFO quarkus.log.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n - OpenLiberty:通过
traceSpecification记录健康端点请求<logging traceSpecification="com.ibm.ws.microprofile.health.*=info"/>
4. 自定义健康端点代理(可选)
若需要完全自定义日志逻辑,可创建代理JAX-RS资源转发请求到原生端点,在代理中嵌入日志:
@Path("/health") public class HealthProxyResource { private static final Logger LOG = Logger.getLogger(HealthProxyResource.class.getName()); @Inject @Health HealthCheckRegistry registry; @GET @Path("/ready") public Response getReadyHealth() { // 记录请求 LOG.info("Health ready endpoint requested"); // 调用原生健康检查逻辑 HealthCheckResponse response = registry.getHealthChecks(HealthCheckType.READINESS).stream() .map(HealthCheck::call) .reduce(HealthCheckResponse::combine) .orElse(HealthCheckResponse.up("proxy")); // 记录响应 LOG.info("Health ready response status: " + response.getStatus()); return Response.status(response.getStatus() == HealthCheckResponse.Status.UP ? 200 : 503) .entity(response) .build(); } }
之后禁用原生健康端点暴露,仅对外提供代理端点即可。
额外注意事项
- 检查自定义过滤器的
@Priority注解:若存在优先级设置,确保其值高于系统过滤器(例如使用@Priority(Priorities.USER))。 - 容器版本适配:部分旧版本容器不支持系统端点的过滤器扩展,建议升级至最新稳定版。
内容的提问来源于stack exchange,提问作者GrofMonteCristo
相关产品推荐
相关产品推荐

