Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit 4859247

Browse files
authored
Metrics: Allow to set constant labels for Gauge APIs. (#1842)
1 parent 44906aa commit 4859247

13 files changed

Lines changed: 378 additions & 75 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## Unreleased
22
- Add HTTP text format serializer to Tag propagation component.
3+
- Support constant labels in Gauge APIs.
34

45
## 0.20.0 - 2019-03-28
56
- Add OpenCensus Java OC-Agent Trace Exporter.

api/src/main/java/io/opencensus/metrics/MetricOptions.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public abstract class MetricOptions {
4141
* <p>Default value is {@code ""}.
4242
*
4343
* @return the description of the Metric.
44+
* @since 0.20
4445
*/
4546
public abstract String getDescription();
4647

@@ -50,6 +51,7 @@ public abstract class MetricOptions {
5051
* <p>Default value is {@code "1"}.
5152
*
5253
* @return the unit of the Metric.
54+
* @since 0.20
5355
*/
5456
public abstract String getUnit();
5557

@@ -59,6 +61,7 @@ public abstract class MetricOptions {
5961
* <p>Default value is {@link Collections#emptyList()}.
6062
*
6163
* @return the list of label keys for the Metric.
64+
* @since 0.20
6265
*/
6366
public abstract List<LabelKey> getLabelKeys();
6467

@@ -68,9 +71,9 @@ public abstract class MetricOptions {
6871
* <p>Default value is {@link Collections#emptyMap()}.
6972
*
7073
* @return the map of constant labels for the Metric.
74+
* @since 0.21
7175
*/
72-
// TODO: add support for this and make it public.
73-
abstract Map<LabelKey, LabelValue> getConstantLabels();
76+
public abstract Map<LabelKey, LabelValue> getConstantLabels();
7477

7578
/**
7679
* Returns a new {@link Builder} with default options.
@@ -94,6 +97,7 @@ public abstract static class Builder {
9497
*
9598
* @param description the description of the Metric.
9699
* @return this.
100+
* @since 0.20
97101
*/
98102
public abstract Builder setDescription(String description);
99103

@@ -102,6 +106,7 @@ public abstract static class Builder {
102106
*
103107
* @param unit the unit of the Metric.
104108
* @return this.
109+
* @since 0.20
105110
*/
106111
public abstract Builder setUnit(String unit);
107112

@@ -110,6 +115,7 @@ public abstract static class Builder {
110115
*
111116
* @param labelKeys the list of label keys for the Metric.
112117
* @return this.
118+
* @since 0.20
113119
*/
114120
public abstract Builder setLabelKeys(List<LabelKey> labelKeys);
115121

@@ -118,9 +124,9 @@ public abstract static class Builder {
118124
*
119125
* @param constantLabels the map of constant labels for the Metric.
120126
* @return this.
127+
* @since 0.21
121128
*/
122-
// TODO: add support for this and make it public.
123-
abstract Builder setConstantLabels(Map<LabelKey, LabelValue> constantLabels);
129+
public abstract Builder setConstantLabels(Map<LabelKey, LabelValue> constantLabels);
124130

125131
abstract Map<LabelKey, LabelValue> getConstantLabels();
126132

api/src/test/java/io/opencensus/metrics/MetricRegistryTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.util.Collections;
2222
import java.util.List;
23+
import java.util.Map;
2324
import org.junit.Rule;
2425
import org.junit.Test;
2526
import org.junit.rules.ExpectedException;
@@ -40,12 +41,17 @@ public class MetricRegistryTest {
4041
private static final LabelKey LABEL_KEY = LabelKey.create("test_key", "test key description");
4142
private static final List<LabelKey> LABEL_KEYS = Collections.singletonList(LABEL_KEY);
4243
private static final LabelValue LABEL_VALUE = LabelValue.create("test_value");
44+
private static final LabelValue LABEL_VALUE_2 = LabelValue.create("test_value_2");
4345
private static final List<LabelValue> LABEL_VALUES = Collections.singletonList(LABEL_VALUE);
46+
private static final Map<LabelKey, LabelValue> CONSTANT_LABELS =
47+
Collections.singletonMap(
48+
LabelKey.create("test_key_1", "test key description"), LABEL_VALUE_2);
4449
private static final MetricOptions METRIC_OPTIONS =
4550
MetricOptions.builder()
4651
.setDescription(DESCRIPTION)
4752
.setUnit(UNIT)
4853
.setLabelKeys(LABEL_KEYS)
54+
.setConstantLabels(CONSTANT_LABELS)
4955
.build();
5056
private final MetricRegistry metricRegistry =
5157
MetricsComponent.newNoopMetricsComponent().getMetricRegistry();

impl_core/src/main/java/io/opencensus/implcore/metrics/DerivedDoubleGaugeImpl.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.LinkedHashMap;
3838
import java.util.List;
3939
import java.util.Map;
40+
import java.util.Map.Entry;
4041

4142
/*>>>
4243
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -46,14 +47,28 @@
4647
public final class DerivedDoubleGaugeImpl extends DerivedDoubleGauge implements Meter {
4748
private final MetricDescriptor metricDescriptor;
4849
private final int labelKeysSize;
50+
private final List<LabelValue> constantLabelValues;
4951

5052
private volatile Map<List<LabelValue>, PointWithFunction<?>> registeredPoints =
5153
Collections.<List<LabelValue>, PointWithFunction<?>>emptyMap();
5254

53-
DerivedDoubleGaugeImpl(String name, String description, String unit, List<LabelKey> labelKeys) {
54-
labelKeysSize = labelKeys.size();
55+
DerivedDoubleGaugeImpl(
56+
String name,
57+
String description,
58+
String unit,
59+
List<LabelKey> labelKeys,
60+
Map<LabelKey, LabelValue> constantLabels) {
61+
List<LabelValue> constantLabelValues = new ArrayList<LabelValue>();
62+
List<LabelKey> allKeys = new ArrayList<>(labelKeys);
63+
for (Entry<LabelKey, LabelValue> label : constantLabels.entrySet()) {
64+
// Ensure constant label keys and values are in the same order.
65+
allKeys.add(label.getKey());
66+
constantLabelValues.add(label.getValue());
67+
}
68+
labelKeysSize = allKeys.size();
5569
this.metricDescriptor =
56-
MetricDescriptor.create(name, description, unit, Type.GAUGE_DOUBLE, labelKeys);
70+
MetricDescriptor.create(name, description, unit, Type.GAUGE_DOUBLE, allKeys);
71+
this.constantLabelValues = Collections.unmodifiableList(constantLabelValues);
5772
}
5873

5974
@Override
@@ -62,14 +77,16 @@ public synchronized <T> void createTimeSeries(
6277
@javax.annotation.Nullable T obj,
6378
ToDoubleFunction</*@Nullable*/ T> function) {
6479
Utils.checkListElementNotNull(checkNotNull(labelValues, "labelValues"), "labelValue");
80+
List<LabelValue> labelValuesCopy = new ArrayList<LabelValue>(labelValues);
81+
labelValuesCopy.addAll(constantLabelValues);
82+
6583
checkArgument(
66-
labelKeysSize == labelValues.size(), "Label Keys and Label Values don't have same size.");
84+
labelKeysSize == labelValuesCopy.size(),
85+
"Label Keys and Label Values don't have same size.");
6786
checkNotNull(function, "function");
6887

69-
List<LabelValue> labelValuesCopy =
70-
Collections.<LabelValue>unmodifiableList(new ArrayList<LabelValue>(labelValues));
71-
72-
PointWithFunction<?> existingPoint = registeredPoints.get(labelValuesCopy);
88+
PointWithFunction<?> existingPoint =
89+
registeredPoints.get(Collections.unmodifiableList(labelValuesCopy));
7390
if (existingPoint != null) {
7491
throw new IllegalArgumentException(
7592
"A different time series with the same labels already exists.");
@@ -86,11 +103,13 @@ public synchronized <T> void createTimeSeries(
86103

87104
@Override
88105
public synchronized void removeTimeSeries(List<LabelValue> labelValues) {
89-
checkNotNull(labelValues, "labelValues");
106+
List<LabelValue> labelValuesCopy =
107+
new ArrayList<LabelValue>(checkNotNull(labelValues, "labelValues"));
108+
labelValuesCopy.addAll(constantLabelValues);
90109

91110
Map<List<LabelValue>, PointWithFunction<?>> registeredPointsCopy =
92111
new LinkedHashMap<List<LabelValue>, PointWithFunction<?>>(registeredPoints);
93-
if (registeredPointsCopy.remove(labelValues) == null) {
112+
if (registeredPointsCopy.remove(labelValuesCopy) == null) {
94113
// The element not present, no need to update the current map of time series.
95114
return;
96115
}

impl_core/src/main/java/io/opencensus/implcore/metrics/DerivedLongGaugeImpl.java

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.LinkedHashMap;
3838
import java.util.List;
3939
import java.util.Map;
40+
import java.util.Map.Entry;
4041

4142
/*>>>
4243
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -46,30 +47,46 @@
4647
public final class DerivedLongGaugeImpl extends DerivedLongGauge implements Meter {
4748
private final MetricDescriptor metricDescriptor;
4849
private final int labelKeysSize;
50+
private final List<LabelValue> constantLabelValues;
4951

5052
private volatile Map<List<LabelValue>, PointWithFunction<?>> registeredPoints =
5153
Collections.<List<LabelValue>, PointWithFunction<?>>emptyMap();
5254

53-
DerivedLongGaugeImpl(String name, String description, String unit, List<LabelKey> labelKeys) {
54-
labelKeysSize = labelKeys.size();
55+
DerivedLongGaugeImpl(
56+
String name,
57+
String description,
58+
String unit,
59+
List<LabelKey> labelKeys,
60+
Map<LabelKey, LabelValue> constantLabels) {
61+
List<LabelValue> constantLabelValues = new ArrayList<LabelValue>();
62+
List<LabelKey> allKeys = new ArrayList<>(labelKeys);
63+
for (Entry<LabelKey, LabelValue> label : constantLabels.entrySet()) {
64+
// Ensure constant label keys and values are in the same order.
65+
allKeys.add(label.getKey());
66+
constantLabelValues.add(label.getValue());
67+
}
68+
labelKeysSize = allKeys.size();
5569
this.metricDescriptor =
56-
MetricDescriptor.create(name, description, unit, Type.GAUGE_INT64, labelKeys);
70+
MetricDescriptor.create(name, description, unit, Type.GAUGE_INT64, allKeys);
71+
this.constantLabelValues = Collections.unmodifiableList(constantLabelValues);
5772
}
5873

5974
@Override
6075
public synchronized <T> void createTimeSeries(
6176
List<LabelValue> labelValues,
6277
@javax.annotation.Nullable T obj,
6378
ToLongFunction</*@Nullable*/ T> function) {
64-
Utils.checkListElementNotNull(checkNotNull(labelValues, "labelValues"), "labelValue");
65-
checkArgument(
66-
labelKeysSize == labelValues.size(), "Label Keys and Label Values don't have same size.");
6779
checkNotNull(function, "function");
80+
Utils.checkListElementNotNull(checkNotNull(labelValues, "labelValues"), "labelValue");
81+
List<LabelValue> labelValuesCopy = new ArrayList<LabelValue>(labelValues);
82+
labelValuesCopy.addAll(constantLabelValues);
6883

69-
List<LabelValue> labelValuesCopy =
70-
Collections.unmodifiableList(new ArrayList<LabelValue>(labelValues));
84+
checkArgument(
85+
labelKeysSize == labelValuesCopy.size(),
86+
"Label Keys and Label Values don't have same size.");
7187

72-
PointWithFunction<?> existingPoint = registeredPoints.get(labelValuesCopy);
88+
PointWithFunction<?> existingPoint =
89+
registeredPoints.get(Collections.unmodifiableList(labelValuesCopy));
7390
if (existingPoint != null) {
7491
throw new IllegalArgumentException(
7592
"A different time series with the same labels already exists.");
@@ -86,11 +103,13 @@ public synchronized <T> void createTimeSeries(
86103

87104
@Override
88105
public synchronized void removeTimeSeries(List<LabelValue> labelValues) {
89-
checkNotNull(labelValues, "labelValues");
106+
List<LabelValue> labelValuesCopy =
107+
new ArrayList<LabelValue>(checkNotNull(labelValues, "labelValues"));
108+
labelValuesCopy.addAll(constantLabelValues);
90109

91110
Map<List<LabelValue>, PointWithFunction<?>> registeredPointsCopy =
92111
new LinkedHashMap<List<LabelValue>, PointWithFunction<?>>(registeredPoints);
93-
if (registeredPointsCopy.remove(labelValues) == null) {
112+
if (registeredPointsCopy.remove(labelValuesCopy) == null) {
94113
// The element not present, no need to update the current map of time series.
95114
return;
96115
}

impl_core/src/main/java/io/opencensus/implcore/metrics/DoubleGaugeImpl.java

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.LinkedHashMap;
3838
import java.util.List;
3939
import java.util.Map;
40+
import java.util.Map.Entry;
4041
import javax.annotation.Nullable;
4142

4243
/** Implementation of {@link DoubleGauge}. */
@@ -48,17 +49,32 @@ public final class DoubleGaugeImpl extends DoubleGauge implements Meter {
4849
Collections.<List<LabelValue>, PointImpl>emptyMap();
4950
private final int labelKeysSize;
5051
private final List<LabelValue> defaultLabelValues;
51-
52-
DoubleGaugeImpl(String name, String description, String unit, List<LabelKey> labelKeys) {
53-
labelKeysSize = labelKeys.size();
52+
private final List<LabelValue> constantLabelValues;
53+
54+
DoubleGaugeImpl(
55+
String name,
56+
String description,
57+
String unit,
58+
List<LabelKey> labelKeys,
59+
Map<LabelKey, LabelValue> constantLabels) {
60+
List<LabelValue> constantLabelValues = new ArrayList<LabelValue>();
61+
List<LabelKey> allKeys = new ArrayList<>(labelKeys);
62+
for (Entry<LabelKey, LabelValue> label : constantLabels.entrySet()) {
63+
// Ensure constant label keys and values are in the same order.
64+
allKeys.add(label.getKey());
65+
constantLabelValues.add(label.getValue());
66+
}
67+
labelKeysSize = allKeys.size();
5468
this.metricDescriptor =
55-
MetricDescriptor.create(name, description, unit, Type.GAUGE_DOUBLE, labelKeys);
69+
MetricDescriptor.create(name, description, unit, Type.GAUGE_DOUBLE, allKeys);
70+
this.constantLabelValues = Collections.unmodifiableList(constantLabelValues);
5671

5772
// initialize defaultLabelValues
58-
defaultLabelValues = new ArrayList<LabelValue>(labelKeysSize);
59-
for (int i = 0; i < labelKeysSize; i++) {
73+
defaultLabelValues = new ArrayList<LabelValue>(labelKeys.size());
74+
for (int i = 0; i < labelKeys.size(); i++) {
6075
defaultLabelValues.add(UNSET_VALUE);
6176
}
77+
defaultLabelValues.addAll(constantLabelValues);
6278
}
6379

6480
@Override
@@ -70,9 +86,9 @@ public DoublePoint getOrCreateTimeSeries(List<LabelValue> labelValues) {
7086
}
7187

7288
List<LabelValue> labelValuesCopy =
73-
Collections.unmodifiableList(
74-
new ArrayList<LabelValue>(checkNotNull(labelValues, "labelValues")));
75-
return registerTimeSeries(labelValuesCopy);
89+
new ArrayList<LabelValue>(checkNotNull(labelValues, "labelValues"));
90+
labelValuesCopy.addAll(constantLabelValues);
91+
return registerTimeSeries(Collections.unmodifiableList(labelValuesCopy));
7692
}
7793

7894
@Override
@@ -87,11 +103,13 @@ public DoublePoint getDefaultTimeSeries() {
87103

88104
@Override
89105
public synchronized void removeTimeSeries(List<LabelValue> labelValues) {
90-
checkNotNull(labelValues, "labelValues");
106+
List<LabelValue> labelValuesCopy =
107+
new ArrayList<LabelValue>(checkNotNull(labelValues, "labelValues"));
108+
labelValuesCopy.addAll(constantLabelValues);
91109

92110
Map<List<LabelValue>, PointImpl> registeredPointsCopy =
93111
new LinkedHashMap<List<LabelValue>, PointImpl>(registeredPoints);
94-
if (registeredPointsCopy.remove(labelValues) == null) {
112+
if (registeredPointsCopy.remove(labelValuesCopy) == null) {
95113
// The element not present, no need to update the current map of points.
96114
return;
97115
}

0 commit comments

Comments
 (0)