Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JVM Buildpack Memory Calculator values to actuator-autoconfigure Metrics #42458

Closed
michael-arndt-gcx opened this issue Sep 26, 2024 · 5 comments
Labels
for: external-project For an external project and not something we can fix status: superseded An issue that has been superseded by another

Comments

@michael-arndt-gcx
Copy link

When using buildpacks / bootBuildImage, the Java Buildpack Memory Calculator uses some heuristics to calculate memory parameters.

Those include an assumed number of loaded classes and maximum tread count. We'd like to have alerts, when those values were underestimated, but currently there are no metrics available to write these alerts.

We're currently doing something like the following, but I believe adding this to the actuator-autoconfigure project would be beneficial for other, too.

@AutoConfiguration(after = [MetricsAutoConfiguration::class, CompositeMeterRegistryAutoConfiguration::class])
@ConditionalOnClass(MeterRegistry::class)
@ConditionalOnBean(MeterRegistry::class)
class JvmMemoryCalculatorMetricsAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty("bpl.jvm.thread.count")
    fun jvmMemoryCalculatorMetrics(): JvmMemoryCalculatorMetrics = JvmMemoryCalculatorMetrics()
}

class JvmMemoryCalculatorMetrics : MeterBinder {
    override fun bindTo(registry: MeterRegistry) {
        // These environment variables are always set when running an image build with the Buildpack
        val threadCount = System.getenv("BPL_JVM_THREAD_COUNT")?.toLong()
        val classCount = System.getenv("BPI_JVM_CLASS_COUNT")?.toLong()

        if (threadCount != null) {
            Gauge.builder("jvm.buildpack.memorycalculator.threads") { threadCount }
                .description("Number of threads used by the JVM Memory Calculator as the " +
                    "maximum number of threads")
                .baseUnit(BaseUnits.THREADS)
                .register(registry)
        }

        if (classCount != null) {
            Gauge.builder("jvm.buildpack.memorycalculator.classes") { classCount }
                .description("Number of classes used by the JVM Memory Calculator as the " +
                    "maximum number of loaded classes")
                .baseUnit(BaseUnits.CLASSES)
                .register(registry)
        }
    }
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 26, 2024
@michael-arndt-gcx michael-arndt-gcx changed the title Add JVM Memory Calculator values to actuator-autoconfigure Metrics Add JVM Buildpack Memory Calculator values to actuator-autoconfigure Metrics Sep 26, 2024
@wilkinsona
Copy link
Member

Thanks for the suggestion. I wonder if some of this would be better off in Micrometer. For example, Micrometer could provide the MeterBinder implementation that works for any Java application deployed using buildpacks. Spring Boot could then auto-configure it. I'll discuss it with the observability team.

@wilkinsona wilkinsona added the status: waiting-for-internal-feedback An issue that needs input from a member or another Spring Team label Sep 30, 2024
@michael-arndt-gcx
Copy link
Author

Good point, wasn't aware there are standard MeterBinders in micrometer.

Please note that my initial assumption was not completely correct. It does work as described above for threads, but for classes the situation is more complicated, as I described in paketo-buildpacks/libjvm#425 (comment).

In short: the value is not currently not available and it's currently also unclear where other metrics like the maximum number of loaded classes assumed by the memory calculator will come from. Providing a calculated value would clash with the naming-schme of environment variables.

@wilkinsona
Copy link
Member

The observability team agree that this could be a standard MeterBinder in Micrometer. Once paketo-buildpacks/libjvm#425 has reached a conclusion, I'd recommend opening a Micrometer issue to add the binder. Once that's happened, please open a new Boot issue to see if we can auto-configure the binder.

/cc @jonatan-ivanov @shakuzen

@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale Oct 10, 2024
@wilkinsona wilkinsona added for: external-project For an external project and not something we can fix status: superseded An issue that has been superseded by another and removed status: waiting-for-triage An issue we've not yet triaged status: waiting-for-internal-feedback An issue that needs input from a member or another Spring Team labels Oct 10, 2024
@jonatan-ivanov
Copy link
Member

Thanks Andy for the follow-up.
From Micrometer-perspective, I think we will need a stable (no breaking changes in minor or patch versions) mechanism easily available to the JVM to get these values (e.g.: env vars, system properties, property files, etc).

@michael-arndt-gcx
Copy link
Author

Thanks Andy for the follow-up. From Micrometer-perspective, I think we will need a stable (no breaking changes in minor or patch versions) mechanism easily available to the JVM to get these values (e.g.: env vars, system properties, property files, etc).

An environment variable is one option currently considered (filesystem also, but with reservations). Number of threads already is available as BPL_JVM_THREAD_COUNT, number of classes not yet.

See paketo-buildpacks/libjvm#425 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project For an external project and not something we can fix status: superseded An issue that has been superseded by another
Projects
None yet
Development

No branches or pull requests

4 participants