Jython jmxmp协议支持

时间:2011-04-01 08:39:03

标签: java jython jmx

我正在为zabbix开发监控脚本和模板的集合。它被称为ZTC,所有脚本都在python上。

现在我想添加对某些java监控的支持。我没有找到从CPython中做到这一点的方法 - 仅限于java或jython。由于所有项目都在python上,我决定在jython上编写一个简单的脚本,它将从我的cpython类中调用。

以下是我的代码的样子:

#!/usr/bin/env jython

#Java Dependencies
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.ManagementFactory;

#Python Dependencies
import sys, cmd, socket

def usage():
    print """Usage:
    jmxclient.py -h
    jmxclient.py <connect_url> <jmx_attribute_path> <jmx_property>"""

class JMXClient:
    remote = None

    def connect(self, connect_url):
        if self.remote:
            return True

        #Establish Connection to JMX Server
        url = javax.management.remote.JMXServiceURL(connect_url);
        connector = javax.management.remote.JMXConnectorFactory.connect(url);
        self.remote = connector.getMBeanServerConnection();

    def getAttribute(self, mbean_path, attribute):
        """Query the mbean server for a specific attribute and return the
        result"""
        obn =  javax.management.ObjectName(mbean_path);
        result = self.remote.getAttribute(obn, attribute);

        return result    

if len(sys.argv) <= 1:
    usage()
    sys.exit(2)

if sys.argv[1] in ('-h', '--help'):
    usage()
    sys.exit(2)

if len(sys.argv) <> 4:
    usage()
    sys.exit(2)

(connect_url, mbean_path, attribute) = sys.argv[1:]

j = JMXClient()
j.connect(connect_url)
print j.getAttribute(mbean_path, attribute)   

好的,现在我正试图从兵马俑服务器获取一些属性。它使用jmxmp和url服务:jmx:jmxmp://0.0.0.0:9520。

所以,我按照以下方式运行我的脚本:

$ ./jmxclient.py service:jmx:jmxmp://localhost:9520 java.lang.ClassLoading LoadedClassCount
Traceback (innermost last):
  File "./jmxclient.py", line 87, in ?
  File "./jmxclient.py", line 61, in connect
        at javax.management.remote.JMXConnectorFactory.newJMXConnector(JMXConnectorFactory.java:327)
        at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:247)
        at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:207)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)

java.net.MalformedURLException:java.net.MalformedURLException:不支持的协议:jmxmp

(由于某些被删除的评论,行号不相关)

如何添加对此jmxmp协议的支持?

我发现它似乎可以通过jmxremote_optional.jar启用。如何将此jar添加到我的jython(pref。不是系统范围的)?

更新

正如所建议的那样,我已经从jmxremote-1_0_1-ri-bin-b58.zip参考实现jython -Djava.endorsed.dirs=. -Dpython.path=.../jmxremote_optional.jar:.../jmxremote.jar:.../jmissl.jar jmxclient.py service:jmx:jmxmp://localhost:9520 java.lang.ClassLoading LoadedClassCount添加了jmxremote_optional.jar和jmxremote.jar,但仍然遇到了同样的错误。我确定jmxr​​emote_optional.jar在classpath中,代码似乎与参考示例非常相似。

阅读api文档后,我尝试了以下更改:

url = javax.management.remote.JMXServiceURL('jmxmp', 'localhost', 9520);
connector = javax.management.remote.jmxmp.JMXMPConnector(url)
connector.connect()
self.remote = connector.getMBeanServerConnection();

这引出了另一个例外:

Traceback (innermost last):
  File "../src/jmxclient.py", line 87, in ?
  File "../src/jmxclient.py", line 61, in connect
        at com.sun.jmx.remote.opt.security.AdminClient.connectionOpen(AdminClient.java:209)
        at com.sun.jmx.remote.generic.ClientSynchroMessageConnectionImpl.connect(ClientSynchroMessageConnectionImpl.java:72)
        at javax.management.remote.generic.GenericConnector.connect(GenericConnector.java:177)
        at javax.management.remote.jmxmp.JMXMPConnector.connect(JMXMPConnector.java:119)
        at javax.management.remote.generic.GenericConnector.connect(GenericConnector.java:124)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
java.io.IOException: java.io.IOException: javax.management.remote.message.HandshakeBeginMessage

Jython版本是2.2,我不喜欢使用更高版本,因为这个脚本主要用在RHEL5盒子上,而且它们只有jython 2.2.1。

PS:将问题标记为已回答,因为我已经决定放弃并使用jmxterm或类似的工具,这些工具似乎与jmxmp一起使用,只需添加-Djava.endosed.dirs = / path / to / dir_with_jmxremote_optional /。 但是我仍然希望看到jython解决方案。

3 个答案:

答案 0 :(得分:5)

伙计,我读了大约7次这个帖子.....

无论如何,这就是我的想法。 jmxmp协议未打包在标准J2SE运行时中。见page。引用:

注意 - 如果要使用JMXMP连接器,请从http://java.sun.com/products/JavaManagement/download.html下载JSR 160 Reference Implementation,并将jmxremote_optional.jar文件添加到类路径中。您将在JSR 160 Reference Implementation附带的JMX Remote API Tutorial中找到使用JMXMP连接器的示例。

我对jython并不熟悉,但看起来这个post会让你感到困惑。

答案 1 :(得分:1)

我遇到了同样的问题。解决方案是使用另一种导入jar GET test_index/_search { "size": 0, "track_total_hits": false, "aggs": { "features": { "terms": { "field": "feature.name", "size": 10, "min_doc_count": 1, "order": { "_key": "asc" } }, "aggs": { "types": { "terms": { "field": "feature.type", "size": 10, "min_doc_count": 1, "order": { "_key": "asc" } } } } } } } 的方法。 https://stackoverflow.com/a/11638390/9209536

此代码在Jython 2.7中有效

jmxremote_optional.jar

答案 2 :(得分:0)

另一种选择可能是使用不同的堆栈,如Jolokia,它通过HTTP和JSON导出JMX信息。虽然还没有Python,但已经有各种客户端绑定(Perl via Jmx4Perl,Javascript,Java)。但是从头开始构建一个并不困难,详细描述了协议here