From d2d8a2214b9a869f40cc3cb145c37c7840ca75ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 16 Jan 2022 23:13:40 +0100 Subject: [PATCH] Prevent remote JMX monitoring when started in agent mode (#675) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../java/io/prometheus/jmx/JmxCollector.java | 37 ++++++++++--------- .../java/io/prometheus/jmx/WebServer.java | 2 +- .../java/io/prometheus/jmx/JavaAgent.java | 2 +- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/collector/src/main/java/io/prometheus/jmx/JmxCollector.java b/collector/src/main/java/io/prometheus/jmx/JmxCollector.java index b87d64b4..7c719dd3 100644 --- a/collector/src/main/java/io/prometheus/jmx/JmxCollector.java +++ b/collector/src/main/java/io/prometheus/jmx/JmxCollector.java @@ -29,7 +29,12 @@ public class JmxCollector extends Collector implements Collector.Describable { - private final boolean jmxUrlRequired; + public enum Mode { + AGENT, + STANDALONE + } + + private final Mode mode; static final Counter configReloadSuccess = Counter.build() .name("jmx_config_reload_success_total") @@ -77,36 +82,34 @@ private static class Config { private final JmxMBeanPropertyCache jmxMBeanPropertyCache = new JmxMBeanPropertyCache(); public JmxCollector(File in) throws IOException, MalformedObjectNameException { - this(in, false); + this(in, null); } - public JmxCollector(File in, boolean jmxUrlRequired) throws IOException, MalformedObjectNameException { + public JmxCollector(File in, Mode mode) throws IOException, MalformedObjectNameException { configFile = in; - this.jmxUrlRequired = jmxUrlRequired; + this.mode = mode; config = loadConfig((Map)new Yaml().load(new FileReader(in))); config.lastUpdate = configFile.lastModified(); - exitIfJmxUrlMissing(); + exitOnConfigError(); } public JmxCollector(String yamlConfig) throws MalformedObjectNameException { config = loadConfig((Map)new Yaml().load(yamlConfig)); - jmxUrlRequired = false; + mode = null; } public JmxCollector(InputStream inputStream) throws MalformedObjectNameException { config = loadConfig((Map)new Yaml().load(inputStream)); - jmxUrlRequired = false; + mode = null; } - private void exitIfJmxUrlMissing() { - // If the jmxUrl configuration is missing, the JmxScraper implicitly monitors the JVM it runs in. - // This is good if the JmxCollector is used in the Java agent, because the Java agent should monitor the JVM - // it is attached to. - // However, if the JmxCollector is used in the WebServer, the intention is that it monitors another process. - // If the jmxUrl configuration is missing, it should not silently ignore this and start monitoring itself. - // The WebServer sets jmxUrlRequired to true so that we can verify this and terminate with a proper error message. - if (jmxUrlRequired && config.jmxUrl.isEmpty()) { - LOGGER.severe("configuration error: one of jmxUrl or hostPort is required"); + private void exitOnConfigError() { + if (mode == Mode.AGENT && !config.jmxUrl.isEmpty()) { + LOGGER.severe("Configuration error: When running jmx_exporter as a Java agent, you must not configure 'jmxUrl' or 'hostPort' because you don't want to monitor a remote JVM."); + System.exit(-1); + } + if (mode == Mode.STANDALONE && config.jmxUrl.isEmpty()) { + LOGGER.severe("Configuration error: When running jmx_exporter in standalone mode (using jmx_prometheus_httpserver-*.jar) you must configure 'jmxUrl' or 'hostPort'."); System.exit(-1); } } @@ -141,7 +144,7 @@ private synchronized Config getLatestConfig() { reloadConfig(); } } - exitIfJmxUrlMissing(); + exitOnConfigError(); return config; } diff --git a/jmx_prometheus_httpserver/src/main/java/io/prometheus/jmx/WebServer.java b/jmx_prometheus_httpserver/src/main/java/io/prometheus/jmx/WebServer.java index 53b0dad8..136309fd 100644 --- a/jmx_prometheus_httpserver/src/main/java/io/prometheus/jmx/WebServer.java +++ b/jmx_prometheus_httpserver/src/main/java/io/prometheus/jmx/WebServer.java @@ -27,7 +27,7 @@ public static void main(String[] args) throws Exception { } new BuildInfoCollector().register(); - new JmxCollector(new File(args[1]), true).register(); + new JmxCollector(new File(args[1]), JmxCollector.Mode.STANDALONE).register(); new HTTPServer(socket, CollectorRegistry.defaultRegistry); } } diff --git a/jmx_prometheus_javaagent_java6/src/main/java/io/prometheus/jmx/JavaAgent.java b/jmx_prometheus_javaagent_java6/src/main/java/io/prometheus/jmx/JavaAgent.java index 5038998d..74cbcbf8 100644 --- a/jmx_prometheus_javaagent_java6/src/main/java/io/prometheus/jmx/JavaAgent.java +++ b/jmx_prometheus_javaagent_java6/src/main/java/io/prometheus/jmx/JavaAgent.java @@ -26,7 +26,7 @@ public static void premain(String agentArgument, Instrumentation instrumentation Config config = parseConfig(agentArgument, host); new BuildInfoCollector().register(); - new JmxCollector(new File(config.file)).register(); + new JmxCollector(new File(config.file), JmxCollector.Mode.AGENT).register(); DefaultExports.initialize(); server = new HTTPServer(config.socket, CollectorRegistry.defaultRegistry, true); }