Upgrade to OpenTelemetry 1.5 (#2666)

Signed-off-by: Antoine Toulme <antoine@lunar-ocean.com>
pull/2669/head
Antoine Toulme 3 years ago committed by GitHub
parent b2da957687
commit cda70d3051
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      gradle/versions.gradle
  2. 13
      metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryCounter.java
  3. 24
      metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryGauge.java
  4. 78
      metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetrySystem.java
  5. 32
      metrics/core/src/main/java/org/hyperledger/besu/metrics/opentelemetry/OpenTelemetryTimer.java

@ -61,14 +61,14 @@ dependencyManagement {
dependency 'io.netty:netty-tcnative-boringssl-static:2.0.40.Final'
dependency group: 'io.netty', name: 'netty-transport-native-epoll', version:'4.1.66.Final', classifier: 'linux-x86_64'
dependency 'io.opentelemetry:opentelemetry-api:1.2.0'
dependency 'io.opentelemetry:opentelemetry-exporter-otlp-metrics:1.2.0-alpha'
dependency 'io.opentelemetry:opentelemetry-exporter-otlp:1.2.0'
dependency 'io.opentelemetry:opentelemetry-extension-trace-propagators:1.2.0'
dependency 'io.opentelemetry:opentelemetry-proto:1.2.0-alpha'
dependency 'io.opentelemetry:opentelemetry-sdk-trace:1.2.0'
dependency 'io.opentelemetry:opentelemetry-sdk:1.2.0'
dependency 'io.opentelemetry:opentelemetry-semconv:1.2.0-alpha'
dependency 'io.opentelemetry:opentelemetry-api:1.5.0'
dependency 'io.opentelemetry:opentelemetry-exporter-otlp-metrics:1.5.0-alpha'
dependency 'io.opentelemetry:opentelemetry-exporter-otlp:1.5.0'
dependency 'io.opentelemetry:opentelemetry-extension-trace-propagators:1.5.0'
dependency 'io.opentelemetry:opentelemetry-proto:1.5.0-alpha'
dependency 'io.opentelemetry:opentelemetry-sdk-trace:1.5.0'
dependency 'io.opentelemetry:opentelemetry-sdk:1.5.0'
dependency 'io.opentelemetry:opentelemetry-semconv:1.5.0-alpha'
dependency 'io.opentracing.contrib:opentracing-okhttp3:3.0.0'
dependency 'io.opentracing:opentracing-api:0.33.0'

@ -17,12 +17,10 @@ package org.hyperledger.besu.metrics.opentelemetry;
import org.hyperledger.besu.plugin.services.metrics.Counter;
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
import java.util.ArrayList;
import java.util.List;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.metrics.BoundLongCounter;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.common.Labels;
public class OpenTelemetryCounter implements LabelledMetric<Counter> {
@ -36,12 +34,11 @@ public class OpenTelemetryCounter implements LabelledMetric<Counter> {
@Override
public Counter labels(final String... labelValues) {
List<String> labelKeysAndValues = new ArrayList<>();
final AttributesBuilder builder = Attributes.builder();
for (int i = 0; i < labelNames.length; i++) {
labelKeysAndValues.add(labelNames[i]);
labelKeysAndValues.add(labelValues[i]);
builder.put(labelNames[i], labelValues[i]);
}
final Labels labels = Labels.of(labelKeysAndValues.toArray(new String[] {}));
final Attributes labels = builder.build();
BoundLongCounter boundLongCounter = counter.bind(labels);
return new OpenTelemetryCounter.UnlabelledCounter(boundLongCounter);
}

@ -23,14 +23,14 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.DoubleSupplier;
import com.google.common.base.Preconditions;
import io.opentelemetry.api.metrics.AsynchronousInstrument;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.api.metrics.common.LabelsBuilder;
import io.opentelemetry.api.metrics.ObservableDoubleMeasurement;
public class OpenTelemetryGauge implements LabelledGauge {
private final List<String> labelNames;
private final Map<Labels, DoubleSupplier> observationsMap = new ConcurrentHashMap<>();
private final Map<Attributes, DoubleSupplier> observationsMap = new ConcurrentHashMap<>();
public OpenTelemetryGauge(
final String metricName,
@ -39,11 +39,7 @@ public class OpenTelemetryGauge implements LabelledGauge {
final List<String> labelNames) {
this.labelNames = labelNames;
meter
.doubleValueObserverBuilder(metricName)
.setDescription(help)
.setUpdater(this::updater)
.build();
meter.gaugeBuilder(metricName).setDescription(help).buildWithCallback(this::updater);
}
@Override
@ -51,23 +47,23 @@ public class OpenTelemetryGauge implements LabelledGauge {
Preconditions.checkArgument(
labelValues.length == labelNames.size(),
"label values and label names need the same number of elements");
final Labels labels = getLabels(labelValues);
final Attributes labels = getLabels(labelValues);
if (observationsMap.putIfAbsent(labels, valueSupplier) != null) {
throw new IllegalStateException(
"Already registered a gauge with labels " + Arrays.toString(labelValues));
}
}
private Labels getLabels(final String... labelValues) {
final LabelsBuilder labelsBuilder = Labels.builder();
private Attributes getLabels(final String... labelValues) {
final AttributesBuilder labelsBuilder = Attributes.builder();
for (int i = 0; i < labelNames.size(); i++) {
labelsBuilder.put(labelNames.get(i), labelValues[i]);
}
return labelsBuilder.build();
}
private void updater(final AsynchronousInstrument.DoubleResult doubleResult) {
private void updater(final ObservableDoubleMeasurement measurement) {
observationsMap.forEach(
(labels, valueSupplier) -> doubleResult.observe(valueSupplier.getAsDouble(), labels));
(labels, valueSupplier) -> measurement.observe(valueSupplier.getAsDouble(), labels));
}
}

@ -41,11 +41,10 @@ import java.util.function.DoubleSupplier;
import java.util.stream.Stream;
import com.google.common.collect.ImmutableSet;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleValueRecorder;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.data.DoubleHistogramPointData;
import io.opentelemetry.sdk.metrics.data.DoublePointData;
@ -141,7 +140,7 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
for (Object ptObj : points) {
PointData point = (PointData) ptObj;
List<String> labels = new ArrayList<>();
point.getLabels().forEach((k, v) -> labels.add(v));
point.getAttributes().forEach((k, v) -> labels.add(v.toString()));
observations.add(
new Observation(
category, metricData.getName(), extractValue(metricData.getType(), point), labels));
@ -192,7 +191,7 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
if (isCategoryEnabled(category)) {
final Meter meter = meterSdkProvider.get(category.getName());
final LongCounter counter = meter.longCounterBuilder(name).setDescription(help).build();
final LongCounter counter = meter.counterBuilder(name).setDescription(help).build();
return new OpenTelemetryCounter(counter, labelNames);
} else {
return NoOpMetricsSystem.getCounterLabelledMetric(labelNames.length);
@ -212,10 +211,7 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
(k) -> {
if (timersEnabled && isCategoryEnabled(category)) {
final Meter meter = meterSdkProvider.get(category.getName());
final DoubleValueRecorder recorder =
meter.doubleValueRecorderBuilder(name).setDescription(help).build();
return new OpenTelemetryTimer(recorder, labelNames);
return new OpenTelemetryTimer(name, help, meter, labelNames);
} else {
return NoOpMetricsSystem.getOperationTimerLabelledMetric(labelNames.length);
}
@ -232,13 +228,9 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
if (isCategoryEnabled(category)) {
final Meter meter = meterSdkProvider.get(category.getName());
meter
.doubleValueObserverBuilder(name)
.gaugeBuilder(name)
.setDescription(help)
.setUpdater(
res -> {
res.observe(valueSupplier.getAsDouble(), Labels.empty());
})
.build();
.buildWithCallback(res -> res.observe(valueSupplier.getAsDouble(), Attributes.empty()));
}
}
@ -250,10 +242,8 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
final String... labelNames) {
LOG.trace("Creating a labelled gauge {}", name);
if (isCategoryEnabled(category)) {
final OpenTelemetryGauge gauge =
new OpenTelemetryGauge(
name, help, meterSdkProvider.get(category.getName()), List.of(labelNames));
return gauge;
return new OpenTelemetryGauge(
name, help, meterSdkProvider.get(category.getName()), List.of(labelNames));
}
return NoOpMetricsSystem.getLabelledGauge(labelNames.length);
}
@ -275,34 +265,35 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
final MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
final List<MemoryPoolMXBean> poolBeans = ManagementFactory.getMemoryPoolMXBeans();
final Meter meter = meterSdkProvider.get(StandardMetricCategory.JVM.getName());
final List<Labels> labelSets = new ArrayList<>(garbageCollectors.size());
final List<Attributes> labelSets = new ArrayList<>(garbageCollectors.size());
for (final GarbageCollectorMXBean gc : garbageCollectors) {
labelSets.add(Labels.of("gc", gc.getName()));
labelSets.add(Attributes.of(AttributeKey.stringKey("gc"), gc.getName()));
}
meter
.longSumObserverBuilder("jvm.gc.collection")
.gaugeBuilder("jvm.gc.collection")
.setDescription("Time spent in a given JVM garbage collector in milliseconds.")
.setUnit("ms")
.setUpdater(
.buildWithCallback(
resultLongObserver -> {
for (int i = 0; i < garbageCollectors.size(); i++) {
resultLongObserver.observe(
garbageCollectors.get(i).getCollectionTime(), labelSets.get(i));
}
})
.build();
final Labels usedHeap = Labels.of(TYPE_LABEL_KEY, USED, AREA_LABEL_KEY, HEAP);
final Labels usedNonHeap = Labels.of(TYPE_LABEL_KEY, USED, AREA_LABEL_KEY, NON_HEAP);
final Labels committedHeap = Labels.of(TYPE_LABEL_KEY, COMMITTED, AREA_LABEL_KEY, HEAP);
final Labels committedNonHeap = Labels.of(TYPE_LABEL_KEY, COMMITTED, AREA_LABEL_KEY, NON_HEAP);
});
final AttributeKey<String> typeKey = AttributeKey.stringKey(TYPE_LABEL_KEY);
final AttributeKey<String> areaKey = AttributeKey.stringKey(AREA_LABEL_KEY);
final Attributes usedHeap = Attributes.of(typeKey, USED, areaKey, HEAP);
final Attributes usedNonHeap = Attributes.of(typeKey, USED, areaKey, NON_HEAP);
final Attributes committedHeap = Attributes.of(typeKey, COMMITTED, areaKey, HEAP);
final Attributes committedNonHeap = Attributes.of(typeKey, COMMITTED, areaKey, NON_HEAP);
// TODO: Decide if max is needed or not. May be derived with some approximation from max(used).
final Labels maxHeap = Labels.of(TYPE_LABEL_KEY, MAX, AREA_LABEL_KEY, HEAP);
final Labels maxNonHeap = Labels.of(TYPE_LABEL_KEY, MAX, AREA_LABEL_KEY, NON_HEAP);
final Attributes maxHeap = Attributes.of(typeKey, MAX, areaKey, HEAP);
final Attributes maxNonHeap = Attributes.of(typeKey, MAX, areaKey, NON_HEAP);
meter
.longUpDownSumObserverBuilder("jvm.memory.area")
.upDownCounterBuilder("jvm.memory.area")
.setDescription("Bytes of a given JVM memory area.")
.setUnit("By")
.setUpdater(
.buildWithCallback(
resultLongObserver -> {
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();
@ -312,22 +303,22 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
resultLongObserver.observe(nonHeapUsage.getUsed(), committedNonHeap);
resultLongObserver.observe(heapUsage.getUsed(), maxHeap);
resultLongObserver.observe(nonHeapUsage.getUsed(), maxNonHeap);
})
.build();
final List<Labels> usedLabelSets = new ArrayList<>(poolBeans.size());
final List<Labels> committedLabelSets = new ArrayList<>(poolBeans.size());
final List<Labels> maxLabelSets = new ArrayList<>(poolBeans.size());
});
final List<Attributes> usedLabelSets = new ArrayList<>(poolBeans.size());
final List<Attributes> committedLabelSets = new ArrayList<>(poolBeans.size());
final List<Attributes> maxLabelSets = new ArrayList<>(poolBeans.size());
final AttributeKey<String> poolKey = AttributeKey.stringKey(POOL_LABEL_KEY);
for (final MemoryPoolMXBean pool : poolBeans) {
usedLabelSets.add(Labels.of(TYPE_LABEL_KEY, USED, POOL_LABEL_KEY, pool.getName()));
committedLabelSets.add(Labels.of(TYPE_LABEL_KEY, COMMITTED, POOL_LABEL_KEY, pool.getName()));
maxLabelSets.add(Labels.of(TYPE_LABEL_KEY, MAX, POOL_LABEL_KEY, pool.getName()));
usedLabelSets.add(Attributes.of(typeKey, USED, poolKey, pool.getName()));
committedLabelSets.add(Attributes.of(typeKey, COMMITTED, poolKey, pool.getName()));
maxLabelSets.add(Attributes.of(typeKey, MAX, poolKey, pool.getName()));
}
meter
.longUpDownSumObserverBuilder("jvm.memory.pool")
.upDownCounterBuilder("jvm.memory.pool")
.setDescription("Bytes of a given JVM memory pool.")
.setUnit("By")
.setUpdater(
.buildWithCallback(
resultLongObserver -> {
for (int i = 0; i < poolBeans.size(); i++) {
MemoryUsage poolUsage = poolBeans.get(i).getUsage();
@ -337,7 +328,6 @@ public class OpenTelemetrySystem implements ObservableMetricsSystem {
// max(used).
resultLongObserver.observe(poolUsage.getMax(), maxLabelSets.get(i));
}
})
.build();
});
}
}

@ -17,35 +17,41 @@ package org.hyperledger.besu.metrics.opentelemetry;
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
import org.hyperledger.besu.plugin.services.metrics.OperationTimer;
import java.util.ArrayList;
import java.util.List;
import io.opentelemetry.api.metrics.DoubleValueRecorder;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.metrics.Meter;
public class OpenTelemetryTimer implements LabelledMetric<OperationTimer> {
private final DoubleValueRecorder recorder;
private final String help;
private final Meter meter;
private final String metricName;
private final String[] labelNames;
public OpenTelemetryTimer(final DoubleValueRecorder recorder, final String... labelNames) {
this.recorder = recorder;
public OpenTelemetryTimer(
final String metricName, final String help, final Meter meter, final String... labelNames) {
this.metricName = metricName;
this.help = help;
this.meter = meter;
this.labelNames = labelNames;
}
@Override
public OperationTimer labels(final String... labelValues) {
List<String> labelKeysAndValues = new ArrayList<>();
AttributesBuilder builder = Attributes.builder();
for (int i = 0; i < labelNames.length; i++) {
labelKeysAndValues.add(labelNames[i]);
labelKeysAndValues.add(labelValues[i]);
builder.put(labelNames[i], labelValues[i]);
}
final Labels labels = Labels.of(labelKeysAndValues.toArray(new String[] {}));
final Attributes labels = builder.build();
return () -> {
final long startTime = System.nanoTime();
return () -> {
long elapsed = System.nanoTime() - startTime;
recorder.record(elapsed, labels);
meter
.gaugeBuilder(metricName)
.setDescription(help)
.buildWithCallback((measurement) -> measurement.observe(elapsed, labels));
return elapsed / 1e9;
};
};

Loading…
Cancel
Save