From 52258c51529d7322d2b927eaacdf36ca46c23c62 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 13 Nov 2024 19:47:11 +0100 Subject: [PATCH] Upgrade Promethus lib to 1.x and adapt the code to the new version Signed-off-by: Fabio Di Fabio # Conflicts: # metrics/core/build.gradle # metrics/core/src/main/java/org/hyperledger/besu/metrics/noop/NoOpMetricsSystem.java # metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java # metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java # metrics/rocksdb/src/main/java/org/hyperledger/besu/metrics/rocksdb/RocksDBStats.java # plugin-api/build.gradle # plugin-api/src/main/java/org/hyperledger/besu/plugin/services/MetricsSystem.java --- .../prometheus/PrometheusCollector.java | 18 +++++- .../prometheus/PrometheusGuavaCache.java | 57 ++++++++++++++----- .../prometheus/PrometheusMetricsSystem.java | 16 ++---- plugin-api/build.gradle | 2 +- 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCollector.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCollector.java index ed649679d12a..1f486305c26e 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCollector.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusCollector.java @@ -35,9 +35,18 @@ public interface PrometheusCollector { */ String getName(); - /** Get the native Prometheus collector */ + /** + * Register this collector to the specified registry + * + * @param registry the registry + */ void register(final PrometheusRegistry registry); + /** + * Unregister this collector from the specified registry + * + * @param registry the registry + */ void unregister(final PrometheusRegistry registry); /** @@ -57,6 +66,13 @@ static List getLabelValues(final Labels labels) { return labels.stream().map(Label::getValue).toList(); } + /** + * Add new values to an existing list of label values + * + * @param labelValues existing list of label values + * @param values the values to add + * @return a new list with new values appended to the original list + */ static List addLabelValues(final List labelValues, final String... values) { final var newList = new ArrayList(labelValues.size() + values.length); newList.addAll(labelValues); diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGuavaCache.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGuavaCache.java index 62bd47f9ab47..88584b33cd33 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGuavaCache.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusGuavaCache.java @@ -28,20 +28,21 @@ class PrometheusGuavaCache extends CategorizedPrometheusCollector { private static final String NAME = "__guavaCacheMetricsCollector__"; - private static final CacheMetricsCollector cacheMetricsCollector = new CacheMetricsCollector(); - private static final Set cacheNames = new ConcurrentHashSet<>(); - private static final AtomicBoolean collectorRegistered = new AtomicBoolean(false); private final Cache cache; + private final Context context; public PrometheusGuavaCache( - final MetricCategory category, final String name, final Cache cache) { + final MetricCategory category, + final Context context, + final String name, + final Cache cache) { super(category, NAME); - if (cacheNames.contains(name)) { + if (context.alreadyExists(name)) { throw new IllegalStateException("Cache already registered: " + name); } - cacheNames.add(name); this.cache = cache; + this.context = context; } @Override @@ -51,23 +52,49 @@ public String getName() { @Override public void register(final PrometheusRegistry registry) { - cacheMetricsCollector.addCache(name, cache); - if (collectorRegistered.compareAndSet(false, true)) { - registry.register(cacheMetricsCollector); - } + context.registerCache(registry, name, cache); } @Override public void unregister(final PrometheusRegistry registry) { - cacheMetricsCollector.removeCache(name); - cacheNames.remove(name); - if (cacheNames.isEmpty() && collectorRegistered.compareAndSet(true, false)) { - registry.unregister(cacheMetricsCollector); - } + context.unregisterCache(registry, name); } @Override public Stream streamObservations() { return Stream.empty(); } + + static class Context { + private final CacheMetricsCollector cacheMetricsCollector = new CacheMetricsCollector(); + private final Set cacheNames = new ConcurrentHashSet<>(); + private final AtomicBoolean collectorRegistered = new AtomicBoolean(false); + + boolean alreadyExists(final String name) { + return cacheNames.contains(name); + } + + void registerCache( + final PrometheusRegistry registry, final String name, final Cache cache) { + cacheMetricsCollector.addCache(name, cache); + cacheNames.add(name); + if (collectorRegistered.compareAndSet(false, true)) { + registry.register(cacheMetricsCollector); + } + } + + void unregisterCache(final PrometheusRegistry registry, final String name) { + cacheMetricsCollector.removeCache(name); + cacheNames.remove(name); + if (cacheNames.isEmpty() && collectorRegistered.compareAndSet(true, false)) { + registry.unregister(cacheMetricsCollector); + } + } + + public void clear() { + cacheNames.forEach(cacheMetricsCollector::removeCache); + cacheNames.clear(); + collectorRegistered.set(false); + } + } } diff --git a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java index 11082beecceb..bf2facc8a376 100644 --- a/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java +++ b/metrics/core/src/main/java/org/hyperledger/besu/metrics/prometheus/PrometheusMetricsSystem.java @@ -37,7 +37,6 @@ import com.google.common.cache.Cache; import com.google.common.collect.ImmutableSet; -import io.prometheus.metrics.instrumentation.guava.CacheMetricsCollector; import io.prometheus.metrics.instrumentation.jvm.JvmBufferPoolMetrics; import io.prometheus.metrics.instrumentation.jvm.JvmClassLoadingMetrics; import io.prometheus.metrics.instrumentation.jvm.JvmCompilationMetrics; @@ -69,9 +68,8 @@ public class PrometheusMetricsSystem implements ObservableMetricsSystem { cachedCounters = new ConcurrentHashMap<>(); private final Map> cachedTimers = new ConcurrentHashMap<>(); - private final Map guavaCacheCollectors = - new ConcurrentHashMap<>(); - private final Set guavaCacheNames = new ConcurrentHashSet<>(); + private final PrometheusGuavaCache.Context guavaCacheCollectorContext = + new PrometheusGuavaCache.Context(); private final Set enabledCategories; private final boolean timersEnabled; @@ -213,11 +211,8 @@ public LabelledGauge createLabelledGauge( public void createGuavaCacheCollector( final MetricCategory category, final String name, final Cache cache) { if (isCategoryEnabled(category)) { - if (guavaCacheNames.contains(name)) { - throw new IllegalStateException("Cache already registered: " + name); - } - guavaCacheNames.add(name); - final var cacheCollector = new PrometheusGuavaCache(category, name, cache); + final var cacheCollector = + new PrometheusGuavaCache(category, guavaCacheCollectorContext, name, cache); registerCollector(category, cacheCollector); } } @@ -262,7 +257,6 @@ public void shutdown() { collectors.clear(); cachedCounters.clear(); cachedTimers.clear(); - guavaCacheCollectors.clear(); - guavaCacheNames.clear(); + guavaCacheCollectorContext.clear(); } } diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 42587278f9c1..2d3d5191df41 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -71,7 +71,7 @@ Calculated : ${currentHash} tasks.register('checkAPIChanges', FileStateChecker) { description = "Checks that the API for the Plugin-API project does not change without deliberate thought" files = sourceSets.main.allJava.files - knownHash = '/uVL++40w0GJqDavP8+z3Pv8qIdA+G9jvj4os2JvQ/4=' + knownHash = 'aYWbsgPoKTGDgq9d4QUBvQEaZYbKNJGMiBufzyKnusA=' } check.dependsOn('checkAPIChanges')