Включить регистрацию в 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))
}
}
}
}