深入浅出Zabbix 3.0 -- 第十四章 灵活的脚本扩展

    xiaoxiao2024-12-12  18

    第十四章 灵活的脚本扩展

    近日完成《深入浅出 zabbix 4.0》视频教程的录制并正式发布,该教程基于 zabbix 4.2 ,对Zabbix进行全面讲解。欢迎大家围观。课程链接:https://edu.csdn.net/course/detail/24870

    学习到本章时,相信你已经掌握了Zabbix服务器的各个组件是如何工作的,以及通过Zabbix收集数据的方法,但在实际环境中,你可能会面对一个大型的、异构、复杂的基础设施,你会发现有很多不同的应用平台和系统,服务器和网络设备,还有可能有很多定制的设备和专用的硬件产品,这些设备的共同点是都提供网路接口。对于常规的服务器及网络设备可以轻松的使用Zabbix提供的监控方式收集数据,但是还是会有一些应用系统或设备无法通过Zabbix提供的标准查询方法或SNMP收集监控数据。

    假设在实际环境中用一个用户定制的设备,只能通过特定的客户端软件能够收集设备内部温度传感器提供的当前温度,这是一个关键性的指标现在必须要通过Zabbix进行监控。在这种场景下,必须通过脚本调用客户端软件收集监控数据。另外,还有很多应用系统如Nginx通过stub_status模块提供运行状态信息,Redis通过命令redis-cli info可以收集系统的运行状态。

    Zabbix为了满足这类场景,提供了以下几种方式收集监控数据:

    在Zabbix server中运行脚本收集监控数据(External checks)

    在Zabbix agent中运行脚本收集监控数据(UserParameter)

    在Zabbix server或agent中运行脚本收集监控数据(Zabbix_sender)

    依据Zabbix协议自行开发工具收集监控数据

     

    14.1 Zabbix Server中运行脚本

    在实际环境中,你可能无法在监控设备中安装标准的Zabbix agent收集监控数据,通过Externalchecks监控方式,可以在Zabbix server上执行脚本或二进制程序收集监控数据。

    在使用这种方式前,需要在zabbix-server.conf配置文件中定义脚本或程序的路径,设置正确的权限能够让Zabbix执行。

    # vi /etc/zabbix/zabbix-server.conf

    ExternalScripts=/usr/lib/zabbix/externalscripts

    ExternalScripts 可以使用系统标准的路径,你也可以指定其他路径。在这里我们可以把脚本或程序放在这里,并设置相应的权限。

    使用External checks时需要注意以下几点:

    在Key语法中支持多个逗号分隔的参数。

    在脚本命令中支持用户定义的宏变量。

    External checks通过标准输出(STDOUT)将错误返回,可以在触发器中进行管理。

    支持多行的返回值。

    通过External checks可以完成很复杂的监控任务,但是在实际环境中使用时要注意服务器性能的问题,每一次脚本执行时需要Zabbix server启动一个进程,当有很多脚本运行时会降低Zabbix server的性能。

    具体创建External checks监控方式的监控项步骤请参考第三章。

     

    14.2 Zabbix agent中运行脚本

    为了防止在服务器上运行脚本占用大量资源,影响服务器性能,Zabbix提供了一种方法即UserParameter,我们可以把脚本放到Zabbix agent上运行。

    UserParameter是在agent配置文件中定义的。语法如下:

    UserParameter=<key>,<command>

    User parameter由两部分组成,一部分是Key,在这里定义的Key在Zabbix server前端页面中创建item时会用到,并且在引用这个Key的主机中名称必须是唯一的,Key的名称中我们可以使用点或下划线,但不能有空格或其他特殊字符。另一部分是command,是一个可执行的命令或脚本。

    在User parameter中定义key时,我们也可以设定参数,这些参数可以传递给命令或脚本。语法是:

    UserParameter=key[*],command

    [*]表示可以传递多个参数,对应[*]中参数的位置,在command中可以使用$1,$2,$3 …$9来引用参数,$0代表command本身。如果在使用的命令行中引用$2这种参数,那就需要变成$$2,例如:awk '{print $$2}',在这种情况下$$2实际上引用的是$2参数。另外,像$2这些参数你即使用双引号(”)或单引号(‘)括起来,它也会正常解析相应位置的参数。

    通过Zabbix agent支持User parameter中的命令,最多返回512KB大小的数据。如果达到agent配置文件中定义的超时时间,这个User parameter进程会被杀掉。Userparameter返回的文本中(type ofinformation为character、log或text)可以包括空格,返回值无效时item将变成unsupported。

    为了更好的理解UserParameter,下面举几个例子。

    UserParameter=ping,echo 1

    总是返回1。

    UserParameter=ping[*],echo $1

    ping[0] 将返回 '0';ping[aaa] 将返回 'aaa'。

    UserParameter=mysql.ping,mysqladmin–uroot -p<password> ping | grep -c alive

    如果MySQL运行正常返回1,否则返回0。

    UserParameter=mysql.ping[*],mysqladmin-u$1 -p$2 ping | grep -c alive

    mysql.ping[zabbix,our_password] 会把用户名和密码传递到命令行中参数引用的位置。

    UserParameter=wc[*],grep -c"$2" $1

    wc[/etc/services,zabbix],计算在services文件中包含zabbix的行数,在这里$2用双引号括起来后,在命令行中还是会正确引用相应位置的参数。

    通常的做法是:

    1、  编辑zabbix_agentd.conf配置文件,配置UserParameter选项。比如:

    UserParameter= process.number[*], ps -e |grep $1 | wc -l

    2、  使用zabbix-agentd -t 测试定义的UserParameter

    # zabbix_agentd -t process.number[httpd]

    process.number                     [t|8]

    3、  保存agent 配置文件,重启agent.

    # systemctl restart zabbix-agent.service

    4、  使用zabbix_get工具测试:

    # zabbix_get -s 127.0.0.1 -k process.number[httpd]

    8

    5、  在Zabbix server中的主机上创建一个新的监控项。类型可以是Zabbix agent或者Zabbix agent(active)。如下图14-1所示。

                                 

    图 14-1

    6、  打开Monitoring --> Latest data 页面,稍等片刻后你就能看到httpd process number这个监控项的返回值了。

     

    14.3 使用zabbix_sender发送数据

    Zabbix也提供了工具用来发送数据到server,这个工具就是zabbix_sender。使用zabbix_sender之前,需要在Zabbix server前端页面中添加类型为Zabbixtrapper的监控项。如下图14-2所示。

    图 14-2

    Zabbix_sender用法可以通过 -h 阅读帮助文件,也可以浏览Zabbix网站的页面https://www.zabbix.com/documentation/3.0/manpages/zabbix_sender。下面介绍一些主要的参数和用法。

    参数说明:

    -c, --config config-file:Zabbix sender从agent配置文件中读取有关server的信息,如果不使用这个参数,默认Zabbixsender是不读取配置文件的。config-file必须指定配置文件的绝对路径。目前仅支持Hostname、ServerActive和SourceIP,ServerActive配置有多个服务器时将使用第一个服务器的配置。

    -z, --zabbix-server server:Zabbix server的主机名或IP地址。如果是使用proxy进行监控,这里应该是proxy的主机名或IP地址。如果和--config一起使用,当前该参数的设置将覆盖配置文件中ServerActive的第一个服务器配置的IP或主机名。

    -p, --port port:Zabbix server trapper运行的端口,默认是10051。如果和--config一起使用,当前该参数的设置将覆盖配置文件中ServerActive的第一个服务器配置的端口。

    -I, --source-address IP-address:指定源IP地址。如果和--config一起使用,当前该参数的设置将覆盖配置文件中SourceIP的设置。

    -s, --host host:指定接收监控项数据的主机名称,在这里不能使用主机IP或DNS主机名。如果和--config一起使用,当前该参数的设置将覆盖配置文件中Hostname的设置。

    -k, --key key:指定发送数据的监控项的key。

    -o, --value value:指定监控项的值。

    -i, --input-file input-file:从文件中加载发送的数据。指定input-file为 – 时将从标准输入读取数据。输入文件的内容每行的格式为<hostname> <key> <value>,每个参数直接用空格分隔。其中hostname为Zabbix server前端页面中添加的主机名称,key为监控项item key,value为监控项的值。如果hostname指定为– 时,hostname将使用agent配置文件中的Hostname或—host参数。例如:

    - iostat.avgrq-sz[sda] 39.48  # 使用--host或agent配置文件中Hostname

    Server1 db.connections 60 # 主机server1,监控项的key为db.connections,值为60

    在Zabbix server前端页面中必须设置正确的item的值类型,Zabbix sender每次连接能够发送最多250个值。

    下面举个监控磁盘IO的例子。在本例中通过iostat(sysstat的版本为10.1.5)收集磁盘数据,在模板中定义自动发现规则和item、graph、trigger原型,当模板链接到主机后,自动创建item、graph和trigger。在模板中创建一个item,定期收集监控数据。

    1、  定义UserParameter

    # vi /etc/zabbix/zabbix_agentd.d/userparameter_io.conf

    UserParameter = iostat_status,/etc/zabbix/script/io_stat.sh

    UserParameter = iostat.discovery_disks,/etc/zabbix/script/io_stat.shdisks

    2、  编辑脚本文件

    # vi /etc/zabbix/script/io_stat.sh

    #!/bin/bash

     

    if [ -z $1 ]; then

    RespStr=$(/usr/bin/iostat -dkxy 2>/dev/null)

    (cat <<EOF

    $RespStr

    EOF

     ) |  awk 'BEGIN {split("disk rrqm_s wrqm_sr_s w_s rkB_s wkB_s avgrq-sz avgqu-sz await r_await w_await svct util",aParNames)}

       $1 ~ /^[hsv]d[a-z]$/ {print$0;

       if(NF == 14)

         for(i = 2; i <= 14;i++) print "- iostat."aParNames[i]"["$1"]", $i

     }' | /usr/bin/zabbix_sender--config /etc/zabbix/zabbix_agentd.conf --input-file - >/dev/null 2>&1

     echo 1

     exit 0

    elif [ "$1" = 'disks' ]; then

     DiskStr=`/usr/bin/iostat -d |awk '$1 ~ /^[hsv]d[a-z]$/ {print $1}'`

     es=''

     for disk in $DiskStr; do

      OutStr="$OutStr$es{\"{#DISKNAME}\":\"$disk\"}"

       es=","

     done

     echo -e"{\"data\":[$OutStr]}"

    fi

    3、  创建模板Template IO Trap。如下图14-3所示。

    图 14-3

    4、  在模板中添加一个名称为IO的application。

    5、  创建一个名称为Status的监控项,如下图14-4所示。

     

    图 14-4

    6、  创建一个触发器,如下图14-5所示。

    图 14-5

    7、  创建自动发现规则,定期调用脚本发现磁盘。在脚本中自动生成JOSN格式的数据,例如:

    {"data":

    [

    {"{#DISKNAME}":"sda"},

    {"{#DISKNAME}":"sdb"}

    ]

    }

    如下图14-6所示。

    图 14-6

     

    8、  创建item原型。在第5步中创建的监控项会定期调用脚本,脚本中根据iostat命令的返回结果自动生成的Zabbixsender需要的输入文件。创建item原型时使用输入文件中的key创建类型为Zabbix trapper的监控项。输入文件的内容格式如下:

    -iostat.rrqm_s[sda] 0.00

    -iostat.wrqm_s[sda] 0.02

    -iostat.r_s[sda] 0.12

    -iostat.w_s[sda] 5.17

    -iostat.rkB_s[sda] 4.30

    -iostat.wkB_s[sda] 99.98

    -iostat.avgrq-sz[sda] 39.48

    -iostat.avgqu-sz[sda] 0.01

    -iostat.await[sda] 1.21

    -iostat.r_await[sda] 2.18

    -iostat.w_await[sda] 1.19

    -iostat.svct[sda] 0.66

    -iostat.util[sda] 0.35

    使用输入文件中的key参数创建item原型,如下图14-7所示。

    图 14-7

    创建的item原型列表如下图14-8所示。

    图 14-8

    9、  创建graph原型,如下图14-9所示。

    图 14-9

    graph原型列表如下图14-10所示。

    图 14-10

    10、  将模板Template IOTrap链接到主机,然后到Latest data中查看监控数据,如下图14-11所示。

     

    图 14-11

    Zabbix sender的执行在例子中我们通过一个监控项的查询来调用脚本,实际上你也可以通过cron来运行脚本。通过定义监控项的方式管理比较方便,Update interval (in sec)等设置的改变都可以在前端页面中完成,不需要对监控主机做任何操作。

    最新回复(0)