zabbix自动发现结合shell实现自动发现占用内存最大top10进程并监控其资源

zabbix自动发现结合shell实现自动发现占用内存最大top10进程并监控其资源,第1张

zabbix自动发现结合shell实现自动发现占用内存最大top10进程并监控其资源

最近在思考一个问题。在线服务器运行各种服务。可能这个运行nginx,那个运行mysql,其他的运行nfs或者其他服务等等。有些服务是用一定的脚本编写的,用来监控所有服务器的进程占用情况。如果该服务器运行的服务不在固定列表中,则监控服务无法获取相应的数据。

为了解决这个问题,我最近在想zabbix的自动发现功能是否可以自动发现占用服务器内存最大的N个进程,然后监控这些进程的内存和CPU资源来获取数据。于是这篇文章诞生了。

首先,我们需要得到最高指挥部的结果。您可以使用以下命令将top命令获得的结果重定向到一个文件:

top -b -n 1 >/tmp/top.txt

该命令意味着执行一次top命令,并将结果重定向到top.txt文件。

将该命令添加到zabbix用户的预定任务中,每分钟执行一次。该命令如下所示:

crontab -e */1 * * * * top -b -n 1 >/tmp/top.txt

放进去之后,会在tmp目录下生成一个top.txt文件。

$ head -10 /tmp/top.txt  top - 15:42:01 up 72 days, 22:25,  2 users,  load average: 0.09, 0.08, 0.06 Tasks: 880 total,   1 running, 879 sleeping,   0 stopped,   0 zombie %Cpu(s):  2.8 us,  0.7 sy,  0.0 ni, 96.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st KiB Mem : 13175284+total, 97396048 free, 20357148 used, 13999640 buff/cache KiB Swap: 32767996 total, 32452380 free,   315616 used. 11058964+avail Mem     PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND  20732 zabbix    20   0  130716   2436   1204 R  11.8  0.0   0:00.03 top 126808 upload    20   0 8375636 945876  27268 S   5.9  0.7  63:33.97 java 127591 upload    20   0 9898.1m 1.078g  27960 S   5.9  0.9  63:58.01 java

==========================================================================================

==========================================================================================

==========================================================================================

好的,你得到数据后,你需要处理它。这里有两个脚本,一个是获取占用内存资源最高的进程的名称,另一个是获取某个进程占用内存和cpu资源的信息。让我们先看看第一个脚本:

$ cat scripts/check_process.sh  #!/bin/bash TABLESPACE=`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$6}END{for(k in a)print a[k]/1024,k}'|sort -gr|head -10|cut -d" " -f2` COUNT=`echo "$TABLESPACE" |wc -l` INDEX=0 echo '{"data":[' echo "$TABLESPACE" | while read LINE; do     echo -n '{"{#TABLENAME}":"'$LINE'"}'     INDEX=`expr $INDEX + 1`     if [ $INDEX -lt $COUNT ]; then         echo ','     fi done echo ']}'

最关键的一个是`tail-n+8/tmp/top.txt|awk'{a[$nf]+=$6}end{for(Kina)printa[K]/1024,K}'|sort-gr|head-10|cut-d""-f2`这个命令:这个命令的意思是从top.txt文件中取出第八行到最后一行的数据,然后用awk累加这些数据。效果是以最后一列为关键字,累加每个关键字对应的第六列的值,输出第六列和最后一列的累加结果。然后用sort排序。注意,这里的参数是-gr而不是-nr,因为第六列的值以KB为单位。如果一个进程占用的内存超过10G,它将使用科学记数法进行计数。sort-nr参数不能计算科学记数法,所以需要将参数改为-gr,其中-r是反向排序。同时,为了防止zabbix得到的值被科学记数法识别,先将值/1024改为MB,然后在zabbix得到数据后*1024*1024将值恢复为BYTE。Head-10就是把占用内存最多的十个进程拿出来,然后对数据进行切割,得到这十个进程的进程名。至于下面的代码,是json格式化得到的十个进程名的输出,输出结果如下:

