Skip to content

Commit 8d93dbf

Browse files
committed
Added unit conversion support for YAML
1 parent 6dccc64 commit 8d93dbf

File tree

8 files changed

+69
-13
lines changed

8 files changed

+69
-13
lines changed

instrumentation/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/engine/MetricDef.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@
4242
// new MetricInfo(
4343
// "my.own.jvm.memory.pool.used",
4444
// "Pool memory currently used",
45+
// null,
4546
// "By",
4647
// MetricInfo.Type.UPDOWNCOUNTER);
4748
// MetricInfo poolLimitInfo =
4849
// new MetricInfo(
4950
// "my.own.jvm.memory.pool.limit",
5051
// "Maximum obtainable memory pool size",
52+
// null,
5153
// "By",
5254
// MetricInfo.Type.UPDOWNCOUNTER);
5355
//

instrumentation/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/engine/MetricInfo.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public enum Type {
2727
// How to report the metric using OpenTelemetry API
2828
private final String metricName; // used as Instrument name
2929
@Nullable private final String description;
30+
@Nullable private final String sourceUnit;
3031
@Nullable private final String unit;
3132
private final Type type;
3233

@@ -35,13 +36,19 @@ public enum Type {
3536
*
3637
* @param metricName a String that will be used as a metric name, it should be unique
3738
* @param description a human readable description of the metric
39+
* @param sourceUnit a human readable unit of measurement that is received from metric source
3840
* @param unit a human readable unit of measurement
3941
* @param type the instrument typ to be used for the metric
4042
*/
4143
public MetricInfo(
42-
String metricName, @Nullable String description, String unit, @Nullable Type type) {
44+
String metricName,
45+
@Nullable String description,
46+
@Nullable String sourceUnit,
47+
@Nullable String unit,
48+
@Nullable Type type) {
4349
this.metricName = metricName;
4450
this.description = description;
51+
this.sourceUnit = sourceUnit;
4552
this.unit = unit;
4653
this.type = type == null ? Type.GAUGE : type;
4754
}
@@ -55,6 +62,11 @@ public String getDescription() {
5562
return description;
5663
}
5764

65+
@Nullable
66+
public String getSourceUnit() {
67+
return sourceUnit;
68+
}
69+
5870
@Nullable
5971
public String getUnit() {
6072
return unit;

instrumentation/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/engine/MetricRegistrar.java

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616
import io.opentelemetry.api.metrics.Meter;
1717
import io.opentelemetry.api.metrics.ObservableDoubleMeasurement;
1818
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
19+
import io.opentelemetry.instrumentation.jmx.engine.unit.UnitConverter;
20+
import io.opentelemetry.instrumentation.jmx.engine.unit.UnitConverterFactory;
1921
import java.util.Collection;
2022
import java.util.Optional;
2123
import java.util.function.Consumer;
2224
import java.util.logging.Logger;
25+
import javax.annotation.Nullable;
2326
import javax.management.MBeanServerConnection;
2427
import javax.management.ObjectName;
2528

@@ -61,6 +64,7 @@ void enrollExtractor(
6164
return;
6265
}
6366

67+
boolean recordDoubleValue = attributeInfo.usesDoubleValues();
6468
MetricInfo metricInfo = extractor.getInfo();
6569
String metricName = metricInfo.getMetricName();
6670
MetricInfo.Type instrumentType = metricInfo.getType();
@@ -69,6 +73,12 @@ void enrollExtractor(
6973
? metricInfo.getDescription()
7074
: attributeInfo.getDescription();
7175
String unit = metricInfo.getUnit();
76+
String sourceUnit = metricInfo.getSourceUnit();
77+
78+
UnitConverter unitConverter = UnitConverterFactory.getConverter(sourceUnit, unit);
79+
if (unitConverter != null) {
80+
recordDoubleValue = unitConverter.isConvertingToDouble();
81+
}
7282

7383
switch (instrumentType) {
7484
// CHECKSTYLE:OFF
@@ -79,10 +89,10 @@ void enrollExtractor(
7989
Optional.ofNullable(description).ifPresent(builder::setDescription);
8090
Optional.ofNullable(unit).ifPresent(builder::setUnit);
8191

82-
if (attributeInfo.usesDoubleValues()) {
83-
builder.ofDoubles().buildWithCallback(doubleTypeCallback(extractor));
92+
if (recordDoubleValue) {
93+
builder.ofDoubles().buildWithCallback(doubleTypeCallback(extractor, unitConverter));
8494
} else {
85-
builder.buildWithCallback(longTypeCallback(extractor));
95+
builder.buildWithCallback(longTypeCallback(extractor, unitConverter));
8696
}
8797
logger.log(INFO, "Created Counter for {0}", metricName);
8898
}
@@ -96,10 +106,10 @@ void enrollExtractor(
96106
Optional.ofNullable(description).ifPresent(builder::setDescription);
97107
Optional.ofNullable(unit).ifPresent(builder::setUnit);
98108

99-
if (attributeInfo.usesDoubleValues()) {
100-
builder.ofDoubles().buildWithCallback(doubleTypeCallback(extractor));
109+
if (recordDoubleValue) {
110+
builder.ofDoubles().buildWithCallback(doubleTypeCallback(extractor, unitConverter));
101111
} else {
102-
builder.buildWithCallback(longTypeCallback(extractor));
112+
builder.buildWithCallback(longTypeCallback(extractor, unitConverter));
103113
}
104114
logger.log(INFO, "Created UpDownCounter for {0}", metricName);
105115
}
@@ -113,10 +123,10 @@ void enrollExtractor(
113123
Optional.ofNullable(description).ifPresent(builder::setDescription);
114124
Optional.ofNullable(unit).ifPresent(builder::setUnit);
115125

116-
if (attributeInfo.usesDoubleValues()) {
117-
builder.buildWithCallback(doubleTypeCallback(extractor));
126+
if (recordDoubleValue) {
127+
builder.buildWithCallback(doubleTypeCallback(extractor, unitConverter));
118128
} else {
119-
builder.ofLongs().buildWithCallback(longTypeCallback(extractor));
129+
builder.ofLongs().buildWithCallback(longTypeCallback(extractor, unitConverter));
120130
}
121131
logger.log(INFO, "Created Gauge for {0}", metricName);
122132
}
@@ -133,8 +143,10 @@ void enrollExtractor(
133143
/*
134144
* A method generating metric collection callback for asynchronous Measurement
135145
* of Double type.
146+
* If unit converter is provided then conversion is applied before metric is recorded.
136147
*/
137-
static Consumer<ObservableDoubleMeasurement> doubleTypeCallback(MetricExtractor extractor) {
148+
static Consumer<ObservableDoubleMeasurement> doubleTypeCallback(
149+
MetricExtractor extractor, @Nullable UnitConverter unitConverter) {
138150
return measurement -> {
139151
DetectionStatus status = extractor.getStatus();
140152
if (status != null) {
@@ -145,6 +157,10 @@ static Consumer<ObservableDoubleMeasurement> doubleTypeCallback(MetricExtractor
145157
if (metricValue != null) {
146158
// get the metric attributes
147159
Attributes attr = createMetricAttributes(connection, objectName, extractor);
160+
161+
if (unitConverter != null) {
162+
metricValue = unitConverter.convert(metricValue);
163+
}
148164
measurement.record(metricValue.doubleValue(), attr);
149165
}
150166
}
@@ -155,8 +171,10 @@ static Consumer<ObservableDoubleMeasurement> doubleTypeCallback(MetricExtractor
155171
/*
156172
* A method generating metric collection callback for asynchronous Measurement
157173
* of Long type.
174+
* If unit converter is provided then conversion is applied before metric is recorded.
158175
*/
159-
static Consumer<ObservableLongMeasurement> longTypeCallback(MetricExtractor extractor) {
176+
static Consumer<ObservableLongMeasurement> longTypeCallback(
177+
MetricExtractor extractor, @Nullable UnitConverter unitConverter) {
160178
return measurement -> {
161179
DetectionStatus status = extractor.getStatus();
162180
if (status != null) {
@@ -167,6 +185,10 @@ static Consumer<ObservableLongMeasurement> longTypeCallback(MetricExtractor extr
167185
if (metricValue != null) {
168186
// get the metric attributes
169187
Attributes attr = createMetricAttributes(connection, objectName, extractor);
188+
189+
if (unitConverter != null) {
190+
metricValue = unitConverter.convert(metricValue);
191+
}
170192
measurement.record(metricValue.longValue(), attr);
171193
}
172194
}

instrumentation/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/yaml/JmxRule.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ public MetricDef buildMetricDef() throws Exception {
152152
new MetricInfo(
153153
prefix == null ? niceAttributeName : (prefix + niceAttributeName),
154154
null,
155+
getSourceUnit(),
155156
getUnit(),
156157
getMetricType());
157158
} else {
@@ -226,6 +227,7 @@ protected Number extractNumericalAttribute(
226227
new MetricInfo(
227228
metricInfo.getMetricName(),
228229
metricInfo.getDescription(),
230+
metricInfo.getSourceUnit(),
229231
metricInfo.getUnit(),
230232
MetricInfo.Type.UPDOWNCOUNTER);
231233

instrumentation/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/yaml/Metric.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,13 @@ MetricInfo buildMetricInfo(
6161
metricType = defaultType;
6262
}
6363

64+
String sourceUnit = getSourceUnit();
65+
6466
String unit = getUnit();
6567
if (unit == null) {
6668
unit = defaultUnit;
6769
}
6870

69-
return new MetricInfo(metricName, desc, unit, metricType);
71+
return new MetricInfo(metricName, desc, sourceUnit, unit, metricType);
7072
}
7173
}

instrumentation/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/yaml/MetricStructure.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ abstract class MetricStructure {
4545
private Map<String, Object> metricAttribute;
4646
private StateMapping stateMapping = StateMapping.empty();
4747
private static final String STATE_MAPPING_DEFAULT = "*";
48+
private String sourcetUnit;
4849
private String unit;
4950

5051
private MetricInfo.Type metricType;
@@ -58,6 +59,14 @@ void setType(String t) {
5859
this.metricType = MetricInfo.Type.valueOf(t);
5960
}
6061

62+
public String getSourceUnit() {
63+
return sourcetUnit;
64+
}
65+
66+
public void setSourceUnit(String unit) {
67+
this.sourcetUnit = validateUnit(unit.trim());
68+
}
69+
6170
public String getUnit() {
6271
return unit;
6372
}

instrumentation/jmx-metrics/library/src/main/java/io/opentelemetry/instrumentation/jmx/yaml/RuleParser.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ private static void parseMetricStructure(
142142
if (unit != null) {
143143
out.setUnit(unit);
144144
}
145+
String sourceUnit = (String) metricStructureYaml.remove("sourceUnit");
146+
if (sourceUnit != null) {
147+
out.setSourceUnit(sourceUnit);
148+
}
145149
}
146150

147151
private static void failOnExtraKeys(Map<String, Object> yaml) {

instrumentation/jmx-metrics/library/src/test/java/io/opentelemetry/instrumentation/jmx/engine/RuleParserTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static void setup() {
6363
+ " ATTRIBUTE2:\n"
6464
+ " metric: METRIC_NAME2\n"
6565
+ " desc: DESCRIPTION2\n"
66+
+ " sourceUnit: SOURCE_UNIT2\n"
6667
+ " unit: UNIT2\n"
6768
+ " ATTRIBUTE3:\n"
6869
+ " ATTRIBUTE4:\n"
@@ -95,13 +96,15 @@ void testConf2() {
9596
assertThat(m1).isNotNull();
9697
assertThat(m1.getMetric()).isEqualTo("METRIC_NAME1");
9798
assertThat(m1.getMetricType()).isEqualTo(MetricInfo.Type.GAUGE);
99+
assertThat(m1.getSourceUnit()).isNull();
98100
assertThat(m1.getUnit()).isEqualTo("UNIT1");
99101
assertThat(m1.getMetricAttribute()).containsExactly(entry("LABEL_KEY3", "const(CONSTANT)"));
100102

101103
Metric m2 = attr.get("ATTRIBUTE2");
102104
assertThat(m2).isNotNull();
103105
assertThat(m2.getMetric()).isEqualTo("METRIC_NAME2");
104106
assertThat(m2.getDesc()).isEqualTo("DESCRIPTION2");
107+
assertThat(m2.getSourceUnit()).isEqualTo("SOURCE_UNIT2");
105108
assertThat(m2.getUnit()).isEqualTo("UNIT2");
106109

107110
JmxRule def2 = defs.get(1);

0 commit comments

Comments
 (0)