启用春季启动执行器健康检查API的记录



我正在使用Spring Boot执行器API用于我的项目具有健康检查端点,并通过:

启用它
management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=healthcheck

这里提到的

现在,我想在上述/healthcheck的状态失败并从此终点打印整个响应时,启用登录我的应用程序日志文件。

实现此目标的正确方法是什么?

最佳方法是用@EndpointWebExtension扩展执行器端点。您可以做以下;

@Component
@EndpointWebExtension(endpoint = HealthEndpoint.class)
public class HealthEndpointWebExtension {
    private HealthEndpoint healthEndpoint;
    private HealthStatusHttpMapper statusHttpMapper;
    // Constructor
    @ReadOperation
    public WebEndpointResponse<Health> health() {
        Health health = this.healthEndpoint.health();
        Integer status = this.statusHttpMapper.mapStatus(health.getStatus());
        // log here depending on health status.
        return new WebEndpointResponse<>(health, status);
    }
}

更多关于执行器端点在此处延伸的 4.8。扩展现有端点

上述答案对我不起作用。我实施了以下操作,并且有效。当您从浏览器查看[myhost:port]/actuator/health时,下面将执行。您也可以将healthCheckLogger添加到准备/LINICICES探针中,以便定期执行。

@Slf4j
@Component
public class HealthCheckLogger implements HealthIndicator
{
   @Lazy
   @Autowired
   private HealthEndpoint healthEndpoint;
   @Override
   public Health health()
   {
      log.info("DB health: {}", healthEndpoint.healthForPath("db"));
      log.info("DB health: {}", healthEndpoint.healthForPath("diskSpace"));
      return Health.up().build();
   }
}

使用EndpointWebExtension扩展HealthEndpoint不适用于较新的弹簧版本。不允许覆盖现有的(Web-)扩展名或重新注册另一个。

另一个解决方案是使用Filter。如果健康检查失败,则以下实现日志:

public class HealthLoggingFilter implements Filter {
    private static final Logger LOG = LoggerFactory.getLogger(HealthLoggingFilter.class);
    @Override
    public void init(FilterConfig filterConfig) {
        // nothing to do
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ContentCachingResponseWrapper responseCacheWrapperObject = new ContentCachingResponseWrapper((HttpServletResponse) response);
        chain.doFilter(request, responseCacheWrapperObject);
        int status = ((HttpServletResponse) response).getStatus();
        if (status >= 400) { // unhealthy
            byte[] responseArray = responseCacheWrapperObject.getContentAsByteArray();
            String responseStr = new String(responseArray, responseCacheWrapperObject.getCharacterEncoding());
            LOG.warn("Unhealthy. Health check returned: {}", responseStr);
        }
        responseCacheWrapperObject.copyBodyToResponse();
    }
    @Override
    public void destroy() {
        // nothing to do
    }
}

可以使用FilterRegistrationBean注册actuator/health路由的过滤器:

@Bean
public FilterRegistrationBean<HealthLoggingFilter > loggingFilter(){
    FilterRegistrationBean<HealthLoggingFilter > registrationBean = new FilterRegistrationBean<>();
    registrationBean.setFilter(new HealthLoggingFilter ());
    registrationBean.addUrlPatterns("/actuator/health");
    return registrationBean;    
}

如果使用webflux,则适用于我在kotlin中的样本

@Component
@EndpointWebExtension(endpoint = HealthEndpoint::class)
    class LoggingReactiveHealthEndpointWebExtension(
          registry: ReactiveHealthContributorRegistry,
          groups: HealthEndpointGroups
    ) : ReactiveHealthEndpointWebExtension(registry, groups) {
    companion object {
        private val logger = LoggerFactory.getLogger(LoggingReactiveHealthEndpointWebExtension::class.java)
    }
    override fun health(
        apiVersion: ApiVersion?,
        securityContext: SecurityContext?,
        showAll: Boolean,
        vararg path: String?
    ): Mono<WebEndpointResponse<out HealthComponent>> {
        val health = super.health(apiVersion, securityContext, showAll, *path)
        return health.doOnNext {
            if (it.body.status == UP) {
                logger.info("Health status: {}, {}", it.body.status, ObjectMapper().writeValueAsString(it.body))
            }
        }
    }
}

最新更新