pointerness
pointerness

Reputation: 323

SpringBoot health Endpoints overriden

I am trying to write an extension for the acutator health endpoint. Following the documentation as per https://github.com/spring-projects/spring-boot/wiki/Migrating-a-custom-Actuator-endpoint-to-Spring-Boot-2

However I don't see the my extension being invoked. I do see this message Overriding bean definition for bean 'healthEndpointWebExtension' with a different definition: So the extension I created is being overriden with the default version provided by Spring

Upvotes: 3

Views: 6263

Answers (4)

Gaurao Burghate
Gaurao Burghate

Reputation: 307

You can not actually write EndpointWebExtension for predefine acutator URL. But what you can do is you can overwrite the existing definition for EndpointWebExtension like below. You can write custom logic as per requirement.

@Component

@EndpointWebExtension(endpoint = HealthEndpoint.class)

public class CustomeEndpointWebExtension extends HealthEndpointWebExtension {

    private static final String[] NO_PATH = {};
    public HealthWebEndpointWebExtension(HealthContributorRegistry registry, HealthEndpointGroups groups) {
        super(registry, groups);

    }

//To write custom logic for /acuator/health
    @ReadOperation
    public WebEndpointResponse<HealthComponent> health(ApiVersion apiVersion, SecurityContext securityContext) {
        System.out.println("#@Start");
        WebEndpointResponse<HealthComponent> health = health(apiVersion, securityContext, false, NO_PATH);
        //Can write customer logic here as per requirment
        System.out.println("#@End"+health.getBody().getStatus());
        return health;
    }

//To write custom logic for /acuator/health/db
    @ReadOperation
    public WebEndpointResponse<HealthComponent> health(ApiVersion apiVersion, SecurityContext securityContext,
            @Selector(match = Match.ALL_REMAINING) String... path) {
        WebEndpointResponse<HealthComponent> health = health(apiVersion, securityContext, false, path);
        System.out.println("#Status"+health.getBody().getStatus());
        return health;
    }

}

Upvotes: 2

crusy
crusy

Reputation: 1512

Just tested with 2.1.1.RELEASE: Provide your own @WebEndpoint like

@Component
@WebEndpoint(id = "acmehealth")
public class AcmeHealthEndpoint {

    @ReadOperation
    public String hello() {
      return "hello health";
    }
}

and

  1. include it
  2. map the original /health to, say, /internal/health
  3. map your custom endpoint to /health

via application.properties:

management.endpoints.web.exposure.include=acmehealth
management.endpoints.web.path-mapping.health=internal/health
management.endpoints.web.path-mapping.acmehealth=/health

The important part here is to map the original endpoint to somewhere else. In doing so you prevent the collision.

Upvotes: 4

user3663855
user3663855

Reputation: 21

Akkave is correct. However,as a supplementary, you need to set the package same with spring one: package org.springframework.boot.actuate.health; to ensure it overide the spring's bean!

Upvotes: 2

Akkave
Akkave

Reputation: 473

Use this code and keep in mind that name of your class MUST be exactly HealthEndpointWebExtension

@Component
@EndpointWebExtension(endpoint = HealthEndpoint.class)
public class HealthEndpointWebExtension {

@Autowired
private HealthEndpoint delegate;

@ReadOperation
public WebEndpointResponse<Health> getHealth() {
    Health health = this.delegate.health();
    Integer status = getStatus(health);
    return new WebEndpointResponse<>(health, status);
}
}

Upvotes: 4

Related Questions