I have a SpringBoot based web application that exposes a consul health indicator bean.
The bean is correctly created and initialized by springboot’s autoconfiguration, yet, the indicator is not showing in the actuator health endpoint despite the fact that the associated configuration property “management.health.consul.enabled” is set to true:
{ "status": "UP", "components": { "Kafka": {...}, "SchemaRegistry": {...}, "discoveryComposite": {...}, "diskSpace": {...}, "ping": {...}, "refreshScope": {...} } }
Upon further inspection, I found the bellow snippet that is responsible for fetching all the available indicators (HealthEndpointConfiguration.java) :
@Bean @ConditionalOnMissingBean HealthContributorRegistry healthContributorRegistry(ApplicationContext applicationContext, HealthEndpointGroups groups) { Map<String, HealthContributor> healthContributors = new LinkedHashMap<>( applicationContext.getBeansOfType(HealthContributor.class)); if (ClassUtils.isPresent("reactor.core.publisher.Flux", applicationContext.getClassLoader())) { healthContributors.putAll(new AdaptedReactiveHealthContributors(applicationContext).get()); } return new AutoConfiguredHealthContributorRegistry(healthContributors, groups.getNames()); }
Setting a break point there, I see that indeed the ConsulHealthIndicator bean is not listed in the output of the applicationContext.getBeansOfType(HealthContributor.class) call as shows bellow :
But when I test the same call with the parent application context instead, I get the following :
Can someone please shed some light on why this particular bean is present in the root context but not in the child context ?
Is there a way to force it’s initialisation in the child context so that it will get correctly registered in the health endpoint ?
I’ve attached a sample project allowing the reproduction of the issue. I’ve also included a sample of consul configuration that is used by the app (you can import it via consul import command). Running the example above and going to the health endpoint (localhost:8080/monitoring/health) you will clearly see that the consul component is missing from the list.
Thank you in advance.
Advertisement
Answer
As it seems, the Consul health indicator is not registered to the health contributor registry, you can work around this by registering the consul health check by your self. You can add a snippet like this in any configuration file.
@Autowired public void doRegister( ConsulHealthIndicator healthIndicator, HealthContributorRegistry healthContributorRegistry) { healthContributorRegistry.registerContributor("consul", healthIndicator); }
Once added this should produce something like this
{ "status": "UP", "components": { "consul": { "status": "UP", "details": { "leader": "127.0.0.1:8300", "services": { "consul": [] } } }, "discoveryComposite": { "description": "Discovery Client not initialized", "status": "UNKNOWN", "components": { "discoveryClient": { "description": "Discovery Client not initialized", "status": "UNKNOWN" } } }, "diskSpace": { "status": "UP", "details": { "total": 250685575168, "free": 17967964160, "threshold": 10485760, "exists": true } }, "ping": { "status": "UP" }, "refreshScope": { "status": "UP" } } }