利用zabbix的自动发现功能自动发现tomcat服务并监控日志中出现的关键字的频次
一、简介
zabbix的自动发现功能需要传输的数据为json格式的,可以使用Python格式json.dump进行json格式化,也可以使用shell,利用printf,进行打印出json格式的回显。所以,自动发现功能可以有Python书写,也可以由shell进行书写。
当然本篇除了自动发现的功能之外能,还有一个功能是根据自动发现功能的发现的tomcat服务,去监控这些自动发现的tomcat服务的一些关键字。所以会有两个脚本,一个是关于自动发现功能的,一个是监控日志关键字的。
二、相关的脚本
1、自动发现tomcat服务功能
这个脚本暂时只有python版本,先欠着shell版本,等开心了再开发shell脚本
Python版本是python3
vim tomcat_name_discovery.py #!/usr/bin/python3 # -*- coding: UTF-8 -*- import os import subprocess import simplejson as json TOMCAT_HOME="/usr/local/tomcat/" #TOMCAT_NAME="/bin/find 'TOMCAT_HOME' -name 'server.xml' | sort -n | uniq -c | awk -F'/' '{print $4}'" #TOMCAT_NAME="/bin/find /usr/local/tomcat/ -name 'server.xml' | sort -n | uniq -c | awk -F'/' '{print $5}'" ##两种检测tomcat的方式,下面这个,如果是tomcat的目录下的项目的话,用下面这个,如果,直接在/usr/local下面直接就是项目,那就用现在打开的这个吧,pycharm 这个本地调试需要禁用 #TOMCAT_NAME="ps -ef |grep java|grep tomcat|grep -v grep|grep -v pycharm |awk '{ print $9 }'|awk -F '/' '{ print $(NF-2) }'" TOMCAT_NAME="ps -ef |grep java|grep -v grep|grep -v pycharm |awk '{ print $9 }'|awk -F '/' '{ print $(NF-2) }'" t=subprocess.getoutput(TOMCAT_NAME) tomcats=[] for tomcat in t.split('\n'): if len(tomcat) != 0: tomcats.append({'{#TOMCAT_NAME}':tomcat}) # # 打印出zabbix可识别的json格式 print(json.dumps({'data':tomcats},sort_keys=True,indent=4,separators=(',',':')))
2、监控日志关键字功能
vim log_keyword.py #!/usr/bin/python3 # -*- coding: UTF-8 -*- ######################################################################### # 监控日志,分析关键字,供zabbix报警 # 将脚本放在/usr/local/zabbix/sbin/目录下,给zabbix用户赋予执行权限 # Create Date : 2019-05-30 # Written by : yuwei # python-version:3 ######################################################################### import sys import os import subprocess def init_log_tmp(log_path): # 检测linux目录是否存在,不存在创建 if os.path.exists(os.path.split(zabbix_monitor_log_tmp)[0]): pass else: # print() subprocess.getoutput('mkdir -p %s ' %(os.path.split(zabbix_monitor_log_tmp)[0]) ) # 检测tmp文件是否存在,不存在创建 if os.path.exists(zabbix_monitor_log_tmp): pass else: with open(zabbix_monitor_log_tmp, 'w') as c_tmp_file: c_tmp_file.write(log_path + ' 0\n') def check_log(log_path ,error_key): # 检测文件是否存在 if os.path.exists(log_path): pass; else: # print '\nERROR ' +log_path +' not found!!!' print("\nERROR %s not found!!!"%log_path) show_help() # 从zabbix_monitor_log_tmp中找到log_path上一次读取的最后一行的行号,如果之前没有记录,则认为是从第一行开始 init_log_tmp(log_path) # 获取log_path现在共有多少行 log_path_line = subprocess.getoutput("wc -l %s |awk '{print $1}'"%log_path) # 从zabbix_monitor_log_tmp中获取上次检测时的行号,下面第一行当时考虑有多个logpath,在zabbix中使用并不是太好,改为一个记录文件只记录一个应用的单个keyword # log_path_line_last = subprocess.getoutput('awk \'{if ($1=="%s") {print $2}}\' %s'%(log_path,zabbix_monitor_log_tmp)) log_path_line_last = subprocess.getoutput("awk '{print $2}' %s"%zabbix_monitor_log_tmp) # 如果log_path_line_last为空,说明这个日志文件之前没有检测过,现在认为log_path_line_last=0 if len(log_path_line_last) == 0: log_path_line_last =0 # 由于文件之前没有检测过,因此要添加到zabbix_monitor_log_tmp中 with open(zabbix_monitor_log_tmp, 'w') as c_tmp_file: c_tmp_file.write('%s %s\n'%(log_path,str(log_path_line_last))) # 做差值计算结果便是本次检测需要从文件结尾tail的行数,如果差值是负数则检查全部日志 if int(log_path_line) < int(log_path_line_last): # 说明日志文件发生了替换 cha = log_path_line elif int(log_path_line) == int(log_path_line_last): # 说明日志文件没有发生任何变化,直接打印0并退出 key_count = 0 print(key_count) sys.exit(0) else: cha = int(log_path_line) - int(log_path_line_last) # 把关键字字符串做处理,将分隔符由,改为| error_key_new = subprocess.getoutput("echo %s|sed 's/,/|/g'"%(error_key)) # # 获取关键词在时间范围内出现的次数 key_count = subprocess.getoutput('tail -n %s %s |grep -cE "%s"'%(str(cha),log_path,error_key_new)) print(key_count) # 更新tmp中log_path的行数 with open(zabbix_monitor_log_tmp, 'w') as c_tmp_file: c_tmp_file.write('%s %s\n' % (log_path, str(log_path_line))) # 帮助 def show_help(): print(''' HELP: %s [LOG_PATH] [ERROR_KEY] LOG_PATH: absolute path ERROR_KEY: keyword,multi use ',' separate. EXP: %s /var/log/tomcat.log error_warning '''%(sys.argv[0],sys.argv[0])) sys.exit(1) if __name__ == '__main__': if len(sys.argv) == 3: #获取应用的目录名称,一般以项目名称作为该项目的tomcat的名称 app_name =sys.argv[1] #要检测的关键字 error_key =sys.argv[2] ##根据app_name 获取到app的catalina.base或者catalina.name appdir=subprocess.getoutput("ps -ef |grep %s|grep -v grep |awk '{ print $(NF-4) }'|awk -F '=' '{ print $2 }'"%app_name).strip('\n') log_path="%s/logs/catalina.out"%(appdir) # 将日志文件最后一行记录到tmp文件,用于下一次检测关键字时定义开头,文件格式“日志绝对路径 上一次检测的最后一行的行号” # zabbix_monitor_log_tmp = "%ssbin/tomcat/%s_%s_line.safe"%(zabbix_base,app_name,error_key) zabbix_monitor_log_tmp = "/usr/local/zabbix_agentd/sbin/tomcat/%s_%s_line.safe"%(app_name,error_key) check_log(log_path ,error_key) else: show_help()
注意:
以上脚本都需要添加执行权限,或者是在执行的时候使用/usr/bin/python3 tomcat_name_discovery.py
三、配置zabbix客户端并测试
在zabbix客户端的配置文件(/usr/bin/zabbix_agentd/etc/zabbix_agentd.con)中添加字段
UnsafeUserParameters=1 UserParameter=tomcat.name.discovery, /usr/local/zabbix_agentd/sbin/tomcat_name_discovery.py UserParameter=tomcat.log.monitor[*], /usr/local/zabbix_agentd/sbin/log_keyword.py $1 $2
修改完成后重启zabbix_agentd 服务。
/etc/init.d/zabbix_agentd restart
在服务端测试能否获取到自动发现的端口号
/usr/local/zabbix/bin/zabbix_get -s 192.168.x.xx -p 10050 -k "tomcat.name.discovery" ###如果返回以下内容表示能自动发现端口号; ###如果不能正确返回,请自行检查zabbix客户端的日志文件,看报错,还可以在终端中自行执行,看能否返回如下格式的数据 { "data":[ { "{#TOMCAT_NAME}":"tomcat1" }, { "{#TOMCAT_NAME}":"tomcat2" }, { "{#TOMCAT_NAME}":"tomcat3" } ] }
/usr/local/zabbix/bin/zabbix_get -s 192.168.x.xx -p 10050 -k "tomcat.log.monitor[zqsign-service-callback Null]" #如果不能正常返回信息,则会提示:ZBX_NOTSUPPORTED #如果能正常返回信息,会提示发现的关键字的个数,如下图
四、zabbix的web页面配置自动发现
1、zabbix前端页面中创建一个Template
2、创建完成后进入该Template,创建Applications,
3、点击Discovery rules选项,然后创建自动发现规则
下面是我创建的规则:
其中key那个地方字段一定要填为“三”中配置的“UserParameter=tomcat.name.discovery”的“tomcat.name.discovery”
创建完成后,点击Item prototypes选项创建监控项
下面是我创建完成的监控项
此处的key是:UserParameter=tomcat.log.monitor[*], /usr/local/zabbix_agentd/sbin/log_keyword3.py $1 $2中的“tomcat.log.monitor”
填好框中的选项之后,点击Add选项,即可创建监控项;
5、下面开始创建告警规则。
点击上图中的创建Create trigger prototype
在上图的第二个框中,可以点击add进行添加“Expression”,点击Add选项之后,出现下图
然后点击红色框选中的选项,既可快速的选中监控项,在上图中的Result中,选择自己想要的即可。因为我监控的是日志关键字,所以出现的频次大于0 我就会触发告警。
6、添加图形显示
这个图形,如果需要的话,可以监控,如果不需要,就不添加。
五、主机关联模板
可以在下面的红线框中输入Template名称然后就会自动出现,然后添加即可。点击add之后,需要在点击update,进行更新。
添加完成之后,可以在“Configure”》》“Hosts”》》“items”中看到下图的内容,表示添加监控已经成功了
出现上面图,是监控的日志关键字,表示能正常使用
六、说一下碰到的问题吧。
1、执行脚本的时候发现提示 Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.
这个错误是由于zabbix用户启动的zabbix服务,默认没有执行netstat命令的权限,有两种解决方法:
###第一种,在/etc/sudoers 中添加一条命令 #Defaults requiretty 注释掉这个 zabbix ALL=(ALL) NOPASSWD: ALL ###第二种,是给所使用的命令赋予s的权限 chmod +s /bin/netstat #“chmod +s”命令的含义是:为了方便普通用户执行一些特权命令,SUID/SGID程序允许普通用户以root身份暂时执行该程序,并在执行结束后再恢复身份。
2、添加自动发现端口后出现报错“Value should be a JSON object.”的报错
可能的原因也是上面的那个报错引起的
“http://www.voidcn.com/article/p-npjtgyco-bpa.html”上面的这个链接给了一个完美的解答,在此借鉴一下;
也有可能是下面的这个原因
后记:本文是本人亲手测试之后书写而成,其中的一些脚本可能有借鉴网上某兄弟的脚本的成分,在此感谢被借鉴的朋友。
- 点赞
- 收藏
- 关注作者
评论(0)