From 5948f5751da817756e9d219d4ec4eb19cd8f75f2 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:38:01 +0200 Subject: [PATCH 01/10] add snapshot dependency --- jmx-scraper/build.gradle.kts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/jmx-scraper/build.gradle.kts b/jmx-scraper/build.gradle.kts index bab7b7cb7..d2bea917c 100644 --- a/jmx-scraper/build.gradle.kts +++ b/jmx-scraper/build.gradle.kts @@ -13,9 +13,20 @@ otelJava.moduleName.set("io.opentelemetry.contrib.jmxscraper") application.mainClass.set("io.opentelemetry.contrib.jmxscraper.JmxScraper") +repositories { + mavenCentral() + mavenLocal() + // TODO: remove snapshot repository once 2.9.0 is released + maven { + setUrl("https://oss.sonatype.org/content/repositories/snapshots") + } + +} + + dependencies { // TODO remove snapshot dependency on upstream once 2.9.0 is released - // api(enforcedPlatform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:2.9.0-SNAPSHOT-alpha",)) + api(enforcedPlatform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:2.9.0-alpha-SNAPSHOT")) implementation("io.opentelemetry:opentelemetry-api") implementation("io.opentelemetry:opentelemetry-sdk") From 7f7681b91ee25fa8eedb1565bdcdca58a17d0bf6 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:06:44 +0200 Subject: [PATCH 02/10] first working poc with tomcat --- jmx-scraper/build.gradle.kts | 3 + .../contrib/jmxscraper/JmxScraper.java | 95 ++++++++++++++----- jmx-scraper/src/main/resources/tomcat.yaml | 84 ++++++++++++++++ 3 files changed, 160 insertions(+), 22 deletions(-) create mode 100644 jmx-scraper/src/main/resources/tomcat.yaml diff --git a/jmx-scraper/build.gradle.kts b/jmx-scraper/build.gradle.kts index d2bea917c..569582bf9 100644 --- a/jmx-scraper/build.gradle.kts +++ b/jmx-scraper/build.gradle.kts @@ -33,6 +33,9 @@ dependencies { implementation("io.opentelemetry:opentelemetry-sdk-metrics") implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + runtimeOnly("io.opentelemetry:opentelemetry-exporter-otlp") + runtimeOnly("io.opentelemetry:opentelemetry-exporter-logging") + implementation("io.opentelemetry.instrumentation:opentelemetry-jmx-metrics") testImplementation("org.junit-pioneer:junit-pioneer") diff --git a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java index ebed7c780..617b4702f 100644 --- a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java +++ b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java @@ -5,16 +5,22 @@ package io.opentelemetry.contrib.jmxscraper; +import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.contrib.jmxscraper.config.ConfigurationException; import io.opentelemetry.contrib.jmxscraper.config.JmxScraperConfig; +import io.opentelemetry.instrumentation.jmx.engine.JmxMetricInsight; +import io.opentelemetry.instrumentation.jmx.engine.MetricConfiguration; +import io.opentelemetry.instrumentation.jmx.yaml.RuleParser; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; @@ -23,10 +29,13 @@ public class JmxScraper { private static final Logger logger = Logger.getLogger(JmxScraper.class.getName()); private static final String CONFIG_ARG = "-config"; + private static final String OTEL_AUTOCONFIGURE = "otel.java.global-autoconfigure.enabled"; + private final JmxConnectorBuilder client; + private final JmxMetricInsight service; + private final JmxScraperConfig config; - // TODO depend on instrumentation 2.9.0 snapshot - // private final JmxMetricInsight service; + private final AtomicBoolean running = new AtomicBoolean(false); /** * Main method to create and run a {@link JmxScraper} instance. @@ -35,15 +44,23 @@ public class JmxScraper { */ @SuppressWarnings({"SystemOut", "SystemExitOutsideMain"}) public static void main(String[] args) { + + // enable SDK auto-configure if not explicitly set by user + if (System.getProperty(OTEL_AUTOCONFIGURE) == null) { + System.setProperty(OTEL_AUTOCONFIGURE, "true"); + } + try { JmxScraperConfig config = JmxScraperConfig.fromProperties(parseArgs(Arrays.asList(args)), System.getProperties()); // propagate effective user-provided configuration to JVM system properties + // this also enables SDK auto-configuration to use those properties config.propagateSystemProperties(); - // TODO: depend on instrumentation 2.9.0 snapshot - // service = JmxMetricInsight.createService(GlobalOpenTelemetry.get(), - // config.getIntervalMilliseconds()); - JmxScraper jmxScraper = new JmxScraper(JmxConnectorBuilder.createNew(config.getServiceUrl())); + + JmxMetricInsight service = JmxMetricInsight.createService(GlobalOpenTelemetry.get(), + config.getIntervalMilliseconds()); + JmxScraper jmxScraper = new JmxScraper(JmxConnectorBuilder.createNew(config.getServiceUrl()), + service, config); jmxScraper.start(); } catch (ArgumentsParsingException e) { @@ -109,29 +126,63 @@ private static Properties loadPropertiesFromPath(String path) throws Configurati } } - JmxScraper(JmxConnectorBuilder client) { + JmxScraper(JmxConnectorBuilder client, JmxMetricInsight service, JmxScraperConfig config) { this.client = client; + this.service = service; + this.config = config; } private void start() throws IOException { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + logger.info("JMX scraping stopped"); + running.set(false); + })); + + try (JMXConnector connector = client.build()) { + MBeanServerConnection connection = connector.getMBeanServerConnection(); + service.startRemote(getMetricConfig(config), () -> Collections.singletonList(connection)); + + running.set(true); + logger.info("JMX scraping started"); + + while (running.get()) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // silenty ignored + } + } + } + } - JMXConnector connector = client.build(); - - @SuppressWarnings("unused") - MBeanServerConnection connection = connector.getMBeanServerConnection(); - - // TODO: depend on instrumentation 2.9.0 snapshot - // MetricConfiguration metricConfig = new MetricConfiguration(); - // TODO create JMX insight config from scraper config - // service.startRemote(metricConfig, () -> Collections.singletonList(connection)); + private static MetricConfiguration getMetricConfig(JmxScraperConfig scraperConfig) { + MetricConfiguration config = new MetricConfiguration(); + for (String system : scraperConfig.getTargetSystems()) { + try { + addRulesForSystem(system, config); + } catch (RuntimeException e) { + logger.warning("unable to load rules for system " + system + ": " + e.getMessage()); + } + } + // TODO : add ability for user to provide custom yaml configurations - logger.info("JMX scraping started"); + return config; + } - // TODO: wait a bit to keep the JVM running, this won't be needed once calling jmx insight - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - throw new IllegalStateException(e); + private static void addRulesForSystem(String system, MetricConfiguration conf) { + String yamlResource = system + ".yaml"; + try (InputStream inputStream = + JmxScraper.class.getClassLoader().getResourceAsStream(yamlResource)) { + if (inputStream != null) { + RuleParser parserInstance = RuleParser.get(); + parserInstance.addMetricDefsTo(conf, inputStream, system); + } else { + throw new IllegalStateException("no support for " + system); + } + } catch (Exception e) { + throw new IllegalStateException("error while loading rules for system " + system, e); } } + + } diff --git a/jmx-scraper/src/main/resources/tomcat.yaml b/jmx-scraper/src/main/resources/tomcat.yaml new file mode 100644 index 000000000..71adf88ff --- /dev/null +++ b/jmx-scraper/src/main/resources/tomcat.yaml @@ -0,0 +1,84 @@ +--- + +### TODO: for now this is a copy of tomcat.yaml from instrumentation +### This is only for testing and does not fit the current metrics definitions of JMX Gatherer +### + +# For Tomcat, the default JMX domain is "Catalina:", however with some deployments like embedded in spring-boot +# we can have the "Tomcat:" domain used, thus we use both MBean names for the metrics. + +rules: + - beans: + - Catalina:type=GlobalRequestProcessor,name=* + - Tomcat:type=GlobalRequestProcessor,name=* + unit: "1" + prefix: http.server.tomcat. + metricAttribute: + name: param(name) + mapping: + errorCount: + metric: errorCount + type: gauge + desc: The number of errors per second on all request processors + requestCount: + metric: requestCount + type: gauge + desc: The number of requests per second across all request processors + maxTime: + metric: maxTime + type: gauge + unit: ms + desc: The longest request processing time + processingTime: + metric: processingTime + type: counter + unit: ms + desc: Total time for processing all requests + bytesReceived: + metric: traffic + type: counter + unit: By + desc: The number of bytes transmitted + metricAttribute: + direction: const(received) + bytesSent: + metric: traffic + type: counter + unit: By + desc: The number of bytes transmitted + metricAttribute: + direction: const(sent) + + - beans: + - Catalina:type=Manager,host=localhost,context=* + - Tomcat:type=Manager,host=localhost,context=* + unit: "1" + prefix: http.server.tomcat. + type: updowncounter + metricAttribute: + context: param(context) + mapping: + activeSessions: + metric: sessions.activeSessions + desc: The number of active sessions + + - beans: + - Catalina:type=ThreadPool,name=* + - Tomcat:type=ThreadPool,name=* + unit: "{threads}" + prefix: http.server.tomcat. + type: updowncounter + metricAttribute: + name: param(name) + mapping: + currentThreadCount: + metric: threads + desc: Thread Count of the Thread Pool + metricAttribute: + state: const(idle) + currentThreadsBusy: + metric: threads + desc: Thread Count of the Thread Pool + metricAttribute: + state: const(busy) + From 93bf770737629b94c5a593f4b5a0ec581aa87da4 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:34:37 +0200 Subject: [PATCH 03/10] add comments for future config enhancement --- jmx-scraper/build.gradle.kts | 2 -- .../contrib/jmxscraper/JmxScraper.java | 23 +++++++++++-------- .../jmxscraper/config/JmxScraperConfig.java | 6 ++--- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/jmx-scraper/build.gradle.kts b/jmx-scraper/build.gradle.kts index 569582bf9..8a71277a3 100644 --- a/jmx-scraper/build.gradle.kts +++ b/jmx-scraper/build.gradle.kts @@ -20,10 +20,8 @@ repositories { maven { setUrl("https://oss.sonatype.org/content/repositories/snapshots") } - } - dependencies { // TODO remove snapshot dependency on upstream once 2.9.0 is released api(enforcedPlatform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:2.9.0-alpha-SNAPSHOT")) diff --git a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java index 617b4702f..e141d6388 100644 --- a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java +++ b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java @@ -46,6 +46,7 @@ public class JmxScraper { public static void main(String[] args) { // enable SDK auto-configure if not explicitly set by user + // TODO: refactor this to use AutoConfiguredOpenTelemetrySdk if (System.getProperty(OTEL_AUTOCONFIGURE) == null) { System.setProperty(OTEL_AUTOCONFIGURE, "true"); } @@ -57,10 +58,11 @@ public static void main(String[] args) { // this also enables SDK auto-configuration to use those properties config.propagateSystemProperties(); - JmxMetricInsight service = JmxMetricInsight.createService(GlobalOpenTelemetry.get(), - config.getIntervalMilliseconds()); - JmxScraper jmxScraper = new JmxScraper(JmxConnectorBuilder.createNew(config.getServiceUrl()), - service, config); + JmxMetricInsight service = + JmxMetricInsight.createService( + GlobalOpenTelemetry.get(), config.getIntervalMilliseconds()); + JmxScraper jmxScraper = + new JmxScraper(JmxConnectorBuilder.createNew(config.getServiceUrl()), service, config); jmxScraper.start(); } catch (ArgumentsParsingException e) { @@ -133,10 +135,13 @@ private static Properties loadPropertiesFromPath(String path) throws Configurati } private void start() throws IOException { - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - logger.info("JMX scraping stopped"); - running.set(false); - })); + Runtime.getRuntime() + .addShutdownHook( + new Thread( + () -> { + logger.info("JMX scraping stopped"); + running.set(false); + })); try (JMXConnector connector = client.build()) { MBeanServerConnection connection = connector.getMBeanServerConnection(); @@ -183,6 +188,4 @@ private static void addRulesForSystem(String system, MetricConfiguration conf) { throw new IllegalStateException("error while loading rules for system " + system, e); } } - - } diff --git a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/config/JmxScraperConfig.java b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/config/JmxScraperConfig.java index edb7599fd..4e04fe145 100644 --- a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/config/JmxScraperConfig.java +++ b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/config/JmxScraperConfig.java @@ -55,9 +55,9 @@ public class JmxScraperConfig { private String serviceUrl = ""; private String customJmxScrapingConfigPath = ""; private Set targetSystems = Collections.emptySet(); - private int intervalMilliseconds; - private String metricsExporterType = ""; - private String otlpExporterEndpoint = ""; + private int intervalMilliseconds; // TODO only used to set 'otel.metric.export.interval' from SDK + private String metricsExporterType = ""; // TODO only used to default to 'logging' if not set + private String otlpExporterEndpoint = ""; // TODO not really needed here as handled by SDK private String username = ""; private String password = ""; private String realm = ""; From ac67d0f14b0efb9d1f671b8a4e6d3fc7c9fe4f52 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:26:03 +0200 Subject: [PATCH 04/10] fix typo --- .../java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java index e141d6388..853432493 100644 --- a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java +++ b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java @@ -154,7 +154,7 @@ private void start() throws IOException { try { Thread.sleep(100); } catch (InterruptedException e) { - // silenty ignored + // silently ignored } } } From 97038df08840747729904eff7af683cc9a743326 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:26:12 +0200 Subject: [PATCH 05/10] add tomcat yaml config --- jmx-scraper/src/main/resources/tomcat.yaml | 87 +++++++++++----------- 1 file changed, 42 insertions(+), 45 deletions(-) diff --git a/jmx-scraper/src/main/resources/tomcat.yaml b/jmx-scraper/src/main/resources/tomcat.yaml index 71adf88ff..0c60bf49d 100644 --- a/jmx-scraper/src/main/resources/tomcat.yaml +++ b/jmx-scraper/src/main/resources/tomcat.yaml @@ -1,84 +1,81 @@ --- -### TODO: for now this is a copy of tomcat.yaml from instrumentation -### This is only for testing and does not fit the current metrics definitions of JMX Gatherer -### - # For Tomcat, the default JMX domain is "Catalina:", however with some deployments like embedded in spring-boot # we can have the "Tomcat:" domain used, thus we use both MBean names for the metrics. rules: + + - beans: + - Catalina:type=Manager,host=localhost,context=* + - Tomcat:type=Manager,host=localhost,context=* + metricAttribute: + # minor divergence from tomcat.groovy to capture metric for all deployed webapps + context: param(context) + mapping: + activeSessions: + metric: sessions + type: gauge + unit: sessions + desc: The number of active sessions + - beans: - Catalina:type=GlobalRequestProcessor,name=* - Tomcat:type=GlobalRequestProcessor,name=* - unit: "1" - prefix: http.server.tomcat. + prefix: tomcat. metricAttribute: - name: param(name) + proto_handler: param(name) mapping: errorCount: - metric: errorCount - type: gauge - desc: The number of errors per second on all request processors + metric: errors + type: counter + unit: errors + desc: The number of errors encountered requestCount: - metric: requestCount - type: gauge - desc: The number of requests per second across all request processors + metric: request_count + type: counter + unit: requests + desc: The total requests maxTime: - metric: maxTime + metric: max_time type: gauge unit: ms - desc: The longest request processing time + desc: The total requests processingTime: - metric: processingTime - type: counter + metric: processing_time + type: gauge unit: ms - desc: Total time for processing all requests - bytesReceived: + desc: The total processing time + bytesSent: metric: traffic type: counter - unit: By + unit: by desc: The number of bytes transmitted metricAttribute: - direction: const(received) - bytesSent: + direction: const(sent) + bytesReceived: metric: traffic type: counter - unit: By - desc: The number of bytes transmitted + unit: by + desc: The number of bytes received metricAttribute: - direction: const(sent) - - - beans: - - Catalina:type=Manager,host=localhost,context=* - - Tomcat:type=Manager,host=localhost,context=* - unit: "1" - prefix: http.server.tomcat. - type: updowncounter - metricAttribute: - context: param(context) - mapping: - activeSessions: - metric: sessions.activeSessions - desc: The number of active sessions + direction: const(received) - beans: - Catalina:type=ThreadPool,name=* - Tomcat:type=ThreadPool,name=* - unit: "{threads}" - prefix: http.server.tomcat. - type: updowncounter + prefix: tomcat. metricAttribute: - name: param(name) + proto_handler: param(name) mapping: currentThreadCount: metric: threads - desc: Thread Count of the Thread Pool + type: updowncounter + unit: threads metricAttribute: state: const(idle) currentThreadsBusy: metric: threads - desc: Thread Count of the Thread Pool + type: updowncounter + unit: threads metricAttribute: state: const(busy) - From 67a50a0c31f9fd0e82ce1803b8328b7c46e6011d Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:31:46 +0200 Subject: [PATCH 06/10] fix test logging + fail on unsupported system --- .../target_systems/TargetSystemIntegrationTest.java | 3 ++- .../opentelemetry/contrib/jmxscraper/JmxScraper.java | 10 ++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java index 0552aa3bd..8ab2241f8 100644 --- a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java @@ -93,7 +93,7 @@ void endToEndTest() { target = createTargetContainer(JMX_PORT) - .withLogConsumer(new Slf4jLogConsumer(logger)) + .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("target-system")) .withNetwork(network) .withExposedPorts(JMX_PORT) .withNetworkAliases(TARGET_SYSTEM_NETWORK_ALIAS); @@ -114,6 +114,7 @@ void endToEndTest() { scraper = new JmxScraperContainer(otlpEndpoint) + .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("jmx-scraper")) .withNetwork(network) .withService(TARGET_SYSTEM_NETWORK_ALIAS, JMX_PORT); diff --git a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java index 853432493..b1faa0854 100644 --- a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java +++ b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java @@ -77,6 +77,9 @@ public static void main(String[] args) { } catch (IOException e) { System.err.println("Unable to connect " + e.getMessage()); System.exit(2); + } catch (RuntimeException e) { + System.err.println("ERROR: " + e.getMessage()); + System.exit(3); } } @@ -163,14 +166,9 @@ private void start() throws IOException { private static MetricConfiguration getMetricConfig(JmxScraperConfig scraperConfig) { MetricConfiguration config = new MetricConfiguration(); for (String system : scraperConfig.getTargetSystems()) { - try { addRulesForSystem(system, config); - } catch (RuntimeException e) { - logger.warning("unable to load rules for system " + system + ": " + e.getMessage()); - } } // TODO : add ability for user to provide custom yaml configurations - return config; } @@ -182,7 +180,7 @@ private static void addRulesForSystem(String system, MetricConfiguration conf) { RuleParser parserInstance = RuleParser.get(); parserInstance.addMetricDefsTo(conf, inputStream, system); } else { - throw new IllegalStateException("no support for " + system); + throw new IllegalStateException("no support for system" + system); } } catch (Exception e) { throw new IllegalStateException("error while loading rules for system " + system, e); From edb3d6eb81243cb63ded9204e36ed4a5952c2343 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 4 Oct 2024 17:33:25 +0200 Subject: [PATCH 07/10] plug things together + test JVM & Tomcat --- jmx-scraper/build.gradle.kts | 1 + .../jmxscraper/JmxScraperContainer.java | 1 + .../target_systems/JvmIntegrationTest.java | 58 +++++++- .../target_systems/MetricAssertions.java | 126 ++++++++++++++++++ .../TargetSystemIntegrationTest.java | 62 +++++++-- .../target_systems/TomcatIntegrationTest.java | 70 +++++++++- .../contrib/jmxscraper/JmxScraper.java | 2 +- jmx-scraper/src/main/resources/jvm.yaml | 91 +++++++++++++ jmx-scraper/src/main/resources/tomcat.yaml | 16 ++- 9 files changed, 399 insertions(+), 28 deletions(-) create mode 100644 jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/MetricAssertions.java create mode 100644 jmx-scraper/src/main/resources/jvm.yaml diff --git a/jmx-scraper/build.gradle.kts b/jmx-scraper/build.gradle.kts index 8a71277a3..8c2a84675 100644 --- a/jmx-scraper/build.gradle.kts +++ b/jmx-scraper/build.gradle.kts @@ -38,6 +38,7 @@ dependencies { testImplementation("org.junit-pioneer:junit-pioneer") testImplementation("io.opentelemetry:opentelemetry-sdk-testing") + testImplementation("org.awaitility:awaitility") } testing { diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxScraperContainer.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxScraperContainer.java index f85a5ba17..a1deb1717 100644 --- a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxScraperContainer.java +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxScraperContainer.java @@ -76,6 +76,7 @@ public void start() { // for now only configure through JVM args List arguments = new ArrayList<>(); arguments.add("java"); + arguments.add("-Dotel.metrics.exporter=otlp"); arguments.add("-Dotel.exporter.otlp.endpoint=" + endpoint); if (!targetSystems.isEmpty()) { diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/JvmIntegrationTest.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/JvmIntegrationTest.java index 4c240ee16..2b89914f3 100644 --- a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/JvmIntegrationTest.java +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/JvmIntegrationTest.java @@ -5,9 +5,13 @@ package io.opentelemetry.contrib.jmxscraper.target_systems; +import static io.opentelemetry.contrib.jmxscraper.target_systems.MetricAssertions.assertGauge; +import static io.opentelemetry.contrib.jmxscraper.target_systems.MetricAssertions.assertTypedGauge; +import static io.opentelemetry.contrib.jmxscraper.target_systems.MetricAssertions.assertTypedSum; + import io.opentelemetry.contrib.jmxscraper.JmxScraperContainer; import io.opentelemetry.contrib.jmxscraper.TestAppContainer; -import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; +import java.util.Arrays; import java.util.List; import org.testcontainers.containers.GenericContainer; @@ -25,7 +29,55 @@ protected JmxScraperContainer customizeScraperContainer(JmxScraperContainer scra } @Override - protected void verifyMetrics(List metrics) { - // TODO: Verify gathered metrics + protected void verifyMetrics() { + // those values depend on the JVM GC configured + List gcLabels = + Arrays.asList( + "Code Cache", + "PS Eden Space", + "PS Old Gen", + "Metaspace", + "Compressed Class Space", + "PS Survivor Space"); + List gcCollectionLabels = Arrays.asList("PS MarkSweep", "PS Scavenge"); + + waitAndAssertMetrics( + metric -> assertGauge(metric, "jvm.classes.loaded", "number of loaded classes", "1"), + metric -> + assertTypedSum( + metric, + "jvm.gc.collections.count", + "total number of collections that have occurred", + "1", + gcCollectionLabels), + metric -> + assertTypedSum( + metric, + "jvm.gc.collections.elapsed", + "the approximate accumulated collection elapsed time in milliseconds", + "ms", + gcCollectionLabels), + metric -> assertGauge(metric, "jvm.memory.heap.committed", "current heap usage", "by"), + metric -> assertGauge(metric, "jvm.memory.heap.init", "current heap usage", "by"), + metric -> assertGauge(metric, "jvm.memory.heap.max", "current heap usage", "by"), + metric -> assertGauge(metric, "jvm.memory.heap.used", "current heap usage", "by"), + metric -> + assertGauge(metric, "jvm.memory.nonheap.committed", "current non-heap usage", "by"), + metric -> assertGauge(metric, "jvm.memory.nonheap.init", "current non-heap usage", "by"), + metric -> assertGauge(metric, "jvm.memory.nonheap.max", "current non-heap usage", "by"), + metric -> assertGauge(metric, "jvm.memory.nonheap.used", "current non-heap usage", "by"), + metric -> + assertTypedGauge( + metric, "jvm.memory.pool.committed", "current memory pool usage", "by", gcLabels), + metric -> + assertTypedGauge( + metric, "jvm.memory.pool.init", "current memory pool usage", "by", gcLabels), + metric -> + assertTypedGauge( + metric, "jvm.memory.pool.max", "current memory pool usage", "by", gcLabels), + metric -> + assertTypedGauge( + metric, "jvm.memory.pool.used", "current memory pool usage", "by", gcLabels), + metric -> assertGauge(metric, "jvm.threads.count", "number of threads", "1")); } } diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/MetricAssertions.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/MetricAssertions.java new file mode 100644 index 000000000..addf145ea --- /dev/null +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/MetricAssertions.java @@ -0,0 +1,126 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.contrib.jmxscraper.target_systems; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +import io.opentelemetry.proto.common.v1.KeyValue; +import io.opentelemetry.proto.metrics.v1.Metric; +import io.opentelemetry.proto.metrics.v1.NumberDataPoint; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import org.assertj.core.api.MapAssert; + +/** Metrics assertions */ +class MetricAssertions { + + private MetricAssertions() {} + + static void assertGauge(Metric metric, String name, String description, String unit) { + assertThat(metric.getName()).isEqualTo(name); + assertThat(metric.getDescription()).isEqualTo(description); + assertThat(metric.getUnit()).isEqualTo(unit); + assertThat(metric.hasGauge()).isTrue(); + assertThat(metric.getGauge().getDataPointsList()) + .satisfiesExactly(point -> assertThat(point.getAttributesList()).isEmpty()); + } + + static void assertSum(Metric metric, String name, String description, String unit) { + assertSum(metric, name, description, unit, /* isMonotonic= */ true); + } + + static void assertSum( + Metric metric, String name, String description, String unit, boolean isMonotonic) { + assertThat(metric.getName()).isEqualTo(name); + assertThat(metric.getDescription()).isEqualTo(description); + assertThat(metric.getUnit()).isEqualTo(unit); + assertThat(metric.hasSum()).isTrue(); + assertThat(metric.getSum().getDataPointsList()) + .satisfiesExactly(point -> assertThat(point.getAttributesList()).isEmpty()); + assertThat(metric.getSum().getIsMonotonic()).isEqualTo(isMonotonic); + } + + static void assertTypedGauge( + Metric metric, String name, String description, String unit, List types) { + assertThat(metric.getName()).isEqualTo(name); + assertThat(metric.getDescription()).isEqualTo(description); + assertThat(metric.getUnit()).isEqualTo(unit); + assertThat(metric.hasGauge()).isTrue(); + assertTypedPoints(metric.getGauge().getDataPointsList(), types); + } + + static void assertTypedSum( + Metric metric, String name, String description, String unit, List types) { + assertThat(metric.getName()).isEqualTo(name); + assertThat(metric.getDescription()).isEqualTo(description); + assertThat(metric.getUnit()).isEqualTo(unit); + assertThat(metric.hasSum()).isTrue(); + assertTypedPoints(metric.getSum().getDataPointsList(), types); + } + + @SafeVarargs + static void assertSumWithAttributes( + Metric metric, + String name, + String description, + String unit, + Consumer>... attributeGroupAssertions) { + assertThat(metric.getName()).isEqualTo(name); + assertThat(metric.getDescription()).isEqualTo(description); + assertThat(metric.getUnit()).isEqualTo(unit); + assertThat(metric.hasSum()).isTrue(); + assertAttributedPoints(metric.getSum().getDataPointsList(), attributeGroupAssertions); + } + + @SafeVarargs + static void assertGaugeWithAttributes( + Metric metric, + String name, + String description, + String unit, + Consumer>... attributeGroupAssertions) { + assertThat(metric.getName()).isEqualTo(name); + assertThat(metric.getDescription()).isEqualTo(description); + assertThat(metric.getUnit()).isEqualTo(unit); + assertThat(metric.hasGauge()).isTrue(); + assertAttributedPoints(metric.getGauge().getDataPointsList(), attributeGroupAssertions); + } + + @SuppressWarnings("unchecked") + private static void assertTypedPoints(List points, List types) { + Consumer>[] assertions = + types.stream() + .map( + type -> + (Consumer>) + attrs -> attrs.containsOnly(entry("name", type))) + .toArray(Consumer[]::new); + + assertAttributedPoints(points, assertions); + } + + @SuppressWarnings("unchecked") + private static void assertAttributedPoints( + List points, + Consumer>... attributeGroupAssertions) { + Consumer>[] assertions = + Arrays.stream(attributeGroupAssertions) + .map(assertion -> (Consumer>) m -> assertion.accept(assertThat(m))) + .toArray(Consumer[]::new); + assertThat(points) + .extracting( + numberDataPoint -> + numberDataPoint.getAttributesList().stream() + .collect( + Collectors.toMap( + KeyValue::getKey, keyValue -> keyValue.getValue().getStringValue()))) + .satisfiesExactlyInAnyOrder(assertions); + } +} diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java index 8ab2241f8..383197a9e 100644 --- a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java @@ -6,23 +6,28 @@ package io.opentelemetry.contrib.jmxscraper.target_systems; import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; import com.linecorp.armeria.server.ServerBuilder; import com.linecorp.armeria.server.grpc.GrpcService; import com.linecorp.armeria.testing.junit5.server.ServerExtension; import io.grpc.stub.StreamObserver; -import io.opentelemetry.contrib.jmxscraper.JmxConnectorBuilder; import io.opentelemetry.contrib.jmxscraper.JmxScraperContainer; import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse; import io.opentelemetry.proto.collector.metrics.v1.MetricsServiceGrpc; -import java.io.IOException; +import io.opentelemetry.proto.metrics.v1.Metric; +import io.opentelemetry.proto.metrics.v1.ResourceMetrics; +import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.LinkedBlockingDeque; -import javax.management.remote.JMXConnector; +import java.util.function.Consumer; +import java.util.stream.Collectors; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -104,14 +109,6 @@ void endToEndTest() { logger.info( "Target system started, JMX port: {} mapped to {}:{}", JMX_PORT, targetHost, targetPort); - // TODO : wait for metrics to be sent and add assertions on what is being captured - // for now we just test that we can connect to remote JMX using our client. - try (JMXConnector connector = JmxConnectorBuilder.createNew(targetHost, targetPort).build()) { - assertThat(connector.getMBeanServerConnection()).isNotNull(); - } catch (IOException e) { - throw new RuntimeException(e); - } - scraper = new JmxScraperContainer(otlpEndpoint) .withLogConsumer(new Slf4jLogConsumer(logger).withPrefix("jmx-scraper")) @@ -121,10 +118,45 @@ void endToEndTest() { scraper = customizeScraperContainer(scraper); scraper.start(); - verifyMetrics(otlpServer.getMetrics()); + verifyMetrics(); } - protected abstract void verifyMetrics(List metrics); + protected void waitAndAssertMetrics(Iterable> assertions) { + await() + .atMost(Duration.ofSeconds(30)) + .untilAsserted( + () -> { + List receivedMetrics = otlpServer.getMetrics(); + assertThat(receivedMetrics).describedAs("no metric received").isNotEmpty(); + + List metrics = + receivedMetrics.stream() + .map(ExportMetricsServiceRequest::getResourceMetricsList) + .flatMap(rm -> rm.stream().map(ResourceMetrics::getScopeMetricsList)) + .flatMap(Collection::stream) + .filter( + // TODO: disabling batch span exporter might help remove unwanted metrics + sm -> sm.getScope().getName().equals("io.opentelemetry.jmx")) + .flatMap(sm -> sm.getMetricsList().stream()) + .collect(Collectors.toList()); + + assertThat(metrics) + .describedAs("metrics reported but none from JMX scraper") + .isNotEmpty(); + + for (Consumer assertion : assertions) { + assertThat(metrics).anySatisfy(assertion); + } + }); + } + + @SafeVarargs + @SuppressWarnings("varargs") + protected final void waitAndAssertMetrics(Consumer... assertions) { + waitAndAssertMetrics(Arrays.asList(assertions)); + } + + protected abstract void verifyMetrics(); protected JmxScraperContainer customizeScraperContainer(JmxScraperContainer scraper) { return scraper; @@ -153,6 +185,10 @@ protected void configure(ServerBuilder sb) { public void export( ExportMetricsServiceRequest request, StreamObserver responseObserver) { + + // verbose but helpful to diagnose what is received + logger.info("receiving metrics {}", request); + metricRequests.add(request); responseObserver.onNext(ExportMetricsServiceResponse.getDefaultInstance()); responseObserver.onCompleted(); diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TomcatIntegrationTest.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TomcatIntegrationTest.java index ccf7e59a7..500e89f82 100644 --- a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TomcatIntegrationTest.java +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TomcatIntegrationTest.java @@ -5,10 +5,12 @@ package io.opentelemetry.contrib.jmxscraper.target_systems; +import static io.opentelemetry.contrib.jmxscraper.target_systems.MetricAssertions.assertGaugeWithAttributes; +import static io.opentelemetry.contrib.jmxscraper.target_systems.MetricAssertions.assertSumWithAttributes; +import static org.assertj.core.api.Assertions.entry; + import io.opentelemetry.contrib.jmxscraper.JmxScraperContainer; -import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; import java.time.Duration; -import java.util.List; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.images.builder.ImageFromDockerfile; @@ -48,7 +50,67 @@ protected JmxScraperContainer customizeScraperContainer(JmxScraperContainer scra } @Override - protected void verifyMetrics(List metrics) { - // TODO: Verify gathered metrics + protected void verifyMetrics() { + waitAndAssertMetrics( + metric -> + assertGaugeWithAttributes( + metric, + "tomcat.sessions", + "The number of active sessions", + "sessions", + attrs -> attrs.containsKey("context")), + metric -> + assertSumWithAttributes( + metric, + "tomcat.errors", + "The number of errors encountered", + "errors", + attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))), + metric -> + assertSumWithAttributes( + metric, + "tomcat.processing_time", + "The total processing time", + "ms", + attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))), + metric -> + assertSumWithAttributes( + metric, + "tomcat.traffic", + "The number of bytes transmitted and received", + "by", + attrs -> + attrs.containsOnly( + entry("proto_handler", "\"http-nio-8080\""), entry("direction", "sent")), + attrs -> + attrs.containsOnly( + entry("proto_handler", "\"http-nio-8080\""), + entry("direction", "received"))), + metric -> + assertGaugeWithAttributes( + metric, + "tomcat.threads", + "The number of threads", + "threads", + attrs -> + attrs.containsOnly( + entry("proto_handler", "\"http-nio-8080\""), entry("state", "idle")), + attrs -> + attrs.containsOnly( + entry("proto_handler", "\"http-nio-8080\""), entry("state", "busy"))), + metric -> + assertGaugeWithAttributes( + metric, + "tomcat.max_time", + "Maximum time to process a request", + "ms", + attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\""))), + metric -> + assertSumWithAttributes( + metric, + "tomcat.request_count", + "The total requests", + "requests", + attrs -> attrs.containsOnly(entry("proto_handler", "\"http-nio-8080\"")))); } } diff --git a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java index b1faa0854..ba84aac2d 100644 --- a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java +++ b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java @@ -166,7 +166,7 @@ private void start() throws IOException { private static MetricConfiguration getMetricConfig(JmxScraperConfig scraperConfig) { MetricConfiguration config = new MetricConfiguration(); for (String system : scraperConfig.getTargetSystems()) { - addRulesForSystem(system, config); + addRulesForSystem(system, config); } // TODO : add ability for user to provide custom yaml configurations return config; diff --git a/jmx-scraper/src/main/resources/jvm.yaml b/jmx-scraper/src/main/resources/jvm.yaml new file mode 100644 index 000000000..d3e95d5d4 --- /dev/null +++ b/jmx-scraper/src/main/resources/jvm.yaml @@ -0,0 +1,91 @@ +--- + +rules: + + - bean: java.lang:type=ClassLoading + mapping: + LoadedClassCount: + metric: jvm.classes.loaded + type: gauge + unit: '1' + desc: number of loaded classes + + - bean: java.lang:type=GarbageCollector,name=* + mapping: + CollectionCount: + metric: jvm.gc.collections.count + type: counter + unit: '1' + desc: total number of collections that have occurred + metricAttribute: + name: param(name) + CollectionTime: + metric: jvm.gc.collections.elapsed + type: counter + unit: ms + desc: the approximate accumulated collection elapsed time in milliseconds + metricAttribute: + name: param(name) + + - bean: java.lang:type=Memory + unit: by + prefix: jvm.memory. + mapping: + HeapMemoryUsage.committed: + metric: heap.committed + desc: current heap usage + type: gauge + HeapMemoryUsage.init: + metric: heap.init + desc: current heap usage + type: gauge + HeapMemoryUsage.max: + metric: heap.max + desc: current heap usage + type: gauge + HeapMemoryUsage.used: + metric: heap.used + desc: current heap usage + type: gauge + NonHeapMemoryUsage.committed: + metric: nonheap.committed + desc: current non-heap usage + type: gauge + NonHeapMemoryUsage.init: + metric: nonheap.init + desc: current non-heap usage + type: gauge + NonHeapMemoryUsage.max: + metric: nonheap.max + desc: current non-heap usage + type: gauge + NonHeapMemoryUsage.used: + metric: nonheap.used + desc: current non-heap usage + type: gauge + + - bean: java.lang:type=MemoryPool,name=* + type: gauge + unit: by + metricAttribute: + name: param(name) + mapping: + Usage.committed: + metric: jvm.memory.pool.committed + desc: current memory pool usage + Usage.init: + metric: jvm.memory.pool.init + desc: current memory pool usage + Usage.max: + metric: jvm.memory.pool.max + desc: current memory pool usage + Usage.used: + metric: jvm.memory.pool.used + desc: current memory pool usage + + - bean: java.lang:type=Threading + mapping: + ThreadCount: + metric: jvm.threads.count + unit: '1' + desc: number of threads diff --git a/jmx-scraper/src/main/resources/tomcat.yaml b/jmx-scraper/src/main/resources/tomcat.yaml index 0c60bf49d..076be6400 100644 --- a/jmx-scraper/src/main/resources/tomcat.yaml +++ b/jmx-scraper/src/main/resources/tomcat.yaml @@ -13,7 +13,7 @@ rules: context: param(context) mapping: activeSessions: - metric: sessions + metric: tomcat.sessions type: gauge unit: sessions desc: The number of active sessions @@ -39,24 +39,24 @@ rules: metric: max_time type: gauge unit: ms - desc: The total requests + desc: Maximum time to process a request processingTime: metric: processing_time - type: gauge + type: counter unit: ms desc: The total processing time bytesSent: metric: traffic type: counter unit: by - desc: The number of bytes transmitted + desc: The number of bytes transmitted and received metricAttribute: direction: const(sent) bytesReceived: metric: traffic type: counter unit: by - desc: The number of bytes received + desc: The number of bytes transmitted and received metricAttribute: direction: const(received) @@ -69,13 +69,15 @@ rules: mapping: currentThreadCount: metric: threads - type: updowncounter + desc: The number of threads + type: gauge unit: threads metricAttribute: state: const(idle) currentThreadsBusy: metric: threads - type: updowncounter + desc: The number of threads + type: gauge unit: threads metricAttribute: state: const(busy) From 70d0bb0a77d60eded4d0870220e0f5328596b1f3 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 8 Oct 2024 10:58:39 +0200 Subject: [PATCH 08/10] change case of exceptions msg --- .../io/opentelemetry/contrib/jmxscraper/JmxScraper.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java index ba84aac2d..1ad51893e 100644 --- a/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java +++ b/jmx-scraper/src/main/java/io/opentelemetry/contrib/jmxscraper/JmxScraper.java @@ -97,10 +97,10 @@ static Properties parseArgs(List args) return new Properties(); } if (args.size() != 2) { - throw new ArgumentsParsingException("exactly two arguments expected, got " + args.size()); + throw new ArgumentsParsingException("Exactly two arguments expected, got " + args.size()); } if (!args.get(0).equalsIgnoreCase(CONFIG_ARG)) { - throw new ArgumentsParsingException("unexpected first argument must be '" + CONFIG_ARG + "'"); + throw new ArgumentsParsingException("Unexpected first argument must be '" + CONFIG_ARG + "'"); } String path = args.get(1); @@ -180,10 +180,10 @@ private static void addRulesForSystem(String system, MetricConfiguration conf) { RuleParser parserInstance = RuleParser.get(); parserInstance.addMetricDefsTo(conf, inputStream, system); } else { - throw new IllegalStateException("no support for system" + system); + throw new IllegalArgumentException("No support for system" + system); } } catch (Exception e) { - throw new IllegalStateException("error while loading rules for system " + system, e); + throw new IllegalStateException("Error while loading rules for system " + system, e); } } } From 69f0fd112718077a8ab7f8a45d8dbe10776e0910 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 16 Oct 2024 09:42:34 +0200 Subject: [PATCH 09/10] log received metrics at debug level --- .../jmxscraper/target_systems/TargetSystemIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java index 8f0ae0091..88a2e5957 100644 --- a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java @@ -190,7 +190,7 @@ public void export( StreamObserver responseObserver) { // verbose but helpful to diagnose what is received - logger.info("receiving metrics {}", request); + logger.debug("receiving metrics {}", request); metricRequests.add(request); responseObserver.onNext(ExportMetricsServiceResponse.getDefaultInstance()); From 33621666fef646e917fefddae5a3adece961ddc5 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 16 Oct 2024 09:52:18 +0200 Subject: [PATCH 10/10] mapped port not mapped anymore --- .../target_systems/TargetSystemIntegrationTest.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java index 88a2e5957..510b4eab5 100644 --- a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/TargetSystemIntegrationTest.java @@ -107,11 +107,6 @@ void endToEndTest() { .withNetworkAliases(TARGET_SYSTEM_NETWORK_ALIAS); target.start(); - String targetHost = target.getHost(); - Integer targetPort = target.getMappedPort(JMX_PORT); - logger.info( - "Target system started, JMX port: {} mapped to {}:{}", JMX_PORT, targetHost, targetPort); - scraper = new JmxScraperContainer(otlpEndpoint) .withLogConsumer(new Slf4jLogConsumer(jmxScraperLogger))