Skip to content

Commit ac96916

Browse files
committed
add lowecase + testing
1 parent 588f6d3 commit ac96916

File tree

4 files changed

+147
-5
lines changed

4 files changed

+147
-5
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.instrumentation.jmx.engine;
77

8+
import java.util.Locale;
89
import javax.annotation.Nullable;
910
import javax.management.MBeanServerConnection;
1011
import javax.management.ObjectName;
@@ -46,4 +47,20 @@ static MetricAttributeExtractor fromObjectNameParameter(String parameterKey) {
4647
static MetricAttributeExtractor fromBeanAttribute(String attributeName) {
4748
return BeanAttributeExtractor.fromName(attributeName);
4849
}
50+
51+
/**
52+
* Provides an extractor that will transform provided string value in lower-case
53+
*
54+
* @param extractor extractor to wrap
55+
* @return lower-case extractor
56+
*/
57+
static MetricAttributeExtractor toLowerCase(MetricAttributeExtractor extractor) {
58+
return (a, b) -> {
59+
String value = extractor.extractValue(a, b);
60+
if (value != null) {
61+
value = value.toLowerCase(Locale.ROOT);
62+
}
63+
return value;
64+
};
65+
}
4966
}

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

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,18 @@ private List<MetricAttribute> addMetricAttributes(Map<String, Object> metricAttr
136136
return list;
137137
}
138138

