添加 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 没有发生异常