Включить регистрацию в API проверки работоспособности привода с пружинной загрузкой

Я использую Spring boot Actuator API для конечной точки проверки работоспособности и включил ее:

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

Упоминается здесь: https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-monitoring.html

Теперь я хочу включить журнал в моем файле журнала приложения, когда когда-либо не получится состояние вышеупомянутой проверки работоспособности, и напечатать весь ответ с этой конечной точки.

Можете ли вы помочь или предложить, как правильно достичь этого.

4 ответа

Приведенные выше ответы не сработали для меня. Я реализовал ниже, и это работает. Когда вы просматриваете[myhost:port]/actuator/healthиз вашего браузера будет выполнено следующее. Вы также можете добавитьhealthCheckLoggerк вашим зондам готовности/живучести, чтобы он выполнялся периодически.

      @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. Вы можете сделать следующее;

@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. Расширение существующих конечных точек

РасширениеHealthEndpointиспользуяEndpointWebExtensionне работает с более новыми версиями Spring. Не разрешается переопределять существующее (веб-) расширение или перерегистрировать другое.

Другим решением является использование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
    }
}

Фильтр можно зарегистрировать дляactuator/healthмаршрут с использованиемFilterRegistrationBean:

      @Bean
public FilterRegistrationBean<HealthLoggingFilter > loggingFilter(){
    FilterRegistrationBean<HealthLoggingFilter > registrationBean = new FilterRegistrationBean<>();

    registrationBean.setFilter(new HealthLoggingFilter ());
    registrationBean.addUrlPatterns("/actuator/health");

    return registrationBean;    
}

Если использовать Webflux, это сработало для меня, образец в Котлине

      @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))
        }
    }
}

}

Другие вопросы по тегам