139-
private static MetricAttribute buildMetricAttribute(String key, String target) {
139+
// package protected for testing
140+
static MetricAttribute buildMetricAttribute(String key, String target) {
141+
142+
// an optional modifier may wrap the target
143+
// - lowercase(param(STRING))
144+
boolean lowercase = false;
145+
if (target.startsWith("lowercase(")) {
146+
lowercase = true;
147+
target = target.substring(10, target.lastIndexOf(')'));
148+
}
149+
150+
//
140151
// The recognized forms of target are:
141152
// - param(STRING)
142153
// - beanattr(STRING)
@@ -145,24 +156,32 @@ private static MetricAttribute buildMetricAttribute(String key, String target) {
145156
// or the direct value to use
146157
int k = target.indexOf(')');
147158

159+
MetricAttributeExtractor extractor = null;
160+
148161
// Check for one of the cases as above
149162
if (target.startsWith("param(")) {
150163
if (k > 0) {
151164
String jmxAttribute = target.substring(6, k).trim();
152-
return new MetricAttribute(
153-
key, MetricAttributeExtractor.fromObjectNameParameter(jmxAttribute));
165+
extractor = MetricAttributeExtractor.fromObjectNameParameter(jmxAttribute);
154166
}
155167
} else if (target.startsWith("beanattr(")) {
156168
if (k > 0) {
157169
String jmxAttribute = target.substring(9, k).trim();
158-
return new MetricAttribute(key, MetricAttributeExtractor.fromBeanAttribute(jmxAttribute));
170+
extractor = MetricAttributeExtractor.fromBeanAttribute(jmxAttribute);
159171
}
160172
} else if (target.startsWith("const(")) {
161173
if (k > 0) {
162174
String constantValue = target.substring(6, k).trim();
163-
return new MetricAttribute(key, MetricAttributeExtractor.fromConstant(constantValue));
175+
extractor = MetricAttributeExtractor.fromConstant(constantValue);
164176
}
165177
}
178+
if (extractor != null) {
179+
if (lowercase) {
180+
extractor = MetricAttributeExtractor.toLowerCase(extractor);
181+
}
182+
183+
return new MetricAttribute(key, extractor);
184+
}
166185

167186
String msg = "Invalid metric attribute specification for '" + key + "': " + target;
168187
throw new IllegalArgumentException(msg);

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,39 @@ void testStateMetricConf() throws Exception {
451451
});
452452
}
453453

454+
private static final String CONF10 =
455+
"--- # keep stupid spotlessJava at bay\n"
456+
+ "rules:\n"
457+
+ " - bean: my-test:type=10_Hello\n"
458+
+ " mapping:\n"
459+
+ " jmxAttribute:\n"
460+
+ " type: counter\n"
461+
+ " metric: my_metric\n"
462+
+ " metricAttribute:\n"
463+
+ " to_lower_const: lowercase(const(Hello))\n"
464+
+ " to_lower_attribute: lowercase(beanattr(beanAttribute))\n"
465+
+ " to_lower_param: lowercase(param(type))\n";
466+
467+
@Test
468+
void attributeValueLowercase() {
469+
470+
JmxConfig config = parseConf(CONF10);
471+
472+
List<JmxRule> rules = config.getRules();
473+
assertThat(rules).hasSize(1);
474+
JmxRule jmxRule = rules.get(0);
475+
476+
assertThat(jmxRule.getBean()).isEqualTo("my-test:type=10_Hello");
477+
Metric metric = jmxRule.getMapping().get("jmxAttribute");
478+
assertThat(metric.getMetricType()).isEqualTo(MetricInfo.Type.COUNTER);
479+
assertThat(metric.getMetric()).isEqualTo("my_metric");
480+
assertThat(metric.getMetricAttribute())
481+
.hasSize(3)
482+
.containsEntry("to_lower_const", "lowercase(const(Hello))")
483+
.containsEntry("to_lower_attribute", "lowercase(beanattr(beanAttribute))")
484+
.containsEntry("to_lower_param", "lowercase(param(type))");
485+
}
486+
454487
@Test
455488
void testEmptyConf() {
456489
JmxConfig config = parseConf(EMPTY_CONF);
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.jmx.yaml;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
import static org.mockito.Mockito.mock;
10+
import static org.mockito.Mockito.when;
11+
12+
import io.opentelemetry.instrumentation.jmx.engine.MetricAttribute;
13+
import javax.management.MBeanAttributeInfo;
14+
import javax.management.MBeanInfo;
15+
import javax.management.MBeanServerConnection;
16+
import javax.management.ObjectName;
17+
import org.junit.jupiter.params.ParameterizedTest;
18+
import org.junit.jupiter.params.provider.CsvSource;
19+
20+
public class MetricStructureTest {
21+
22+
@ParameterizedTest
23+
@CsvSource({"const(Hello),Hello", "lowercase(const(Hello)),hello"})
24+
void metricAttribute_constant(String target, String expectedValue) {
25+
MetricAttribute ma = MetricStructure.buildMetricAttribute("name", target);
26+
assertThat(ma.getAttributeName()).isEqualTo("name");
27+
assertThat(ma.isStateAttribute()).isFalse();
28+
assertThat(ma.acquireAttributeValue(null, null)).isEqualTo(expectedValue);
29+
}
30+
31+
@ParameterizedTest
32+
@CsvSource({
33+
"beanattr(beanAttribute),Hello,Hello",
34+
"lowercase(beanattr(beanAttribute)),Hello,hello",
35+
})
36+
void metricAttribute_beanAttribute(String target, String value, String expectedValue)
37+
throws Exception {
38+
MetricAttribute ma = MetricStructure.buildMetricAttribute("name", target);
39+
assertThat(ma.getAttributeName()).isEqualTo("name");
40+
assertThat(ma.isStateAttribute()).isFalse();
41+
42+
ObjectName objectName = new ObjectName("test:name=_beanAttribute");
43+
MBeanServerConnection mockConnection = mock(MBeanServerConnection.class);
44+
45+
MBeanInfo mockBeanInfo = mock(MBeanInfo.class);
46+
when(mockBeanInfo.getAttributes())
47+
.thenReturn(
48+
new MBeanAttributeInfo[] {
49+
new MBeanAttributeInfo("beanAttribute", "java.lang.String", "", true, false, false)
50+
});
51+
when(mockConnection.getMBeanInfo(objectName)).thenReturn(mockBeanInfo);
52+
when(mockConnection.getAttribute(objectName, "beanAttribute")).thenReturn(value);
53+
54+
assertThat(ma.acquireAttributeValue(mockConnection, objectName)).isEqualTo(expectedValue);
55+
}
56+
57+
@ParameterizedTest
58+
@CsvSource({
59+
"param(name),Hello,Hello",
60+
"lowercase(param(name)),Hello,hello",
61+
})
62+
void metricAttribute_beanParam(String target, String value, String expectedValue)
63+
throws Exception {
64+
MetricAttribute ma = MetricStructure.buildMetricAttribute("name", target);
65+
assertThat(ma.getAttributeName()).isEqualTo("name");
66+
assertThat(ma.isStateAttribute()).isFalse();
67+
68+
ObjectName objectName = new ObjectName("test:name=" + value);
69+
MBeanServerConnection mockConnection = mock(MBeanServerConnection.class);
70+
71+
assertThat(ma.acquireAttributeValue(mockConnection, objectName)).isEqualTo(expectedValue);
72+
}
73+
}

0 commit comments

Comments
 (0)