Zabbix在线监控tomcat的线程数,因为线上没有配置jmx,所以使用jstack pid的方式获取thread线程。脚本结合zabbix的自动发现,可以实现多个tomcat实例的自动发现配置。免去以后tomcat增加后一个个手动添加的烦恼。
zabbix agent的配置和路径目录结构
主目录:/etc/zabbix
自定义脚本目录:/etc/zabbix/custom,里面有如下几个路径:
conf zabbix的配置文件目录
externalscripts 外部命令脚本
public zabbix公共文件,例如保存的ip和密码
scripts zabbix自定义的脚本
template zabbix模板文件
自动发现脚本
这个脚本能够打印出当前服务器上所有的tomcat实例名称,pid进程号和home路径。zabbix会定期执行这个脚本,做到自动发现当前所有的tomcat实例。具体脚本如下:
# coding: utf-8 import sys import re import json from optparse import OptionParser from qiueer.python.cmds import cmds def get_tomcat_list(): cmdstr = "ps -ef|grep java|grep -v grep|grep \"Dcatalina.home\"|awk '{print $2 ,$(NF-3)}'|sed 's/-Dcatalina.home=//g'" c2 = cmds(cmdstr, timeout=3) stdo = c2.stdo() stde = c2.stde() # retcode = c2.code() (stdo_list, stde_list) = (re.split("\n", stdo), re.split("\n", stde)) data = list() for tomcat in stdo_list: if not tomcat:continue data.append({ "{#TOMCAT_PID}":tomcat.split()[0], "{#TOMCAT_PATH}": tomcat.split()[1], "{#TOMCAT_NAME}":tomcat.split()[1].split('/')[-1], }) return json.dumps({'data': data}, sort_keys=True, indent=7, separators=(",",":")) def main(): try: usage = "usage: %prog [options]\ngGet Tomcat Stat" parser = OptionParser(usage) parser.add_option("-l", "--list", action="store_true", dest="is_list", default=False, help="if list all tomcat") (options, args) = parser.parse_args() if 1 >= len(sys.argv): parser.print_help() return if options.is_list == True: print get_tomcat_list() return except Exception as e: import traceback tb = traceback.format_exc() print tb if __name__ == "__main__": main()
监控脚本
监控脚本是实际执行jstack的地方,用法如下:
./tomcat_thread_status.sh pid username
pid: tomcat进程号
username: 运行tomcat的用户名
脚本:
#!/bin/bash #### 添加sudo权限 #### #zabbix ALL=(root) NOPASSWD:/etc/zabbix/custom/scripts/tomcat_thread_status.sh #Defaults:zabbix !requiretty #### export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin tomcat_path=$1 user=$2 STATS=(NEW:0 RUNNABLE:0 BLOCKED:0 WAITING:0 TIMED_WAITING:0 TERMINATED:0 TOTAL:0) pid=`ps -ef|grep "java .*$tomcat_path"|grep -v grep|awk '{print $2}'` if [ $pid ];then STATUS=`su - $user -c "jstack $pid|grep -i \"java.lang.Thread.State:\""|awk '{print $2}'|sort|uniq -c|awk '{print $2":"$1}'` fi if [ ! -z "$STATUS" ];then total=0 for s in $STATUS;do key=`echo $s|cut -d: -f1` val=`echo $s|cut -d: -f2` i=0 for t in ${STATS[@]};do if [ `echo $t|grep -c $key` -eq 1 ];then idx=$i break fi let i=$i+1 done STATS[$i]=${key}":"${val} let total=$total+${val} done STATS[6]="TOTAL:"${total} fi echo ${STATS[@]} | sed -e s/' '/',"'/g -e s/':'/'":'/g -e s/^/'{"thread_status":{"'/g -e s/'$'/'}}'/g
脚本执行后会返回json格式的字符串,包括new、runnable、blocked等线程状态的数据。
zabbix agent配置
UserParameter=custom.tomcat_thread.discovery,python /etc/zabbix/custom/scripts/tomcat_thread_discovery.py --list 2>/dev/null UserParameter=custom.tomcat_thread_status.item[*],sudo /etc/zabbix/custom/scripts/tomcat_thread_status.sh "$1" "$2"
配置单独放在/etc/zabbix/custom/conf里,记得需要在主配置文件/etc/zabbix/zabbix_agentd.conf里include该路径,否则配置不会生效。
都准备好后重启zabbix agent。
导入模板配置
模板配置可以参考这个,下载后导入即可。
配置主机
最后在主机的template中添加导入的模板,过会就会发现tomcat已自动发现并添加相关线程的监控。
写在最后
具体脚本也可在github上下载:
自动发现:https://github.com/zhangnq/zabbix/blob/master/scripts/tomcat_thread_discovery.py
线程监控:https://github.com/zhangnq/zabbix/blob/master/scripts/tomcat_thread_status.sh
模板:https://github.com/zhangnq/zabbix/blob/master/template/tomcat_thread_status_zbx_v3_template.xml
配置:https://github.com/zhangnq/zabbix/blob/master/conf/tomcat_thread_status.conf
项目地址:https://github.com/zhangnq/zabbix