From 8aa9075cc555d83a7bbda7b8a0a6dc891e07da16 Mon Sep 17 00:00:00 2001 From: Paolo Di Tommaso Date: Mon, 9 Dec 2024 18:08:46 +0100 Subject: [PATCH] Add support for common pool and vthread pool metrics (#762) Signed-off-by: Paolo Di Tommaso Signed-off-by: munishchouhan Co-authored-by: Munish Chouhan Co-authored-by: munishchouhan --- build.gradle | 2 +- .../metrics/ExecutorsMetricsBinder.groovy | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/main/groovy/io/seqera/wave/metrics/ExecutorsMetricsBinder.groovy diff --git a/build.gradle b/build.gradle index 398816052..71d6bf6c2 100644 --- a/build.gradle +++ b/build.gradle @@ -158,7 +158,7 @@ jib { run{ def envs = findProperty('micronautEnvs') - def args = ["-Dmicronaut.environments=$envs","-Djdk.tracePinnedThreads=short"] + def args = ["-Dmicronaut.environments=$envs","-Djdk.tracePinnedThreads=short", "--add-opens","java.base/java.lang=ALL-UNNAMED"] if( environment['JVM_OPTS'] ) args.add(environment['JVM_OPTS']) jvmArgs args systemProperties 'DOCKER_USER': project.findProperty('DOCKER_USER') ?: environment['DOCKER_USER'], diff --git a/src/main/groovy/io/seqera/wave/metrics/ExecutorsMetricsBinder.groovy b/src/main/groovy/io/seqera/wave/metrics/ExecutorsMetricsBinder.groovy new file mode 100644 index 000000000..2f1a1000e --- /dev/null +++ b/src/main/groovy/io/seqera/wave/metrics/ExecutorsMetricsBinder.groovy @@ -0,0 +1,73 @@ +/* + * Wave, containers provisioning service + * Copyright (c) 2023-2024, Seqera Labs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.seqera.wave.metrics + +import java.lang.reflect.Field +import java.util.concurrent.ForkJoinPool + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import io.micrometer.core.instrument.MeterRegistry +import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics +import io.micronaut.context.annotation.Context +import jakarta.annotation.PostConstruct +import jakarta.inject.Inject +/** + * Register Micrometer metrics for ForkJoin commonPool and virtual threads scheduler + * + * @author Paolo Di Tommaso + */ +@Slf4j +@Context +@CompileStatic +class ExecutorsMetricsBinder { + + @Inject + private MeterRegistry registry + + @PostConstruct + void register() { + log.info "+ Registering executor metrics binder" + registerCommonPoolMetrics(registry) + registerVirtualThreadPoolMetrics(registry) + } + + void registerCommonPoolMetrics(MeterRegistry registry) { + final commonPool = ForkJoinPool.commonPool() + ExecutorServiceMetrics.monitor(registry, commonPool, "ForkJoin.commonPool") + } + + void registerVirtualThreadPoolMetrics(MeterRegistry registry) { + try { + // Create a virtual thread executor + Class VirtualThread = Class.forName("java.lang.VirtualThread"); + + // Use reflection to get the internal ForkJoinPool + Field poolField = VirtualThread.getDeclaredField("DEFAULT_SCHEDULER"); + poolField.setAccessible(true); + ForkJoinPool virtualThreadPool = (ForkJoinPool) poolField.get(null); + + // Register metrics for the virtual thread pool + ExecutorServiceMetrics.monitor(registry, virtualThreadPool, "ForkJoin.virtualPool") + } + catch (Exception e) { + log.warn "Unable to registry carrier threads pool metrics", e + } + } +}