利用zabbix的自动发现功能自动发现tomcat服务并监控日志中出现的关键字的频次
【摘要】 zabbix自动发现java的端口号,并添加监控以及告警。
一、简介
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”上面的这个链接给了一个完美的解答,在此借鉴一下;
也有可能是下面的这个原因
后记:本文是本人亲手测试之后书写而成,其中的一些脚本可能有借鉴网上某兄弟的脚本的成分,在此感谢被借鉴的朋友。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)