otel: add LongUpDownCounterMetricInstrument

This commit is contained in:
AgraVator 2025-07-07 13:24:49 +05:30
parent a06568cdce
commit daf901b1d5
6 changed files with 136 additions and 7 deletions

View File

@ -0,0 +1,32 @@
/*
* Copyright 2025 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import java.util.List;
/**
* Represents a long-valued up down counter metric instrument.
*/
@Internal
public final class LongUpDownCounterMetricInstrument extends PartialMetricInstrument {
public LongUpDownCounterMetricInstrument(int index, String name, String description, String unit,
List<String> requiredLabelKeys,
List<String> optionalLabelKeys,
boolean enableByDefault) {
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
}
}

View File

@ -144,6 +144,47 @@ public final class MetricInstrumentRegistry {
}
}
/**
* Registers a new Long Up Down Counter metric instrument.
*
* @param name the name of the metric
* @param description a description of the metric
* @param unit the unit of measurement for the metric
* @param requiredLabelKeys a list of required label keys
* @param optionalLabelKeys a list of optional label keys
* @param enableByDefault whether the metric should be enabled by default
* @return the newly created LongUpDownCounterMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public LongUpDownCounterMetricInstrument registerLongUpDownCounter(String name,
String description,
String unit,
List<String> requiredLabelKeys,
List<String> optionalLabelKeys,
boolean enableByDefault) {
checkArgument(!Strings.isNullOrEmpty(name), "missing metric name");
checkNotNull(description, "description");
checkNotNull(unit, "unit");
checkNotNull(requiredLabelKeys, "requiredLabelKeys");
checkNotNull(optionalLabelKeys, "optionalLabelKeys");
synchronized (lock) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
}
int index = nextAvailableMetricIndex;
if (index + 1 == metricInstruments.length) {
resizeMetricInstruments();
}
LongUpDownCounterMetricInstrument instrument = new LongUpDownCounterMetricInstrument(
index, name, description, unit, requiredLabelKeys, optionalLabelKeys,
enableByDefault);
metricInstruments[index] = instrument;
registeredMetricNames.add(name);
nextAvailableMetricIndex += 1;
return instrument;
}
}
/**
* Registers a new Double Histogram metric instrument.
*

View File

@ -50,7 +50,7 @@ public interface MetricRecorder {
* Adds a value for a long valued counter metric instrument.
*
* @param metricInstrument The counter metric instrument to add the value against.
* @param value The value to add.
* @param value The value to add. MUST be non-negative.
* @param requiredLabelValues A list of required label values for the metric.
* @param optionalLabelValues A list of additional, optional label values for the metric.
*/
@ -66,6 +66,29 @@ public interface MetricRecorder {
metricInstrument.getOptionalLabelKeys().size());
}
/**
* Adds a value for a long valued up down counter metric instrument.
*
* @param metricInstrument The counter metric instrument to add the value against.
* @param value The value to add. May be positive, negative or zero.
* @param requiredLabelValues A list of required label values for the metric.
* @param optionalLabelValues A list of additional, optional label values for the metric.
*/
default void addLongUpDownCounter(LongUpDownCounterMetricInstrument metricInstrument,
long value,
List<String> requiredLabelValues,
List<String> optionalLabelValues) {
checkArgument(requiredLabelValues != null
&& requiredLabelValues.size() == metricInstrument.getRequiredLabelKeys().size(),
"Incorrect number of required labels provided. Expected: %s",
metricInstrument.getRequiredLabelKeys().size());
checkArgument(optionalLabelValues != null
&& optionalLabelValues.size() == metricInstrument.getOptionalLabelKeys().size(),
"Incorrect number of optional labels provided. Expected: %s",
metricInstrument.getOptionalLabelKeys().size());
}
/**
* Records a value for a double-precision histogram metric instrument.
*

View File

@ -65,12 +65,26 @@ public interface MetricSink {
* Adds a value for a long valued counter metric associated with specified metric instrument.
*
* @param metricInstrument The counter metric instrument identifies metric measure to add.
* @param value The value to record.
* @param value The value to record. MUST be non-negative.
* @param requiredLabelValues A list of required label values for the metric.
* @param optionalLabelValues A list of additional, optional label values for the metric.
*/
default void addLongCounter(LongCounterMetricInstrument metricInstrument, long value,
List<String> requiredLabelValues, List<String> optionalLabelValues) {
List<String> requiredLabelValues, List<String> optionalLabelValues) {
}
/**
* Adds a value for a long valued up down counter metric associated with specified metric
* instrument.
*
* @param metricInstrument The counter metric instrument identifies metric measure to add.
* @param value The value to record. May be positive, negative or zero.
* @param requiredLabelValues A list of required label values for the metric.
* @param optionalLabelValues A list of additional, optional label values for the metric.
*/
default void addLongUpDownCounter(LongUpDownCounterMetricInstrument metricInstrument, long value,
List<String> requiredLabelValues,
List<String> optionalLabelValues) {
}
/**

View File

@ -19,6 +19,7 @@ package io.grpc.internal;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import io.grpc.LongCounterMetricInstrument;
import io.grpc.LongUpDownCounterMetricInstrument;
import io.grpc.MetricInstrumentRegistry;
import io.grpc.MetricRecorder;
@ -27,7 +28,7 @@ public final class SubchannelMetrics {
private static final LongCounterMetricInstrument disconnections;
private static final LongCounterMetricInstrument connectionAttemptsSucceeded;
private static final LongCounterMetricInstrument connectionAttemptsFailed;
private static final LongCounterMetricInstrument openConnections;
private static final LongUpDownCounterMetricInstrument openConnections;
private final MetricRecorder metricRecorder;
public SubchannelMetrics(MetricRecorder metricRecorder) {
@ -64,7 +65,7 @@ public final class SubchannelMetrics {
false
);
openConnections = metricInstrumentRegistry.registerLongCounter(
openConnections = metricInstrumentRegistry.registerLongUpDownCounter(
"grpc.subchannel.open_connections",
"EXPERIMENTAL. Number of open connections.",
"{connection}",
@ -80,7 +81,7 @@ public final class SubchannelMetrics {
ImmutableList.of(labelSet.target),
ImmutableList.of(labelSet.backendService, labelSet.locality));
metricRecorder
.addLongCounter(openConnections, 1,
.addLongUpDownCounter(openConnections, 1,
ImmutableList.of(labelSet.target),
ImmutableList.of(labelSet.securityLevel, labelSet.backendService, labelSet.locality));
}
@ -98,7 +99,7 @@ public final class SubchannelMetrics {
ImmutableList.of(labelSet.target),
ImmutableList.of(labelSet.backendService, labelSet.locality, labelSet.disconnectError));
metricRecorder
.addLongCounter(openConnections, -11,
.addLongUpDownCounter(openConnections, -1,
ImmutableList.of(labelSet.target),
ImmutableList.of(labelSet.securityLevel, labelSet.backendService, labelSet.locality));
}

View File

@ -27,6 +27,7 @@ import io.grpc.DoubleHistogramMetricInstrument;
import io.grpc.LongCounterMetricInstrument;
import io.grpc.LongGaugeMetricInstrument;
import io.grpc.LongHistogramMetricInstrument;
import io.grpc.LongUpDownCounterMetricInstrument;
import io.grpc.MetricInstrument;
import io.grpc.MetricSink;
import io.opentelemetry.api.common.Attributes;
@ -36,6 +37,7 @@ import io.opentelemetry.api.metrics.DoubleCounter;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.LongHistogram;
import io.opentelemetry.api.metrics.LongUpDownCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
import io.opentelemetry.api.metrics.ObservableMeasurement;
@ -117,6 +119,22 @@ final class OpenTelemetryMetricSink implements MetricSink {
counter.add(value, attributes);
}
@Override
public void addLongUpDownCounter(LongUpDownCounterMetricInstrument metricInstrument, long value,
List<String> requiredLabelValues,
List<String> optionalLabelValues) {
MeasuresData instrumentData = measures.get(metricInstrument.getIndex());
if (instrumentData == null) {
// Disabled metric
return;
}
Attributes attributes = createAttributes(metricInstrument.getRequiredLabelKeys(),
metricInstrument.getOptionalLabelKeys(), requiredLabelValues, optionalLabelValues,
instrumentData.getOptionalLabelsBitSet());
LongUpDownCounter counter = (LongUpDownCounter) instrumentData.getMeasure();
counter.add(value, attributes);
}
@Override
public void recordDoubleHistogram(DoubleHistogramMetricInstrument metricInstrument, double value,
List<String> requiredLabelValues, List<String> optionalLabelValues) {