Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MetricRecorder implementation #11128

Merged
merged 7 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
@Internal
public final class DoubleCounterMetricInstrument extends PartialMetricInstrument {
DoubleCounterMetricInstrument(long index, String name, String description, String unit,
public DoubleCounterMetricInstrument(int index, String name, String description, String unit,
DNVindhya marked this conversation as resolved.
Show resolved Hide resolved
List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean enableByDefault) {
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
public final class DoubleHistogramMetricInstrument extends PartialMetricInstrument {
private final List<Double> bucketBoundaries;

DoubleHistogramMetricInstrument(long index, String name, String description, String unit,
public DoubleHistogramMetricInstrument(int index, String name, String description, String unit,
List<Double> bucketBoundaries, List<String> requiredLabelKeys, List<String> optionalLabelKeys,
boolean enableByDefault) {
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/io/grpc/LongCounterMetricInstrument.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
@Internal
public final class LongCounterMetricInstrument extends PartialMetricInstrument {
LongCounterMetricInstrument(long index, String name, String description, String unit,
public LongCounterMetricInstrument(int index, String name, String description, String unit,
List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean enableByDefault) {
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
}
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/io/grpc/LongGaugeMetricInstrument.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
@Internal
public final class LongGaugeMetricInstrument extends PartialMetricInstrument {
LongGaugeMetricInstrument(long index, String name, String description, String unit,
public LongGaugeMetricInstrument(int index, String name, String description, String unit,
List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean enableByDefault) {
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
public final class LongHistogramMetricInstrument extends PartialMetricInstrument {
private final List<Long> bucketBoundaries;

LongHistogramMetricInstrument(long index, String name, String description, String unit,
public LongHistogramMetricInstrument(int index, String name, String description, String unit,
List<Long> bucketBoundaries, List<String> requiredLabelKeys, List<String> optionalLabelKeys,
boolean enableByDefault) {
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/io/grpc/MetricInstrument.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface MetricInstrument {
*
* @return the index of the metric instrument.
*/
public long getIndex();
public int getIndex();

/**
* Returns the name of the metric.
Expand Down
150 changes: 96 additions & 54 deletions api/src/main/java/io/grpc/MetricInstrumentRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,36 @@

package io.grpc;

import java.util.Collections;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

/**
* A registry for globally registered metric instruments.
*/
@Internal
public final class MetricInstrumentRegistry {
private static final int DEFAULT_INSTRUMENT_LIST_CAPACITY = 20;
private static MetricInstrumentRegistry instance;
private final List<MetricInstrument> metricInstruments;
private final Object lock = new Object();
private final Set<String> registeredMetricNames;
private final AtomicInteger instrumentIndexAlloc = new AtomicInteger();
ejona86 marked this conversation as resolved.
Show resolved Hide resolved
private volatile List<MetricInstrument> metricInstruments;
private volatile int instrumentListCapacity = DEFAULT_INSTRUMENT_LIST_CAPACITY;
ejona86 marked this conversation as resolved.
Show resolved Hide resolved

private MetricInstrumentRegistry() {
this.metricInstruments = new CopyOnWriteArrayList<>();
this.registeredMetricNames = new CopyOnWriteArraySet<>();
this(new ArrayList<>(DEFAULT_INSTRUMENT_LIST_CAPACITY), new HashSet<>());
}

@VisibleForTesting
MetricInstrumentRegistry(List<MetricInstrument> metricInstruments,
Set<String> registeredMetricNames) {
this.metricInstruments = metricInstruments;
this.registeredMetricNames = registeredMetricNames;
}

/**
Expand All @@ -50,7 +62,7 @@ public static synchronized MetricInstrumentRegistry getDefaultRegistry() {
* Returns a list of registered metric instruments.
*/
public List<MetricInstrument> getMetricInstruments() {
return Collections.unmodifiableList(metricInstruments);
return ImmutableList.copyOf(metricInstruments);
ejona86 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -65,20 +77,25 @@ public List<MetricInstrument> getMetricInstruments() {
* @return the newly created DoubleCounterMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
// TODO(dnvindhya): Evaluate locks over synchronized methods and update if needed
public synchronized DoubleCounterMetricInstrument registerDoubleCounter(String name,
public DoubleCounterMetricInstrument registerDoubleCounter(String name,
String description, String unit, List<String> requiredLabelKeys,
List<String> optionalLabelKeys, boolean enableByDefault) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
// Null check for arguments
synchronized (lock) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
}
int index = instrumentIndexAlloc.getAndIncrement();
if (index + 1 == instrumentListCapacity) {
resizeMetricInstruments();
}
DoubleCounterMetricInstrument instrument = new DoubleCounterMetricInstrument(
index, name, description, unit, requiredLabelKeys, optionalLabelKeys,
enableByDefault);
metricInstruments.add(index, instrument);
registeredMetricNames.add(name);
return instrument;
}
long instrumentIndex = metricInstruments.size();
DoubleCounterMetricInstrument instrument = new DoubleCounterMetricInstrument(
instrumentIndex, name, description, unit, requiredLabelKeys, optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}

/**
Expand All @@ -93,20 +110,24 @@ public synchronized DoubleCounterMetricInstrument registerDoubleCounter(String n
* @return the newly created LongCounterMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public synchronized LongCounterMetricInstrument registerLongCounter(String name,
public LongCounterMetricInstrument registerLongCounter(String name,
String description, String unit, List<String> requiredLabelKeys,
List<String> optionalLabelKeys, boolean enableByDefault) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
synchronized (lock) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
}
int index = instrumentIndexAlloc.getAndIncrement();
if (index + 1 == instrumentListCapacity) {
resizeMetricInstruments();
}
LongCounterMetricInstrument instrument = new LongCounterMetricInstrument(
index, name, description, unit, requiredLabelKeys, optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}
// Acquire lock?
long instrumentIndex = metricInstruments.size();
LongCounterMetricInstrument instrument = new LongCounterMetricInstrument(
instrumentIndex, name, description, unit, requiredLabelKeys, optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}

/**
Expand All @@ -122,20 +143,25 @@ public synchronized LongCounterMetricInstrument registerLongCounter(String name,
* @return the newly created DoubleHistogramMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public synchronized DoubleHistogramMetricInstrument registerDoubleHistogram(String name,
public DoubleHistogramMetricInstrument registerDoubleHistogram(String name,
String description, String unit, List<Double> bucketBoundaries,
List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean enableByDefault) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
synchronized (lock) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
}
int index = instrumentIndexAlloc.getAndIncrement();
if (index + 1 == instrumentListCapacity) {
resizeMetricInstruments();
}
DoubleHistogramMetricInstrument instrument = new DoubleHistogramMetricInstrument(
index, name, description, unit, bucketBoundaries, requiredLabelKeys,
optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}
long indexToInsertInstrument = metricInstruments.size();
DoubleHistogramMetricInstrument instrument = new DoubleHistogramMetricInstrument(
indexToInsertInstrument, name, description, unit, bucketBoundaries, requiredLabelKeys,
optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}

/**
Expand All @@ -151,20 +177,25 @@ public synchronized DoubleHistogramMetricInstrument registerDoubleHistogram(Stri
* @return the newly created LongHistogramMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public synchronized LongHistogramMetricInstrument registerLongHistogram(String name,
public LongHistogramMetricInstrument registerLongHistogram(String name,
String description, String unit, List<Long> bucketBoundaries, List<String> requiredLabelKeys,
List<String> optionalLabelKeys, boolean enableByDefault) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
synchronized (lock) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
}
int index = instrumentIndexAlloc.getAndIncrement();
if (index + 1 == instrumentListCapacity) {
resizeMetricInstruments();
}
LongHistogramMetricInstrument instrument = new LongHistogramMetricInstrument(
index, name, description, unit, bucketBoundaries, requiredLabelKeys,
optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}
long indexToInsertInstrument = metricInstruments.size();
LongHistogramMetricInstrument instrument = new LongHistogramMetricInstrument(
indexToInsertInstrument, name, description, unit, bucketBoundaries, requiredLabelKeys,
optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}


Expand All @@ -180,18 +211,29 @@ public synchronized LongHistogramMetricInstrument registerLongHistogram(String n
* @return the newly created LongGaugeMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public synchronized LongGaugeMetricInstrument registerLongGauge(String name, String description,
public LongGaugeMetricInstrument registerLongGauge(String name, String description,
ejona86 marked this conversation as resolved.
Show resolved Hide resolved
String unit, List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean
enableByDefault) {
if (registeredMetricNames.contains(name)) {
throw new IllegalStateException("Metric with name " + name + " already exists");
}
long indexToInsertInstrument = metricInstruments.size();
int index = instrumentIndexAlloc.getAndIncrement();
if (index + 1 == metricInstruments.size()) {
resizeMetricInstruments();
}
LongGaugeMetricInstrument instrument = new LongGaugeMetricInstrument(
indexToInsertInstrument, name, description, unit, requiredLabelKeys, optionalLabelKeys,
index, name, description, unit, requiredLabelKeys, optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}

private synchronized void resizeMetricInstruments() {
// Resize by factor of DEFAULT_INSTRUMENT_LIST_CAPACITY
instrumentListCapacity = metricInstruments.size() + DEFAULT_INSTRUMENT_LIST_CAPACITY + 1;
List<MetricInstrument> newList = new ArrayList<>(instrumentListCapacity);
newList.addAll(metricInstruments);
metricInstruments = newList;
}
}
2 changes: 2 additions & 0 deletions api/src/main/java/io/grpc/MetricSink.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,6 @@ default void recordDoubleHistogram(DoubleHistogramMetricInstrument metricInstrum
default void recordLongHistogram(LongHistogramMetricInstrument metricInstrument, long value,
List<String> requiredLabelValues, List<String> optionalLabelValues) {
}

default void updateMeasures(List<MetricInstrument> instruments) {}
}
6 changes: 3 additions & 3 deletions api/src/main/java/io/grpc/PartialMetricInstrument.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*/
@Internal
abstract class PartialMetricInstrument implements MetricInstrument {
protected final long index;
protected final int index;
protected final String name;
protected final String description;
protected final String unit;
Expand All @@ -44,7 +44,7 @@ abstract class PartialMetricInstrument implements MetricInstrument {
* @param optionalLabelKeys a list of optional label keys for the metric
* @param enableByDefault whether the metric should be enabled by default
*/
protected PartialMetricInstrument(long index, String name, String description, String unit,
protected PartialMetricInstrument(int index, String name, String description, String unit,
List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean enableByDefault) {
this.index = index;
this.name = name;
Expand All @@ -56,7 +56,7 @@ protected PartialMetricInstrument(long index, String name, String description, S
}

@Override
public long getIndex() {
public int getIndex() {
return index;
}

Expand Down