Skip to content

Commit

Permalink
Upgrade to Promethus java client 1.x and adapt the code to the new ve…
Browse files Browse the repository at this point in the history
…rsion

Signed-off-by: Fabio Di Fabio <[email protected]>
  • Loading branch information
fab-10 committed Jan 18, 2024
1 parent 1c7ead1 commit 6f3cb0c
Show file tree
Hide file tree
Showing 15 changed files with 1,004 additions and 303 deletions.
2 changes: 0 additions & 2 deletions ethereum/core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ dependencies {
implementation 'org.immutables:value-annotations'
implementation 'tech.pegasys:jc-kzg-4844'

implementation 'io.prometheus:simpleclient_guava'

implementation 'org.xerial.snappy:snappy-java'

annotationProcessor 'org.immutables:value'
Expand Down
2 changes: 1 addition & 1 deletion ethereum/p2p/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ dependencies {
implementation 'com.google.guava:guava'
implementation 'dnsjava:dnsjava'
implementation 'io.netty:netty-transport-native-unix-common'
implementation 'io.prometheus:simpleclient'
implementation 'io.prometheus:prometheus-metrics-core'
implementation 'io.vertx:vertx-core'

implementation 'io.tmio:tuweni-bytes'
Expand Down
611 changes: 611 additions & 0 deletions gradle/verification-metadata.xml

Large diffs are not rendered by default.

10 changes: 4 additions & 6 deletions gradle/versions.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,10 @@ dependencyManagement {

dependency 'io.pkts:pkts-core:3.0.10'

dependencySet(group: 'io.prometheus', version: '0.16.0') {
entry 'simpleclient'
entry 'simpleclient_common'
entry 'simpleclient_hotspot'
entry 'simpleclient_pushgateway'
entry 'simpleclient_guava'
dependencySet(group: 'io.prometheus', version: '1.1.0') {
entry 'prometheus-metrics-core'
entry 'prometheus-metrics-instrumentation-jvm'
entry 'prometheus-metrics-exporter-httpserver'
}

dependency 'io.reactivex.rxjava2:rxjava:2.2.21'
Expand Down
7 changes: 3 additions & 4 deletions metrics/core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,9 @@ dependencies {
implementation 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure'
implementation 'io.opentelemetry.semconv:opentelemetry-semconv'

implementation 'io.prometheus:simpleclient'
implementation 'io.prometheus:simpleclient_common'
implementation 'io.prometheus:simpleclient_hotspot'
implementation 'io.prometheus:simpleclient_pushgateway'
implementation 'io.prometheus:prometheus-metrics-core'
implementation 'io.prometheus:prometheus-metrics-instrumentation-jvm'
implementation 'io.prometheus:prometheus-metrics-exporter-httpserver'
implementation 'io.vertx:vertx-core'
implementation 'io.vertx:vertx-web'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.hyperledger.besu.metrics.prometheus;

import io.prometheus.metrics.model.snapshots.Label;
import io.prometheus.metrics.model.snapshots.Labels;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;

import java.util.List;
import java.util.stream.Collectors;

public abstract class CategorizedPrometheusCollector implements PrometheusCollector {
protected final MetricCategory category;
protected final String name;
protected final String prefixedName;

protected CategorizedPrometheusCollector(final MetricCategory category, final String name) {
this.category = category;
this.name = name;
this.prefixedName = prefixedName(category, name);
}

private static String categoryPrefix(final MetricCategory category) {
return category.getApplicationPrefix().orElse("") + category.getName() + "_";
}

/**
* Get the category prefixed name.
*
* @return the name as string
*/
private static String prefixedName(final MetricCategory category, final String name) {
return categoryPrefix(category) + name;
}

protected static List<String> getLabelValues(final Labels labels) {
return labels.stream().map(Label::getValue).collect(Collectors.toList());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
public class MetricsPushGatewayService implements MetricsService {
private static final Logger LOG = LoggerFactory.getLogger(MetricsPushGatewayService.class);

private PushGateway pushGateway;
private MetricsPushGatewayService pushGateway;
private ScheduledExecutorService scheduledExecutorService;
private final MetricsConfiguration config;
private final MetricsSystem metricsSystem;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.hyperledger.besu.metrics.prometheus;

import io.prometheus.metrics.model.registry.Collector;
import org.hyperledger.besu.metrics.Observation;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;

import java.util.stream.Stream;

public interface PrometheusCollector {
String getName();

Collector toCollector();

Stream<Observation> streamObservations();

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,75 @@
*/
package org.hyperledger.besu.metrics.prometheus;

import io.prometheus.metrics.core.datapoints.CounterDataPoint;
import io.prometheus.metrics.model.registry.Collector;
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
import io.prometheus.metrics.model.snapshots.Label;
import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import io.vertx.core.impl.ConcurrentHashSet;
import org.hyperledger.besu.metrics.Observation;
import org.hyperledger.besu.plugin.services.metrics.Counter;
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;

class PrometheusCounter implements LabelledMetric<Counter> {
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

private final io.prometheus.client.Counter counter;
class PrometheusCounter extends CategorizedPrometheusCollector implements LabelledMetric<Counter> {
private final io.prometheus.metrics.core.metrics.Counter counter;

public PrometheusCounter(final io.prometheus.client.Counter counter) {
this.counter = counter;
public PrometheusCounter( final MetricCategory category,
final String name,
final String help,
final String... labelNames) {
super(category, name);
this.counter = io.prometheus.metrics.core.metrics.Counter.builder().name(this.prefixedName).help(help).labelNames(labelNames).build();
}

@Override
public Counter labels(final String... labels) {
return new UnlabelledCounter(counter.labels(labels));
return new UnlabelledCounter(counter.labelValues(labels));
}

private static class UnlabelledCounter implements Counter {
private final io.prometheus.client.Counter.Child counter;
@Override
public String getName() {
return counter.getPrometheusName();
}

private UnlabelledCounter(final io.prometheus.client.Counter.Child counter) {
this.counter = counter;
}
@Override
public Collector toCollector() {
return counter;
}

@Override
public void inc() {
counter.inc();
}
private Observation convertToObservation(final CounterSnapshot.CounterDataPointSnapshot sample) {
final List<String> labelValues = getLabelValues(sample.getLabels());

return new Observation(
category,
name,
sample.getValue(),
labelValues);
}

@Override
public Stream<Observation> streamObservations() {
final var snapshot = counter.collect();
return snapshot.getDataPoints().stream().map(this::convertToObservation);
}

private record UnlabelledCounter(CounterDataPoint counter) implements Counter {

@Override
public void inc(final long amount) {
counter.inc((double) amount);
public void inc() {
counter.inc();
}

@Override
public void inc(final long amount) {
counter.inc((double) amount);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,58 +14,84 @@
*/
package org.hyperledger.besu.metrics.prometheus;

import com.google.common.base.Preconditions;
import io.prometheus.metrics.core.datapoints.GaugeDataPoint;
import io.prometheus.metrics.core.metrics.Gauge;
import io.prometheus.metrics.model.registry.Collector;
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import org.hyperledger.besu.metrics.Observation;
import org.hyperledger.besu.plugin.services.metrics.Counter;
import org.hyperledger.besu.plugin.services.metrics.LabelledGauge;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.DoubleSupplier;

import io.prometheus.client.Collector;
import java.util.stream.Stream;

/** The Prometheus gauge. */
public class PrometheusGauge extends Collector implements LabelledGauge {
private final String metricName;
private final String help;
private final List<String> labelNames;
private final Map<List<String>, DoubleSupplier> observationsMap = new ConcurrentHashMap<>();
public class PrometheusGauge extends CategorizedPrometheusCollector implements LabelledGauge {
private final Gauge gauge;
private final Map<GaugeDataPoint, DoubleSupplier> observationsMap = new ConcurrentHashMap<>();

/**
* Instantiates a new Prometheus gauge.
*
* @param metricName the metric name
* @param name the metric name
* @param help the help
* @param labelNames the label names
*/
public PrometheusGauge(
final String metricName, final String help, final List<String> labelNames) {
this.metricName = metricName;
this.help = help;
this.labelNames = labelNames;
public PrometheusGauge(final MetricCategory category,
final String name, final String help, final String... labelNames) {
super(category, name);
this.gauge = Gauge.builder().name(this.prefixedName).help(help).labelNames(labelNames).build();
}

public PrometheusGauge(final MetricCategory category,
final String metricName, final String help, final DoubleSupplier valueSupplier) {
super(category, metricName);
this.gauge = Gauge.builder().name(metricName).help(help).build();
observationsMap.put(gauge, valueSupplier);
}

@Override
public synchronized void labels(final DoubleSupplier valueSupplier, final String... labelValues) {
if (labelValues.length != labelNames.size()) {
throw new IllegalArgumentException(
"Label values and label names must be the same cardinality");
}
if (observationsMap.putIfAbsent(List.of(labelValues), valueSupplier) != null) {
final var gaugeDataPoint = gauge.labelValues(labelValues);
if (observationsMap.putIfAbsent(gaugeDataPoint, valueSupplier) != null) {
final String labelValuesString = String.join(",", labelValues);
throw new IllegalArgumentException(
String.format("A gauge has already been created for label values %s", labelValuesString));
}
}

@Override
public List<MetricFamilySamples> collect() {
final List<MetricFamilySamples.Sample> samples = new ArrayList<>();
observationsMap.forEach(
(labels, valueSupplier) ->
samples.add(
new MetricFamilySamples.Sample(
metricName, labelNames, labels, valueSupplier.getAsDouble())));
return List.of(new MetricFamilySamples(metricName, Type.GAUGE, help, samples));
public String getName() {
return gauge.getPrometheusName();
}

@Override
public Collector toCollector() {
return gauge;
}

private Observation convertToObservation(final GaugeSnapshot.GaugeDataPointSnapshot sample) {
final List<String> labelValues = getLabelValues(sample.getLabels());

return new Observation(
category,
name,
sample.getValue(),
labelValues);
}

@Override
public Stream<Observation> streamObservations() {
final var snapshot = gauge.collect();
return snapshot.getDataPoints().stream().map(this::convertToObservation);
}

}
Loading

0 comments on commit 6f3cb0c

Please sign in to comment.