spring-bootspring-boot-actuatormicrometergaugestatsd

MeterRegistry HealthIndicator how to use Gauge gauge to report data when observed


I am using statsd mertics, right now I am trying to add metric healthIndicator

public class xxxHealthIndicator implements HealthIndicator {
 private final xxx xxx;

    private final MeterRegistry meterRegistry;
    @Autowired
    public xxxHealthIndicator(xxx xxx, @Nullable MeterRegistry meterRegistry) {
        this.xxx = xxx;
        this.meterRegistry = meterRegistry;
    }

    @Override
    public Health health() {
        return A.getHealth(xxx.getHealth());
    }
}

what I am thinking is add code in health():

 @Override
    public Health health() {
        if(meterRegistry!=null){
         Gauge gauge = Gauge
// I am confusing about report data when observed, does is means I need to add status change ? 
                .builder("xxxhealth", ????, ????) 

                .tags("status",xxx.getHealth.get("status"))
                .register(meterRegistry);
         }
        return A.getHealth(xxx.getHealth());
    }

and the https://docs.spring.io/spring-boot/docs/2.5.6/reference/html/howto.html#howto.actuator.map-health-indicators-to-metrics, the HealthEndpoint I do not need to add it.

 Gauge gauge = Gauge 
                .builder("xxxhealth", ????, this::getStatusCode ) 
                .tags("status",xxx.getHealth().get("status"))
                .register(meterRegistry);
         }
//getHealth() is return a Map
private int getStatusCode(xxx health) {
       String status = health.getHealth().get("status");
        if (Status.UP.equals(status)) {
            return 3;
        }
        if (Status.OUT_OF_SERVICE.equals(status)) {
            return 2;
        }
        if (Status.DOWN.equals(status)) {
            return 1;
        }
        return 0;
    }


Solution

  • Why are you trying to register a Gauge every time health is called? You just need to register it once and tell it how to get the value, please check the docs to have better understanding about the Gauge concept: https://micrometer.io/docs/concepts#_gauges

    With this, if you put your original code together what is in the Boot docs:

    public class xxxHealthIndicator implements HealthIndicator {
        private final xxx xxx;
    
        public xxxHealthIndicator(xxx xxx, @Nullable MeterRegistry meterRegistry) {
            this.xxx = xxx;
            Gauge.builder("xxxHealth", this::getStatusCode).register(registry);
        }
    
        @Override
        public Health health() {
            return A.getHealth(xxx.getHealth());
        }
    
        private int getStatusCode() {
            Status status = this.health().getStatus();
            if (Status.UP.equals(status)) {
                return 3;
            }
            if (Status.OUT_OF_SERVICE.equals(status)) {
                return 2;
            }
            if (Status.DOWN.equals(status)) {
                return 1;
            }
            return 0;
        }
    }