When trying to export the Spring Boot health indicators as metrics with Micrometer. I followed the Mapping Health Indicators to Micrometer Metrics to implement the same. The implementation is as follows
@Configuration
public class HealthApiToMetricsConvertor {
    @Bean
    public MeterRegistryCustomizer<MeterRegistry> healthRegistryCustomizer(HealthContributorRegistry healthRegistry,
                                                                           HealthEndpoint healthEndpoint) {
        return new MeterRegistryCustomizer<MeterRegistry>() {
            @Override
            public void customize(MeterRegistry registry) {
                registry.gauge("health",Tags.of("name","root"), healthEndpoint, it -> healthToCode(it.health().getStatus()));
                healthRegistry
                        .stream()
                        .forEach(
                                namedContributor -> registry.gauge(
                                        "health",
                                        Tags.of("name", namedContributor.getName()),
                                        healthRegistry,
                                        health -> {
                                            var status = ((HealthIndicator) health.getContributor(namedContributor.getName()))
                                                    .getHealth(false).getStatus();
                                            return healthToCode(status);
                                        }
                                )
                        );
            }
        };
    }
    private int healthToCode(Status status) {
        return status.equals(Status.UP) ? 1 : 0;
    }
}
While building and running the test (using the test-container)I am facing an OutOfMemory error.
Following are the memory metrics.

When the HealthApiToMetricsConvertor class is commented out there is no memory leak.

Could someone please tell me the possible cause and solution? If I've missed anything, or over- or under-emphasized a specific point, please let me know in the comments. Thank you so much in advance for your time.
Disclaimer: I didn't try this out, so it might not be exactly what you need, but it should give you an idea of where it might be going wrong.
Looking at your code, I think this is where it goes wrong: in your second call of the registry.gauge(...) method, you are passing healthRegistry instead of healthPoint, and you are doing this for each contributor of the healthRegistry object. If the gauge(...) method iterates over each contributor you can imagine how quickly the memory will fill up and throw an OutOfMemoryException.
Try something like this:
@Bean
public MeterRegistryCustomizer<MeterRegistry>
healthRegistryCustomizer(HealthContributorRegistry healthRegistry, HealthEndpoint healthEndpoint) {
    return registry -> {
        registry.gauge("health", Tags.of("name", "root"), healthEndpoint, it -> healthToCode(it.health().getStatus()));
        healthRegistry.stream().forEach(namedContributor ->
                registry.gauge("health", Tags.of("name", namedContributor.getName()),
                        healthEndpoint,
                        doubleValues -> {
                            var status = doubleValues.health().getStatus();
                            return healthToCode(status);
                        }
                )
        );
    };
}
private int healthToCode(Status status) {
    return status.equals(Status.UP) ? 1 : 0;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With