添加 jmx_prometheus_javaagent.jar 导致错误
Adding jmx_prometheus_javaagent.jar causing error
当我使用命令将下面作为 javaagent 添加到我的独立 jar 时,我已经能够使用 jmx prometheus exporter 成功提取 JMX 指标
-javaagent:./jmx_prometheus_javaagent-0.15.0.jar=8089:config.yaml -jar myjar.jar
但是当我将其作为 VM 选项添加到 tomcat 服务器时。
它给出以下错误并且无法提取任何 jmx 信息:
SEVERE [prometheus-http-1-4] io.prometheus.jmx.shaded.io.prometheus.jmx.JmxCollector.collect JMX scrape failed: java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.NoInitialContextException: Cannot instantiate class: org.apache.naming.java.javaURLContextFactory [Root exception is java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory]
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:369)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:270)
at io.prometheus.jmx.shaded.io.prometheus.jmx.JmxScraper.doScrape(JmxScraper.java:94)
at io.prometheus.jmx.shaded.io.prometheus.jmx.JmxCollector.collect(JmxCollector.java:547)
at io.prometheus.jmx.shaded.io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.findNextElement(CollectorRegistry.java:207)
at io.prometheus.jmx.shaded.io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.nextElement(CollectorRegistry.java:240)
at io.prometheus.jmx.shaded.io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.nextElement(CollectorRegistry.java:161)
at io.prometheus.jmx.shaded.io.prometheus.client.exporter.common.TextFormat.write004(TextFormat.java:65)
at io.prometheus.jmx.shaded.io.prometheus.client.exporter.common.TextFormat.writeFormat(TextFormat.java:47)
at io.prometheus.jmx.shaded.io.prometheus.client.exporter.HTTPServer$HTTPMetricHandler.handle(HTTPServer.java:72)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.naming.NoInitialContextException: Cannot instantiate class: org.apache.naming.java.javaURLContextFactory [Root exception is java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory]
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:674)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.(InitialContext.java:216)
at javax.management.remote.rmi.RMIConnector.findRMIServerJNDI(RMIConnector.java:1953)
at javax.management.remote.rmi.RMIConnector.findRMIServer(RMIConnector.java:1922)
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:287)
... 18 more
Caused by: java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:72)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:61)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:672)
经过一番摸索,我发现我需要从 config.yml.It 中删除 jmxUrl,在与本地 JVM 对话时不需要任何 jmxUrl 和主机端口
jmx_exporter代码:
JmxCollector.java 第 138 行:
if (yamlConfig.containsKey("hostPort")) {
if (yamlConfig.containsKey("jmxUrl")) {
throw new IllegalArgumentException("At most one of hostPort and jmxUrl must be provided");
}
cfg.jmxUrl ="service:jmx:rmi:///jndi/rmi://" + (String)yamlConfig.get("hostPort") + "/jmxrmi";
} else if (yamlConfig.containsKey("jmxUrl")) {
cfg.jmxUrl = (String)yamlConfig.get("jmxUrl");
}
JmxScraper.java 第 79 行:
if (jmxUrl.isEmpty()) {
beanConn = ManagementFactory.getPlatformMBeanServer();
}
所以,我从 config.yml 文件中删除了 jmxUrl 和主机端口配置。 Class Not Found 没有发生异常
当我使用命令将下面作为 javaagent 添加到我的独立 jar 时,我已经能够使用 jmx prometheus exporter 成功提取 JMX 指标
-javaagent:./jmx_prometheus_javaagent-0.15.0.jar=8089:config.yaml -jar myjar.jar
但是当我将其作为 VM 选项添加到 tomcat 服务器时。 它给出以下错误并且无法提取任何 jmx 信息:
SEVERE [prometheus-http-1-4] io.prometheus.jmx.shaded.io.prometheus.jmx.JmxCollector.collect JMX scrape failed: java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.NoInitialContextException: Cannot instantiate class: org.apache.naming.java.javaURLContextFactory [Root exception is java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory] at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:369) at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:270) at io.prometheus.jmx.shaded.io.prometheus.jmx.JmxScraper.doScrape(JmxScraper.java:94) at io.prometheus.jmx.shaded.io.prometheus.jmx.JmxCollector.collect(JmxCollector.java:547) at io.prometheus.jmx.shaded.io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.findNextElement(CollectorRegistry.java:207) at io.prometheus.jmx.shaded.io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.nextElement(CollectorRegistry.java:240) at io.prometheus.jmx.shaded.io.prometheus.client.CollectorRegistry$MetricFamilySamplesEnumeration.nextElement(CollectorRegistry.java:161) at io.prometheus.jmx.shaded.io.prometheus.client.exporter.common.TextFormat.write004(TextFormat.java:65) at io.prometheus.jmx.shaded.io.prometheus.client.exporter.common.TextFormat.writeFormat(TextFormat.java:47) at io.prometheus.jmx.shaded.io.prometheus.client.exporter.HTTPServer$HTTPMetricHandler.handle(HTTPServer.java:72) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82) at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675) at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: javax.naming.NoInitialContextException: Cannot instantiate class: org.apache.naming.java.javaURLContextFactory [Root exception is java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory] at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:674) at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313) at javax.naming.InitialContext.init(InitialContext.java:244) at javax.naming.InitialContext.(InitialContext.java:216) at javax.management.remote.rmi.RMIConnector.findRMIServerJNDI(RMIConnector.java:1953) at javax.management.remote.rmi.RMIConnector.findRMIServer(RMIConnector.java:1922) at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:287) ... 18 more Caused by: java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:72) at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:61) at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:672)
经过一番摸索,我发现我需要从 config.yml.It 中删除 jmxUrl,在与本地 JVM 对话时不需要任何 jmxUrl 和主机端口
jmx_exporter代码:
JmxCollector.java 第 138 行:
if (yamlConfig.containsKey("hostPort")) {
if (yamlConfig.containsKey("jmxUrl")) {
throw new IllegalArgumentException("At most one of hostPort and jmxUrl must be provided");
}
cfg.jmxUrl ="service:jmx:rmi:///jndi/rmi://" + (String)yamlConfig.get("hostPort") + "/jmxrmi";
} else if (yamlConfig.containsKey("jmxUrl")) {
cfg.jmxUrl = (String)yamlConfig.get("jmxUrl");
}
JmxScraper.java 第 79 行:
if (jmxUrl.isEmpty()) {
beanConn = ManagementFactory.getPlatformMBeanServer();
}
所以,我从 config.yml 文件中删除了 jmxUrl 和主机端口配置。 Class Not Found 没有发生异常