Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OutOfMemory Error When Converting Spring Boot Health Indicators to Micrometer Metrics

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.

memory leak

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

before

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.

like image 820
Nithin Varghese Avatar asked Oct 31 '25 11:10

Nithin Varghese


1 Answers

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;
}
like image 186
ahoxha Avatar answered Nov 03 '25 01:11

ahoxha