$ sh ./scripts/check_process.sh  {"data":[ {"{#TABLENAME}":"java"}, {"{#TABLENAME}":"docker"}, {"{#TABLENAME}":"nginx"}, {"{#TABLENAME}":"sshd"}, {"{#TABLENAME}":"tuned"}, {"{#TABLENAME}":"NetworkMa+"}, {"{#TABLENAME}":"zabbix_ag+"}, {"{#TABLENAME}":"systemd-j+"}, {"{#TABLENAME}":"crond"}, {"{#TABLENAME}":"rsyslogd"}]}

至于为什么需要json格式化,之前的博客已经解释过了,因为zabbix自动发现获取的值的格式是json格式化的值才可以识别。

第二个脚本的作用是获取某个进程占用的cpu和内存资源。该脚本的内容如下:

$ cat ./scripts/processmonitor.sh  #!/bin/bash process=$1 name=$2 case $2 in mem) echo "`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$6}END{for(k in a)print a[k]/1024,k}'|grep "$process"|cut -d" " -f1`" ;; cpu) echo "`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$9}END{for(k in a)print a[k],k}'|grep "$process"|cut -d" " -f1`" ;; *) echo "Error input:" ;; esac exit 0

这个脚本的核心和上一个脚本非常相似。我相信读者很容易理解上面的脚本和下面的脚本。以下是脚本执行的结果:

$ sh ./scripts/processmonitor.sh java mem 13115.5 $ sh ./scripts/processmonitor.sh java cpu 17.7

在可以获取值之后,需要在zabbix_agentd.conf中配置相应的键值来获取数据。需要添加以下配置:

$ tail -3 ./etc/zabbix_agentd.conf #top_process UserParameter=process.discovery,/home/zabbix/zabbix-2.4.4/scripts/check_process.sh UserParameter=process.resource[*],/home/zabbix/zabbix-2.4.4/scripts/processmonitor.sh $1 $2

添加完这个配置后,需要重启zabbix_agentd使配置生效,需要使用pkillzabbix&zabbix-2.4.4/sbin/zabbix_agentd

==========================================================================================

==========================================================================================

==========================================================================================

