JAVA-GATEWAY Zabbix本身不支持直接监控Java,在zabbix 1.8以前,只能使用Zapcat来做代理监控,而且要修改源代码,非常麻烦。所有后来为了解决这个监控问题,Zabbix和Java双方应运生成了各自的代理监控程序:zabbix 2.0以后添加了服务进程zabbix-java-gateway;Java有了JMX,全称是Java Management Extensions,即Java管理扩展 比如:当Zabbix-Server需要知道java应用程序的某项性能的时候,会启动自身的一个Zabbix-JavaPollers进程去连接Zabbix-JavaGateway请求数据,而ZabbixJavagateway收到请求后使用“JMXmanagementAPI”去查询特定的应用程序,而前提是应用程序这端在开启时需要“-Dcom.sun.management.jmxremote”参数来开启JMX远程查询就行。Java程序会启动自身的一个简单的小程序端口12345向Zabbix-JavaGateway提供请求数据。
开始监控部署
从上面的原理图中我们可以看出,配置Zabbix监控Java应用程序的关键点在于:配置Zabbix-JavaGateway、让Zabbix-Server能够连接Zabbix-JavaGateway、Tomcat开启JVM远程监控功能等
网上的大多数文章都配置的是被动模式(即zabbix server 去想java进程去取数据),这样会造成zabbix server的压力过大,所以应该采用主动模式(写一个zabbix类,然后主动去上报数据) 代码如下: zabbix.py cat zabbix.py #!/usr/bin/python import os import time import socket import struct import cPickle import logging try: from hashlib import sha1 except ImportError: from sha import sha as sha1 try: import json except ImportError: import simplejson as json DUMP = ‘dump‘ if not os.path.isdir(DUMP): os.makedirs(DUMP, mode=0755) class Zabbix(object): logger = logging.getLogger(‘zabbix‘) def __init__(self, values=None): if values is not None: self.__dict__[‘values‘] = values def __getattr__(self, name): if name in (‘values‘): return self.__dict__[name] return None def __setattr__(self, name, value): if name == ‘values‘: self.__dict__[name] = value def gen_request(self, jsons): if isinstance(jsons, basestring): data = ‘%s\n‘ % jsons else: data = json.dumps(jsons) header = ‘ZBXD\x01‘ datalen = struct.pack(‘Q‘, len(data)) return header + datalen + data def dump(self, host, port, jsons): data = {‘host‘: host, ‘port‘: port, ‘jsons‘: jsons} hash = sha1(json.dumps(data)).hexdigest() path = ‘%s.%s.%d.%s.error‘ % (host, port, int(time.time()), hash) try: write = open(os.path.join(DUMP, path), ‘wb‘) cPickle.dump(data, write, -1) write.close() except: self.logger.exception(‘cannot dump to file %s‘, path) def get_zbx_result(self, host, port, jsons): retry = 3 while retry: try: data = self._get_zbx_result(host, port, jsons) if data is None: break return data except socket.error: self.logger.exception(‘cannot communit with zabbix‘) time.sleep(5) retry -= 1 self.logger.error(‘cannot send data to zabbix server‘) self.dump(host, port, jsons) def _get_zbx_result(self, host, port, jsons): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print host,port,jsons sock.connect((host, port)) sock.send(self.gen_request(jsons)) print "send %s" % self.gen_request(jsons) self.logger.debug(‘sent %s‘, jsons) recv = sock.recv(5) if recv != ‘ZBXD\x01‘: self.logger.error(‘Invalid Response‘) self.dump(host, port, jsons) return None recv = sock.recv(8) (datalen,) = struct.unpack(‘Q‘, recv) data = sock.recv(datalen) sock.close() self.logger.debug(‘received %s‘, data) return data def getvalue(self): # shoulde be {host: {key: value}} return self.values def run(self): hostvalues = self.getvalue() if not isinstance(hostvalues, dict): self.logger.error(‘invalid hostvalues: %s‘, str(hostvalues)) return False clock = int(time.time()) jsons = { ‘request‘: ‘agent data‘, ‘data‘: [], ‘clock‘: clock, } data = jsons[‘data‘] for host, values in hostvalues.iteritems(): for key, value in values.iteritems(): data.append({ ‘host‘: host, ‘key‘: key, ‘value‘: value, ‘clock‘: clock, }) return self.get_zbx_result(ZBX_HOST, ZBX_PORT, jsons) def getjmx(self, host, port, keys): jsons = { ‘request‘: ‘java gateway jmx‘, ‘conn‘: host, ‘port‘: port, ‘keys‘: keys, } return self.get_zbx_result(JMX_HOST, JMX_PORT, jsons) ZBX_HOST = ‘zabbix.server.com‘ ZBX_PORT = 10051 JMX_HOST = ‘localhost‘ JMX_PORT = 10052 handler = logging.FileHandler(filename=‘/tmp/zabbix.%s.log‘ % time.strftime(‘%Y%m%d‘), mode=‘a‘) formatter = logging.Formatter(‘%(asctime)s %(name)s %(lineno)s %(levelname)s %(message)s‘) handler.setFormatter(formatter) logger = logging.getLogger() logger.addHandler(handler) logger.setLevel(logging.DEBUG) if __name__ == ‘__main__‘: zbx = Zabbix() print zbx.getjmx(‘localhost‘, 8081, [‘jmx["Standalone:type=Manager,path=/,host=localhost",activeSessions]‘, ‘jmx["java.lang:type=Runtime",Uptime]‘, ‘jmx["Catalina:type=GlobalRequestProcessor,name=\\"http-bio-8080\\"",bytesSent]‘]) pass
cat zabbix_wiki_node1_java.py #!/usr/bin/env python
#fileencoding: utf-8
ITEMS = [
‘jmx["java.lang:type=ClassLoading",LoadedClassCount]‘,
‘jmx["java.lang:type=ClassLoading",TotalLoadedClassCount]‘,
‘jmx["java.lang:type=ClassLoading",UnloadedClassCount]‘,
‘jmx["java.lang:type=Memory",HeapMemoryUsage.committed]‘,
‘jmx["java.lang:type=Memory",HeapMemoryUsage.max]‘,
‘jmx["java.lang:type=Memory",HeapMemoryUsage.used]‘,
‘jmx["java.lang:type=Memory",NonHeapMemoryUsage.committed]‘,
‘jmx["java.lang:type=Memory",NonHeapMemoryUsage.max]‘,
‘jmx["java.lang:type=Memory",NonHeapMemoryUsage.used]‘,
‘jmx["java.lang:type=MemoryPool,name=Code Cache",Usage.committed]‘,
‘jmx["java.lang:type=MemoryPool,name=Code Cache",Usage.max]‘,
‘jmx["java.lang:type=MemoryPool,name=Code Cache",Usage.used]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Eden Space",Usage.committed]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Eden Space",Usage.max]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Eden Space",Usage.used]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Old Gen",Usage.committed]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Old Gen",Usage.max]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Old Gen",Usage.used]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Perm Gen",Usage.committed]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Perm Gen",Usage.max]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Perm Gen",Usage.used]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Survivor Space",Usage.committed]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Survivor Space",Usage.max]‘,
‘jmx["java.lang:type=MemoryPool,name=PS Survivor Space",Usage.used]‘,
‘jmx["java.lang:type=OperatingSystem",MaxFileDescriptorCount]‘,
‘jmx["java.lang:type=OperatingSystem",OpenFileDescriptorCount]‘,
‘jmx["java.lang:type=Runtime",Uptime]‘,
‘jmx["java.lang:type=Threading",DaemonThreadCount]‘,
‘jmx["java.lang:type=Threading",PeakThreadCount]‘,
‘jmx["java.lang:type=Threading",ThreadCount]‘,
‘jmx["java.lang:type=Threading",TotalStartedThreadCount]‘,
‘jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",bytesReceived]‘,
‘jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",bytesSent]‘,
‘jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",errorCount]‘,
‘jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",processingTime]‘,
‘jmx["Standalone:type=GlobalRequestProcessor,name=http-8090",requestCount]‘,
‘jmx["Standalone:type=Manager,path=/,host=localhost",activeSessions]‘,
‘jmx["Standalone:type=Manager,path=/,host=localhost",maxActiveSessions]‘,
‘jmx["Standalone:type=Manager,path=/,host=localhost",maxActive]‘,
‘jmx["Standalone:type=Manager,path=/,host=localhost",rejectedSessions]‘,
‘jmx["Standalone:type=Manager,path=/,host=localhost",sessionCounter]‘,
‘jmx["Standalone:type=ProtocolHandler,port=8090",compression]‘,
‘jmx["Standalone:type=ThreadPool,name=http-8090",currentThreadCount]‘,
‘jmx["Standalone:type=ThreadPool,name=http-8090",currentThreadsBusy]‘,
‘jmx["Standalone:type=ThreadPool,name=http-8090",maxThreads]‘,
]
from zabbix import Zabbix
from zabbix import json
def getjmxkey(key):
# key = key.replace(‘http-8080‘, ‘\\"http-bio-8080\\"‘)
# key = key.replace(‘path=/‘, ‘context=/‘)
return key
def getjmxvalue(value):
if isinstance(value, dict):
return value.get(‘value‘, u‘‘).encode(‘utf8‘)
return ‘‘
if __name__ == ‘__main__‘:
host = ‘it-tw01‘
zbx = Zabbix()
jmxkeys = [getjmxkey(x) for x in ITEMS]
data = zbx.getjmx(‘it-tw01‘, ‘8410‘, jmxkeys)
try:
results = json.loads(data)
except:
results = {}
if isinstance(results, dict) and results[‘response‘] == ‘success‘:
jmxvalues = [getjmxvalue(x) for x in results.get(‘data‘, [])]
hostvalues = {host: dict(zip(ITEMS, jmxvalues))}
Zabbix(hostvalues).run()
# vim: set sta sw=4 et: crontab * * * * * /home/sankuai/monitor/zabbix_wiki_node1_java.py
zabbix /etc/zabbix# ls zabbix_agentd.conf zabbix_agentd.confn-place zabbix_agentd.d zabbix_java_gateway.conf
it-tw01需要关联的模板见附件
特别注意: 编译安装zabbix server需要加上--enable-java以支持jmx监控,如果之前的zabbix server没加,那么请重新编译安装,参考编译参数 安装软件 yum install -y java java-devel zabbix-java-gateway 更多的请参考这个文章:http://www.iyunv.com/thread-269939-1-1.html
|