LLD
官方文档:https://www.zabbix.com/documentation/3.4/zh/manual/discovery/low_level_discovery
如果我需要自动发现一台或多台主机并执行一些特定的动作,通过Discovery就可以,但是加入我要自动发现主机上的网络端口、服务、磁盘并进行监控我该怎么做?
答案就是LLD。
Zabbix提供LLD实现上面的需求,举个例子,我现在有一台Docker主机,上面跑了若干个Tomcat,当新Tomcat创建时,Zabbix自动发现新启动的Tomcat容器,并对Tomcat以及JVM运行状态进行监控
首先来过一下流程图
相关配置
/etc/zabbix/zabbix_agent.conf Python脚本会调用一些命令和库,所以需要root权限
AllowRoot=1
Include=/etc/zabbix/zabbix_agentd.d/*.conf
/etc/zabbix/zabbix_agentd.d/userparameter_jvm_gc.conf 用户自定义Key配置文件中定义了两个KEY
- custom.srv.discover_jvm:调用Py脚本获取Tomcat JVM主机列表
- custom.srv.jvm[*]:获取指定JVM运行状态数据
UserParameter=custom.srv.discover_jvm,/usr/local/bin/lld-jvm.py UserParameter=custom.srv.jvm[*],/prodata/scripts/zabbix/tomcat_jvm_gc.sh $1 $2 $3
/usr/local/bin/lld-jvm.py
#!/bin/python35
import json
import docker
import subprocess
from subprocess import PIPE
class AutoDiscoveryTomcatJvm(object):
def __init__(self, client):
self.client = client
self.tomcat_container_list = None
self.jvm_list = []
self.data = []
def get_jvm_info(self, tag):
self.tomcat_container_list = [c for c in self.client.containers.list(filters={'status': 'running'}) if tag in c.name]
for container in self.tomcat_container_list:
container_networks = container.attrs.get('NetworkSettings').get('Networks')
for network in container_networks:
ip_addr = container_networks.get(network).get('IPAddress')
if ip_addr and ip_addr != '':
self.jvm_list.append({container.name: ip_addr})
break
def get_enable_jstatd_jvm(self, jstatd_port=2021):
for jvm in self.jvm_list:
jvm_container_name, jvm_container_ip = list(jvm.items())[0]
res = subprocess.Popen('jps rmi://{}:{}'.format(jvm_container_ip, jstatd_port), shell=True, stdout=PIPE, stderr=PIPE)
res_stdout, res_err = res.communicate()
res_code = res.returncode
if res_code == 0:
self.data.append({"{#TOMCAT}": '{}:{}'.format(jvm_container_ip, jstatd_port), "{#NAME}": jvm_container_name})
return self.data
if __name__ == '__main__':
client = docker.from_env()
auto_discovery_jvm = AutoDiscoveryTomcatJvm(client)
auto_discovery_jvm.get_jvm_info('tomcat')
data = auto_discovery_jvm.get_enable_jstatd_jvm(jstatd_port=2010)
print(json.dumps({"data": data}, indent=4))
/prodata/scripts/zabbix/tomcat_jvm_gc.sh
#!/bin/bash
tomcat_addr="$1"
if [ -z ${3} ];then
metric="$2"
rminame=""
else
rminame="/$2"
metric="$3"
fi
function get_gc_info(){
return "${gc_info}"
}
function ygc_count(){
# Number of young generation GC events.
echo ${gc_info} | awk '{print $7}'
}
function ygc_time_count(){
# Young generation garbage collection time(s).
echo ${gc_info} | awk '{print $8}'
}
function fgc_count(){
# Number of full GC events.
echo ${gc_info} | awk '{print $9}'
}
function fgc_time_count(){
# Young generation garbage collection time(s).
echo ${gc_info} | awk '{print $10}'
}
nc_addr_port=`echo "${tomcat_addr}"|sed -r "s/:/ /g"`
nc -z -w 1 ${nc_addr_port}
if [ $? != 0 ];then
echo "Connect to ${tomcat_addr} failed."
exit 1
else
jvm_id=`jps -v rmi://${tomcat_addr}${rminame}|grep jmx |grep -v 'grep'|awk '{print $1}'`
gc_info=`jstat -gcutil rmi://${jvm_id}@${tomcat_addr}${rminame}|tail -1`
${metric} gc_info
fi