内容简介:先说一下背景,有服务跑的地方就有监控,有监控的地方往往少不了zabbix的优美身影,搞监控我大胆猜一下,朋友们很多都有监控日志的需求,比如老板让你监控一下服务的 "ERROR" 日志,监控一下java 的 NPE,Full GC 等等zabbix 内部自带了日志的监控模块,但是我在使用的时候发现确实很不好用(可能是我不会用
拖了很久终于下定决心来写这篇博客,希望真的能对有需要的朋友有所帮助
先说一下背景,有服务跑的地方就有监控,有监控的地方往往少不了zabbix的优美身影,搞监控我大胆猜一下,朋友们很多都有监控日志的需求,比如老板让你监控一下服务的 "ERROR" 日志,监控一下 java 的 NPE,Full GC 等等
zabbix 内部自带了日志的监控模块,但是我在使用的时候发现确实很不好用(可能是我不会用
先看一下效果, 下面是监控java 服务 Full GC 的场景,配置好之后,就可以查看数据,在latest data 中可以看到获取到的日志信息 选择你关联配置了日志监控的主机,查看数据
其中None 为没匹配到关键词的输出,转换为None 来输出是为了简化数据的输出
输出还有一种情况下是 Noline , 不要慌,这种情况是因为两次采集的间隔时间段没有新的记录,使用时间戳来解决会重复读取记录而误报的问题
如何配置
1、配置模板
和配置其他item 没有太大的区别
Key :这里 需要配置的4个参数依次为:
logpath : 日志的路径
50:表示一次读取的行数,可以根据自己日志刷新频率适当设置
'stringkey' : 要检索的字符串
60 : 执行脚本的间隔 (和 Update interval 的必须值一致)
Type of information :配置为 log 类型
trigger 的配置,可以根据自己的需求来定义告警阈值
Name: 根据场景 设置容易识别的醒目的内容
Severity: 告警的级别
Expression: 如图 配置,我这里使用了count, 表示连续8次检测, 检测到关键词的次数大于3次就告警
2、模本配置完了,咱们搞一下插件
在你的agent 的 bin 目录先增加 monitorlogs.py 脚本(注意增加执行权限)
#!/usr/bin/env python
# *_* coding:utf8 *_*
__author__ = 'xbzy007'
import subprocess, os, sys
import time, datetime
import re
import traceback
class FindOut(object):
def __init__(self, logfile, linenums, stringkeys, interval):
self.logfile = logfile
self.linenums = linenums
self.stringkeys = stringkeys
self.interval = interval
self.logtype_a = '^([0-9]+\-){2}[0-9]+T[0-9]*'
self.logtype_b = '^([0-9]+\-){2}[0-9]+ [0-9]*'
def getlogtimetype(self, loglinelist):
logtype_tag = ''
for i in range(0,len(loglinelist),1):
line = loglinelist[i]
if re.match(self.logtype_a, line, flags=0):
logtype_tag = self.logtype_a
elif re.match(self.logtype_b, line, flags=0):
logtype_tag = self.logtype_b
return logtype_tag
def filterthelogfile(self):
#if not os.path.exists(self.logfile):
# print "{0} not exist".format(self.logfile)
# sys.exit(0)
match_logname = self.logfile
logdir = os.path.abspath(os.path.dirname(self.logfile) + os.path.sep + ".")
logfilenamelist = []
lastlogfile = ''
lastmtime = 338054400.0
for tfile in os.listdir(logdir):
filepath = os.path.join(logdir, tfile)
matchx = re.match(match_logname, filepath, flags=0)
if matchx :
if os.path.isfile(filepath):
logfilenamelist.append(filepath)
if len(logfilenamelist):
for onelogfile in logfilenamelist:
filemtime = os.path.getmtime(onelogfile)
if filemtime > lastmtime:
lastmtime = filemtime
lastlogfile = onelogfile
if lastlogfile:
return lastlogfile
else:
print "not found newest logfile"
return None
def findoutstring(self):
logfile = self.filterthelogfile()
if logfile :
p = subprocess.Popen("tail -%s %s" % (self.linenums, logfile), \
env=None, shell=True, stdout=subprocess.PIPE)
out, err = p.communicate()
p.wait()
if (p.returncode == 0):
res = out.strip('\n')
else:
print "open %s Failed" % logfile
sys.exit(1)
else :
print "%s not found" % logfile
sys.exit(2)
#### 标记值,标记在给定的时间段是否有记录
tags = 0
curtimestamp = time.time()
getlineslist = res.split('\n')
logtype = self.getlogtimetype(getlineslist)
if logtype == self.logtype_b :
###### 查找符合时间区域的第一条记录
for i in range(0,len(getlineslist),1):
line = getlineslist[i]
var = line.strip()
try:
strtime = var.split()[0] + ' ' +var.split()[1]
strtime = strtime.split(',')[0]
timeArray = time.strptime(strtime, "%Y-%m-%d %H:%M:%S")
timestamp = time.mktime(timeArray)
contrasttime = int(curtimestamp) - self.interval
if int(timestamp) > contrasttime :
tags += 1
break
except :
#traceback.print_exc()
continue
elif logtype == self.logtype_a :
###### 查找符合时间区域的第一条记录
for i in range(0,len(getlineslist),1):
line = getlineslist[i]
var = line.strip()
try:
strtime = var.split()[0]
strtime = strtime.split('.')[0]
strtime = strtime.replace('T', ' ')
timeArray = time.strptime(strtime, "%Y-%m-%d %H:%M:%S")
timestamp = time.mktime(timeArray)
contrasttime = int(curtimestamp) - self.interval
if int(timestamp) > contrasttime :
tags += 1
break
except :
#traceback.print_exc()
continue
else:
print 'logtype can not be analysis'
sys.exit(4)
########### 在符合的记录中查找 关键字,起始位置为上一步查到的标记位i
if tags:
for j in range(i, len(getlineslist), 1):
line = getlineslist[j].strip()
res = re.search(self.stringkeys, getlineslist[j], flags=0)
if res:
line = line + ' logsmonitor'
return line
return None ###没有找到有关键字的记录
else :
return 'Noline' ### 在规定的时间段没有找到符合的记录(老的数据)
if __name__ == '__main__' :
if len(sys.argv) < 4 :
print "need 4 args: [ logfile ] [ readline nums ] [ stringkeys ] [ interval time ]"
sys.exit(-1)
logfile= sys.argv[1]
getlinenums = int(sys.argv[2])
if getlinenums > 1000 :
getlinenums = 1000
stringkeys = sys.argv[3]
interval = int(sys.argv[4])
#x = FindOut(logfile, , 'to active state', interval)
x = FindOut(logfile, getlinenums, stringkeys, interval)
res = x.findoutstring()
print res
在你的agent 的 etc/zabbix_agentd.conf.d/ 下面增加插件对应的配置文件:UserParametermonitorlogs.conf
UserParameter=mlogs[*],/usr/local/zmonitor/bin/monitorlogs.py "$1" "$2" "$3" "$4"
然后重启 agent
最后给你需要监控日志的主机关联上模板就可以完成日志的监控, 是不是想实战验证一把,希望能解决你同样的困扰,让世上没有难搞的监控
以上所述就是小编给大家介绍的《zabbix 日志监控(自定义插件开发)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 云监控开源 v3.5 bug fix 以及监控插件开发支持
- xrkmonitor 字符云监控系统 v2.2 发布,新增 Linux 文件目录监控插件
- Fundebug发布Vue插件,简化BUG监控接入代码
- xrkmonitor 字符云监控系统 v3.0 支持自定义统计周期、支持插件灰度、引入插件看板等
- Fundebug前端异常监控插件更新至2.4.0,支持配置breadcrumbSize
- xrkmonitor 字符云监控系统 v2.7 插件一键部署逻辑改进
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Programming Collective Intelligence
Toby Segaran / O'Reilly Media / 2007-8-26 / USD 39.99
Want to tap the power behind search rankings, product recommendations, social bookmarking, and online matchmaking? This fascinating book demonstrates how you can build Web 2.0 applications to mine the......一起来看看 《Programming Collective Intelligence》 这本书的介绍吧!