不好意思,上面用====框起来的代码有问题。经过博主的提醒,我已经发现问题了。top命令中,内存占用单位默认为KB,但当某个进程占用大量内存时,其单位就会变成MB甚至GB,甚至TB。目前无法通过awk得到正确的值(不好意思,我水平有限,但是对不起aww所以,今天我用python实现了上框的代码,把我用python写的脚本贴在了下面:

$ cat process.py  #!/usr/bin/env python # -*- coding: utf-8 -*- # author: huxianglin #date:2015-09-11 import string import sys def read_line(line):     line = line.strip('\n').strip()     programname = line.split()[11]     memoryuse = line.split()[5]     cpuuse = line.split()[8]     return programname,memoryuse,cpuuse def getdate(file_path):     with open(file_path) as f:         for line in range(1,8):             next(f)         result=[]         for line in f:             result.append(list(read_line(line)))     return result def topprogram(file_path):     date=getdate(file_path)     top={}     for i in date:         if 't' in i[1]:             i[1]=string.atof(i[1].split('t')[0])*1073741824         elif 'g' in i[1]:             i[1]=string.atof(i[1].split('g')[0])*1048576         elif 'm' in i[1]:             i[1]=string.atof(i[1].split('m')[0])*1024         else:             i[1]=string.atof(i[1])         if top.get(i[0]):             top[i[0]]=[top[i[0]][0]+i[1],top[i[0]][1]+string.atof(i[2])]         else:             top.setdefault(i[0],[i[1],string.atof(i[2])])     return sorted(top.items(),key=lambda d:d[1][0])[-1:-11:-1] def translatejson(file_path):     data=topprogram(file_path)     print'{"data":['     for i in data:         if i != data[-1]:             print '{"{#TABLENAME}":"%s"},' %i[0]         else:             print '{"{#TABLENAME}":"%s"}]}' %i[0] def printdata(file_path,key):     data=topprogram(file_path)     for i in data:         if key[1] == 'cpu':             if key[0] == i[0]:                 print i[1][1]         else:             if key[0] == i[0]:                 print i[1][0] def main():     file_path='/tmp/top.txt'     if sys.argv[1] == 'json':         translatejson(file_path)     else:         key = [sys.argv[1],sys.argv[2]]         printdata(file_path,key) if __name__=='__main__':     main()

使用上面的python代码输入的参数略有变化。下面是使用效果:

$ ./process.py json {"data":[ {"{#TABLENAME}":"java"}, {"{#TABLENAME}":"haproxy"}, {"{#TABLENAME}":"docker"}, {"{#TABLENAME}":"nginx"}, {"{#TABLENAME}":"sshd"}, {"{#TABLENAME}":"systemd-j+"}, {"{#TABLENAME}":"bash"}, {"{#TABLENAME}":"rsyslogd"}, {"{#TABLENAME}":"tuned"}, {"{#TABLENAME}":"NetworkMa+"}]} [zabbix@dev01 scripts]$ ./process.py java mem 36773689.408 [zabbix@dev01 scripts]$ ./process.py java cpu 77.9

上面得到的数据是服务器占用的真实资源,之前的shell脚本无效。当脚本传入的参数改变时,zabbix_agentd.conf中的参数必须修改如下:

$ tail -3 /home/zabbix/zabbix-2.4.4/etc/zabbix_agentd.conf #top_process UserParameter=process.discovery[*],/home/zabbix/zabbix-2.4.4/scripts/process.py $1 UserParameter=process.resource[*],/home/zabbix/zabbix-2.4.4/scripts/process.py $1 $2

好了,客户端已经配置成功了。接下来需要验证服务器端是否可以获取数据,在服务器端使用zabbix_get命令获取数据。以下是执行结果:

$ zabbix/bin/zabbix_get -s xxx.xxx.xxx.xxx -k"process.discovery[json]" {"data":[ {"{#TABLENAME}":"java"}, {"{#TABLENAME}":"docker"}, {"{#TABLENAME}":"nginx"}, {"{#TABLENAME}":"sshd"}, {"{#TABLENAME}":"tuned"}, {"{#TABLENAME}":"NetworkMa+"}, {"{#TABLENAME}":"zabbix_ag+"}, {"{#TABLENAME}":"systemd-j+"}, {"{#TABLENAME}":"rsyslogd"}, {"{#TABLENAME}":"bash"}]}

上面的xxx.xxx.xxx.xxx代表客户端的IP地址,-k后面的参数是我们刚刚添加到客户端的参数。

$ zabbix/bin/zabbix_get -s xxx.xxx.xxx.xxx -k"process.resource[java,mem]" 13115.6 $ zabbix/bin/zabbix_get -s xxx.xxx.xxx.xxx -k"process.resource[java,cpu]" 0

好的,在服务器端测试客户端没有问题,数据可以获取。接下来,您需要在web端配置模板。

在配置-模板-创建模板中创建一个模板,名为templetop_process,如下图所示:

创建一个名为“进程资源顶部”的应用程序集,如下图所示:

在创建之后,我们需要添加发现规则,这是我们的亮点。创建新的发现规则,如下图所示:

的键值是我们在客户端上配置的键值。我把数据更新间隔设置为5分钟,也就是说每隔5分钟它就会去客户端获取占用内存最多的十个进程,然后取它们的内存和cpu资源数据。现在您需要配置项目原型,如下图所示:

如上图所示,{#TABLENAME}获取十个进程名的列表,process.resource[{#tablename},mem]是我们在客户端配置的键值,其中获取的内存值单位为MB。这里转换成字节单位,所以获取的值*1024*1024=1048576,单位改为字节,这样应用到项目中,一个项目原型就成功了。以下是cpu占用资源的原型配置:

添加项目原型后,需要配置图形原型,如下图所示:

添加图形原型后,模板更改成功。接下来,将模板添加到主机,就可以获取数据了。这里,因为我设置的自动发现时间间隔是5分钟,所以在图形出现之前,我需要等待5分钟以上。这是出现的图形效果。

这是内存占用量最大的十个进程的资源占用图。下面是详细效果。

这是新获得的数据。至此,通过自动发现对top10进程占用资源的监控结束。这只是我自己匆忙写的一个监控方法。拿出来供大家参考。如果有更好的办法,可以和我一起探讨,共同进步。我会把zabbix模板放在附件里供你下载。


由于参数略有变化,模板文件也略有修改。我将把修改后的模板文件上传到附件中。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/779961.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-04
下一篇 2022-05-04

发表评论

登录后才能评论

评论列表(0条)

保存