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

results matching ""

    No results matching ""