Add Metric Instrument Registry (#11103)

* added metric instrument registry
This commit is contained in:
Vindhya Ningegowda 2024-04-12 13:42:40 -07:00 committed by GitHub
parent 34e241a60e
commit 497e155217
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 530 additions and 0 deletions

View File

@ -0,0 +1,30 @@
/*
* Copyright 2024 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 double-valued counter metric instrument.
*/
@Internal
public final class DoubleCounterMetricInstrument extends PartialMetricInstrument {
DoubleCounterMetricInstrument(long 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

@ -0,0 +1,38 @@
/*
* Copyright 2024 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 double-valued histogram metric instrument.
*/
@Internal
public final class DoubleHistogramMetricInstrument extends PartialMetricInstrument {
private final List<Double> bucketBoundaries;
DoubleHistogramMetricInstrument(long 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);
this.bucketBoundaries = bucketBoundaries;
}
public List<Double> getBucketBoundaries() {
return bucketBoundaries;
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2024 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 counter metric instrument.
*/
@Internal
public final class LongCounterMetricInstrument extends PartialMetricInstrument {
LongCounterMetricInstrument(long 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

@ -0,0 +1,30 @@
/*
* Copyright 2024 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 gauge metric instrument.
*/
@Internal
public final class LongGaugeMetricInstrument extends PartialMetricInstrument {
LongGaugeMetricInstrument(long 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

@ -0,0 +1,38 @@
/*
* Copyright 2024 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 histogram metric instrument.
*/
@Internal
public final class LongHistogramMetricInstrument extends PartialMetricInstrument {
private final List<Long> bucketBoundaries;
LongHistogramMetricInstrument(long 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);
this.bucketBoundaries = bucketBoundaries;
}
public List<Long> getBucketBoundaries() {
return bucketBoundaries;
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2024 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 metric instrument. Metric instrument contains information used to describe a metric.
*/
@Internal
public interface MetricInstrument {
/**
* Returns the unique index of this metric instrument.
*
* @return the index of the metric instrument.
*/
public long getIndex();
/**
* Returns the name of the metric.
*
* @return the name of the metric.
*/
public String getName();
/**
* Returns a description of the metric.
*
* @return a description of the metric.
*/
public String getDescription();
/**
* Returns the unit of measurement for the metric.
*
* @return the unit of measurement.
*/
public String getUnit();
/**
* Returns a list of required label keys for this metric instrument.
*
* @return a list of required label keys.
*/
public List<String> getRequiredLabelKeys();
/**
* Returns a list of optional label keys for this metric instrument.
*
* @return a list of optional label keys.
*/
public List<String> getOptionalLabelKeys();
/**
* Indicates whether this metric instrument is enabled by default.
*
* @return {@code true} if this metric instrument is enabled by default,
* {@code false} otherwise.
*/
public boolean isEnableByDefault();
}

View File

@ -0,0 +1,197 @@
/*
* Copyright 2024 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.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* A registry for globally registered metric instruments.
*/
@Internal
public final class MetricInstrumentRegistry {
private static MetricInstrumentRegistry instance;
private final List<MetricInstrument> metricInstruments;
private final Set<String> registeredMetricNames;
private MetricInstrumentRegistry() {
this.metricInstruments = new CopyOnWriteArrayList<>();
this.registeredMetricNames = new CopyOnWriteArraySet<>();
}
/**
* Returns the default metric instrument registry.
*/
public static synchronized MetricInstrumentRegistry getDefaultRegistry() {
if (instance == null) {
instance = new MetricInstrumentRegistry();
}
return instance;
}
/**
* Returns a list of registered metric instruments.
*/
public List<MetricInstrument> getMetricInstruments() {
return Collections.unmodifiableList(metricInstruments);
}
/**
* Registers a new Double 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 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,
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");
}
long instrumentIndex = metricInstruments.size();
DoubleCounterMetricInstrument instrument = new DoubleCounterMetricInstrument(
instrumentIndex, name, description, unit, requiredLabelKeys, optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}
/**
* Registers a new Long 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 LongCounterMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public synchronized 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");
}
// 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;
}
/**
* Registers a new Double Histogram 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 bucketBoundaries recommended set of explicit bucket boundaries for the histogram
* @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 DoubleHistogramMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public synchronized 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");
}
long indexToInsertInstrument = metricInstruments.size();
DoubleHistogramMetricInstrument instrument = new DoubleHistogramMetricInstrument(
indexToInsertInstrument, name, description, unit, bucketBoundaries, requiredLabelKeys,
optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}
/**
* Registers a new Long Histogram 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 bucketBoundaries recommended set of explicit bucket boundaries for the histogram
* @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 LongHistogramMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public synchronized 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");
}
long indexToInsertInstrument = metricInstruments.size();
LongHistogramMetricInstrument instrument = new LongHistogramMetricInstrument(
indexToInsertInstrument, name, description, unit, bucketBoundaries, requiredLabelKeys,
optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}
/**
* Registers a new Long Gauge 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 LongGaugeMetricInstrument
* @throws IllegalStateException if a metric with the same name already exists
*/
public synchronized LongGaugeMetricInstrument registerLongGauge(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");
}
long indexToInsertInstrument = metricInstruments.size();
LongGaugeMetricInstrument instrument = new LongGaugeMetricInstrument(
indexToInsertInstrument, name, description, unit, requiredLabelKeys, optionalLabelKeys,
enableByDefault);
metricInstruments.add(instrument);
registeredMetricNames.add(name);
return instrument;
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2024 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 com.google.common.collect.ImmutableList;
import java.util.List;
/**
* A partial implementation of the {@link MetricInstrument} interface. This class
* provides common fields and functionality for metric instruments.
*/
@Internal
abstract class PartialMetricInstrument implements MetricInstrument {
protected final long index;
protected final String name;
protected final String description;
protected final String unit;
protected final List<String> requiredLabelKeys;
protected final List<String> optionalLabelKeys;
protected final boolean enableByDefault;
/**
* Constructs a new PartialMetricInstrument with the specified attributes.
*
* @param index the unique index of this 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 for the metric
* @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,
List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean enableByDefault) {
this.index = index;
this.name = name;
this.description = description;
this.unit = unit;
this.requiredLabelKeys = ImmutableList.copyOf(requiredLabelKeys);
this.optionalLabelKeys = ImmutableList.copyOf(optionalLabelKeys);
this.enableByDefault = enableByDefault;
}
@Override
public long getIndex() {
return index;
}
@Override
public String getName() {
return name;
}
@Override
public String getDescription() {
return description;
}
@Override
public String getUnit() {
return unit;
}
@Override
public List<String> getRequiredLabelKeys() {
return requiredLabelKeys;
}
@Override
public List<String> getOptionalLabelKeys() {
return optionalLabelKeys;
}
@Override
public boolean isEnableByDefault() {
return enableByDefault;
}
}