Skip to content

Commit f1ea742

Browse files
authored
jmx-scraper add missing custom yaml support (#1741)
1 parent 79ba066 commit f1ea742

File tree

5 files changed

+95
-4
lines changed

5 files changed

+95
-4
lines changed

jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxScraperContainer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ public JmxScraperContainer withExtraJar(String jarPath) {
100100
return this;
101101
}
102102

103+
/**
104+
* Adds custom metrics yaml from classpath resource
105+
*
106+
* @param yamlPath path to resource in classpath
107+
* @return this
108+
*/
103109
@CanIgnoreReturnValue
104110
public JmxScraperContainer withCustomYaml(String yamlPath) {
105111
this.customYamlFiles.add(yamlPath);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.jmxscraper.target_systems;
7+
8+
import io.opentelemetry.contrib.jmxscraper.JmxScraperContainer;
9+
import io.opentelemetry.contrib.jmxscraper.TestAppContainer;
10+
import java.nio.file.Path;
11+
import org.testcontainers.containers.GenericContainer;
12+
import org.testcontainers.containers.wait.strategy.Wait;
13+
14+
public class CustomIntegrationTest extends TargetSystemIntegrationTest {
15+
16+
@Override
17+
protected GenericContainer<?> createTargetContainer(int jmxPort) {
18+
// reusing test application for custom yaml
19+
//noinspection resource
20+
return new TestAppContainer()
21+
.withJmxPort(jmxPort)
22+
.withExposedPorts(jmxPort)
23+
.waitingFor(Wait.forListeningPorts(jmxPort));
24+
}
25+
26+
@Override
27+
protected JmxScraperContainer customizeScraperContainer(
28+
JmxScraperContainer scraper, GenericContainer<?> target, Path tempDir) {
29+
// only testing custom yaml
30+
return scraper.withCustomYaml("custom-metrics.yaml");
31+
}
32+
33+
@Override
34+
protected MetricsVerifier createMetricsVerifier() {
35+
return MetricsVerifier.create()
36+
// custom metric in custom-metrics.yaml
37+
.add(
38+
"custom.jvm.uptime",
39+
metric ->
40+
metric
41+
.hasDescription("JVM uptime in milliseconds")
42+
.hasUnit("ms")
43+
.isCounter()
44+
.hasDataPointsWithoutAttributes());
45+
}
46+
}

jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/JvmIntegrationTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ protected GenericContainer<?> createTargetContainer(int jmxPort) {
3030
@Override
3131
protected JmxScraperContainer customizeScraperContainer(
3232
JmxScraperContainer scraper, GenericContainer<?> target, Path tempDir) {
33-
return scraper.withTargetSystem("jvm");
33+
return scraper
34+
.withTargetSystem("jvm")
35+
// also testing custom yaml
36+
.withCustomYaml("custom-metrics.yaml");
3437
}
3538

3639
@Override
@@ -48,6 +51,16 @@ protected MetricsVerifier createMetricsVerifier() {
4851
nameAttributeMatchers("PS MarkSweep", "PS Scavenge");
4952

5053
return MetricsVerifier.create()
54+
// custom metric in custom-metrics.yaml
55+
.add(
56+
"custom.jvm.uptime",
57+
metric ->
58+
metric
59+
.hasDescription("JVM uptime in milliseconds")
60+
.hasUnit("ms")
61+
.isCounter()
62+
.hasDataPointsWithoutAttributes())
63+
// metrics for 'jvm' target system
5164
.add(
5265
"jvm.classes.loaded",
5366
metric ->
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
3+
rules:
4+
5+
- bean: java.lang:type=Runtime
6+
mapping:
7+
Uptime:
8+
metric: custom.jvm.uptime
9+
type: counter
10+
unit: ms
11+
desc: JVM uptime in milliseconds

jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.io.IOException;
1919
import java.io.InputStream;
2020
import java.nio.file.Files;
21+
import java.nio.file.Path;
2122
import java.nio.file.Paths;
2223
import java.util.ArrayList;
2324
import java.util.Arrays;
@@ -225,7 +226,9 @@ private static MetricConfiguration getMetricConfig(JmxScraperConfig scraperConfi
225226
for (String system : scraperConfig.getTargetSystems()) {
226227
addRulesForSystem(system, config);
227228
}
228-
// TODO : add ability for user to provide custom yaml configurations
229+
for (String file : scraperConfig.getJmxConfig()) {
230+
addRulesFromFile(file, config);
231+
}
229232
return config;
230233
}
231234

@@ -234,13 +237,25 @@ private static void addRulesForSystem(String system, MetricConfiguration conf) {
234237
try (InputStream inputStream =
235238
JmxScraper.class.getClassLoader().getResourceAsStream(yamlResource)) {
236239
if (inputStream != null) {
237-
RuleParser parserInstance = RuleParser.get();
238-
parserInstance.addMetricDefsTo(conf, inputStream, system);
240+
RuleParser.get().addMetricDefsTo(conf, inputStream, system);
239241
} else {
240242
throw new IllegalArgumentException("No support for system " + system);
241243
}
242244
} catch (Exception e) {
243245
throw new IllegalStateException("Error while loading rules for system " + system, e);
244246
}
245247
}
248+
249+
private static void addRulesFromFile(String file, MetricConfiguration conf) {
250+
Path path = Paths.get(file);
251+
if (!Files.isReadable(path)) {
252+
throw new IllegalArgumentException("Unable to read file: " + path);
253+
}
254+
255+
try (InputStream inputStream = Files.newInputStream(path)) {
256+
RuleParser.get().addMetricDefsTo(conf, inputStream, file);
257+
} catch (IOException e) {
258+
throw new IllegalArgumentException("Error while loading rules from file: " + file, e);
259+
}
260+
}
246261
}

0 commit comments

Comments
 (0)