Zabbix应用
     分类:监控     有: 0 条评论

Zabbix应用

     分类:监控     有: 0 条评论

功能配置

聚合图形

聚合图形可以在一格页面中显示多个图。

graphtree:
https://github.com/grafana/grafana
http://docs.grafana.org/installation


远程执行命令

Zabbix远程执行命令:
https://www.ywnds.com/?p=6610
https://www.linuxidc.com/Linux/2016-07/133421p7.htm


邮件报警

报警媒介启用邮件,设置好,这里注意端口,账户等信息,基本发不了邮件都是这里设置有问题。
mark
设置admin用户的报警媒介
mark
在配置--动作中配置Report problems to Zabbix administrators,也可以使用默认的

# 操作
Error: {TRIGGER.NAME}

hostname: ({HOST.NAME}
Time:{EVENT.DATE} {EVENT.TIME}
level:{TRIGGER.SEVERITY}
message:{TRIGGER.NAME}
event:{ITEM.NAME}:{ITEM.VALUE}

# 恢复操作
OK: {TRIGGER.NAME}

hostname: ({HOST.NAME}
Time:{EVENT.DATE} {EVENT.TIME}
level:{TRIGGER.SEVERITY}
message:{TRIGGER.NAME}
event:{ITEM.NAME}:{ITEM.VALUE}

其他默认,这样应该是可以收到邮件的了,如果是QQ邮箱,密码应该填授权码。

参考:https://www.abcdocker.com/abcdocker/1704


微信报警

打开企业微信注册:http://work.weixin.qq.com
mark
填写名称,扫码绑定管理者账号;填写姓名,身份证号登陆。
mark
刚注册完成是看不到CorpID的,工作日要1-3小时后才会显示出来(可能是需要审核);如果注册时选企业,注册完成是可以立刻看到的,但是可能后期需要认证等等,比较麻烦。能看到CorpID时记录备用。

在“通讯录”中添加成员,可能要扫码下载企业微信。记录“账号”,这是User参数,发送消息时要用到,自己设置,没有设置会自动生成,可以回来查看,记录备用。同时,最少要有1个人关注了该企业号,那怕自己也行,关注后能在手机微信里看到。
mark


“我的企业”--“权限管理”中设置管理员。
在“企业应用”中创建应用,设置名称和可见范围(范围可以是一个组的人,也可以是一个人);创建之后可以看到AgentId和Secret记录备用

登陆zabbix服务端,修改配置文件,修改权限,测试

# 确保以下路径是启用的(脚本路径)
[root@zabbix ~]# grep alertscripts /etc/zabbix/zabbix_server.conf 
AlertScriptsPath=/usr/lib/zabbix/alertscripts

# 下载发信息脚本(来源于网络)
cd /usr/lib/zabbix/alertscripts
wget https://image.leolan.top/wechat
chmod 755 wechat
chown zabbix:zabbix wechat

# 测试
# 脚本是编译过的,无法进行编辑,我们可以使用./wechat -h or --help 查看
./wechat --corpid=wwcxxxxxxxxxxxxxxxx --corpsecret=XXXXXXXiuRgr4DCLreQA --user=leolan --agentid=1000002  --msg="hello,这是一个测试"
{"errcode":0,"errmsg":"ok","invaliduser":""}

#要是报错:{"errcode":41001,"errmsg":"access_token missing,一般是企业应用有问题,删除重建就好了。

参数:
--corpid= 我们企业里面的id
--corpsecret= 这里就是我们Secret里面的id
-user=记录的账号
-msg= 消息内容

# 执行后手机端关注的企业号就能收到消息了,但是有时候不是很正常,会收不到。只要能收到说明设置是没问题了。

接着配置web界面,记得先点小的add或update,不然是不会保存配置的,老司机应该都懂的。
“管理”--“报警媒介类型”--“创建媒体类型”
mark

脚本参数:
--corpid=企业id
--corpsecret=Secret的id
--agentid= Agentld ID
--user={ALERT.SENDTO}
--msg={ALERT.MESSAGE}

“管理”--“用户”--“创建用户” ;可以直接设置为管理员,记得设置密码。
mark
报警媒介设置收信人(就是企业微信中你记录了账号的那个人,这里的收信人就填写“账号”,会作为user参数传递给wechat脚本)
mark


“配置”--“动作(Actions)”--“创建动作”
起一个名字,设置报警操作
mark

Error: {TRIGGER.NAME}

hostname: ({HOST.NAME}
Time:{EVENT.DATE} {EVENT.TIME}
level:{TRIGGER.SEVERITY}
message:{TRIGGER.NAME}
event:{ITEM.NAME}:{ITEM.VALUE}

url:www.leolan.top

设置恢复动作
mark

OK: {TRIGGER.NAME}

hostname: ({HOST.NAME}
Time:{EVENT.DATE} {EVENT.TIME}
level:{TRIGGER.SEVERITY}
message:{TRIGGER.NAME}
event:{ITEM.NAME}:{ITEM.VALUE}

url:www.leolan.top

OK,设置完成,一般来说应该是可以正常报警了,但是可能因为权限原因无法发送成功。
参考上一节邮件报警部分,这里直接在管理--用户--admin--报警媒介,在这里添加微信收件人,就可以收到了。

现在停掉某一台机的agent,稍等就会报警了,手机微信应该也能收到消息了。

微信多用户报警
关于设置多个微信收信人,发现设置--user={ALERT.SENDTO}并不能发送给多个收件人,只有排在列表的第一个用户才能收到;但是单独--user=leolan填写某个用户是可以收到信息的;可能是受配置--》动作--》Report problems to Zabbix administrators--》操作中的默认操作步骤持续时间的影响,在时间没过时还是执行第一个用户的操作,时间到了微信的token又失效了。可以设置为60秒试试,记得微信请求token的超时时间是120秒。
用户不多,最简单的解决办法是直接管理--报警媒介设置多一个微信报警,配置和第一个一样,改一下user,和名称,在管理--用户--报警媒介中添加对应的用户就OK了。

参考:
https://www.abcdocker.com/abcdocker/2573
微信报警机器人:https://github.com/X-Mars/Zabbix-Alert-WeChat


钉钉报警

https://github.com/typ431127/zabbix_dingding


Web界面中文乱码问题乱码

yum install -y bash-completion

# zabbix的安装目录下有个fonts文件夹,进去看看,里面应该只有一个字体文件,叫graphfont.ttf
/data/wwwroot/default/zabbix/fonts

# 在win上C:\Windows\Fonts\下找一个你要的中文字体(比如:楷体常规),复制出来后名字是simkai.ttf,上传到zabbix的字体目录。
# 或者从/usr/share/fonts中挑选一个字体,复制到zabbix字体目录。

find / -type f -name "defines.inc.php"  #改文件位于zabbix的安装目录下的include文件夹里面
/data/wwwroot/default/zabbix/include/defines.inc.php
# 修改该文件,搜索graphfont(如果是低于3.2的版本,名字可能是DejaVuSans;)或者搜索:ZBX_GRAPH_FONT_NAME(必须大写),改为你的字体,比如simkai(没有后缀名的)

mark

修改好后在web界面中切换为英文,再切换为中文,就不会乱码了。

如果还是乱码,登陆数据库,查看zabbix的数据库字符集,

MariaDB [(none)]> show create database zabbix;
+----------+----------------------------------------------------------------------------------+
| Database | Create Database                                                                  |
+----------+----------------------------------------------------------------------------------+
| zabbix   | CREATE DATABASE `zabbix` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */ |
+----------+----------------------------------------------------------------------------------+
1 row in set (0.00 sec)

如果不是utf-8的,那要修复这个问题就要备份数据库,重建数据库了。参考:http://www.linuxidc.com/Linux/2015-05/117208.htm
重建数据库后别忘了在my.cnf增加如下配置default-character-set = utf8,重启数据库,完成。


清除历史数据

# 统计数据库中每个表所占的空间:
mysql> SELECT table_name AS "Tables",
       round(((data_length + index_length) / 1024 / 1024), 2) "Size in MB"
      FROM information_schema.TABLES
      WHERE table_schema = 'zabbix'   /* 改为自己的库名 */
      ORDER BY (data_length + index_length) DESC;


# 清理历史数据
#!/bin/bash
# 注意修改用户、密码、库名
User="zabbix"
Passwd="123456"
Date=`date -d $(date -d "-15 day" +%Y%m%d) +%s` #取15天之前的时间戳
$(which mysql) -u${User} -p${Passwd} -e "
use zabbix;
DELETE FROM history WHERE 'clock' < $Date;
optimize table history;
DELETE FROM history_str WHERE 'clock' < $Date;
optimize table history_str;
DELETE FROM history_uint WHERE 'clock' < $Date;
optimize table history_uint;
DELETE FROM history_text WHERE 'clock' < $Date;
optimize table history_text;
DELETE FROM  trends WHERE 'clock' < $Date;
optimize table  trends;
DELETE FROM trends_uint WHERE 'clock' < $Date;
optimize table trends_uint;
DELETE FROM events WHERE 'clock' < $Date;
optimize table events;
"


# 另:可以使用truncate命令直接清空数据库:
truncate table history;
truncate table history_uint;
truncate table history_str;
truncate table history_text;
truncate table trends;
truncate table trends_uint;
truncate table events;

如果想要删除表的所有数据,truncate语句要比 delete 语句快。
因为 truncate 删除了表,然后根据表结构重新建立它,而 delete 删除的是记录,并没有尝试去修改表。
不过truncate命令虽然快,却不像delete命令那样对事务处理是安全的。
因此,如果我们想要执行truncate删除的表正在进行事务处理,这个命令就会产生退出并产生错误信息。

参考:https://www.cnblogs.com/configure/p/6424233.html



服务监控

监控Mysql

虽然zabbix也自带有MySQL监控,但是并不能满足需求。percona官网有更好的MySQL监控模板,同时也支持Nagios和catcti。

Percona组成部分
1、PHP脚本:用来数据采集
2、shell脚本:用来调用采集信息
3、zabbix配置文件
4、zabbix模板文件

配置模板

安装源:https://www.percona.com/downloads/percona-monitoring-plugins/LATEST/
在被监控的服务器上安装脚本

wget https://www.percona.com/downloads/percona-monitoring-plugins/percona-monitoring-plugins-1.1.7/binary/redhat/7/x86_64/percona-zabbix-templates-1.1.7-2.noarch.rpm
rpm -ivh percona-zabbix-templates-1.1.7-2.noarch.rpm

rpm -ql percona-zabbix-templates                           #查看安装的文件所在目录

# 以下两步,不是非必须,不要执行。
yum update               #这里注意不能升级zabbix,可能会导致zabbix无法使用
yum install -y php php-mysql   #这一步一般不用执行,安装zabbix时有安装php-mysql
# 如果被监控机子上没有安装php则要执行这一句,同时还会自动安装httpd。再执行:
systemctl disable httpd

创建mysql只读用户

use mysql;
GRANT Select ON *.* TO 'zabbix_read'@'192.168.10.%'  IDENTIFIED BY "123456";
GRANT Select ON *.* TO 'zabbix_read'@'localhost'  IDENTIFIED BY "123456";
flush privileges;

将配置文件拷贝到/etc/zabbix/zabbix_agentd.d/目录

cp /var/lib/zabbix/percona/templates/userparameter_percona_mysql.conf /etc/zabbix/zabbix_agentd.d/
vim /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php

# 按你的环境修改以下内容,注意字符串要''括起来。
$mysql_user = 'root';

$mysql_pass = '123456';

$mysql_port = 3306;

$mysql_socket = '/tmp/mysql.sock';    #socket看/etc/my.cnf配置文件

$mysql_flags = 0;

########################################
# 修改为保存退出
chown -R zabbix:zabbix /tmp/localhost-mysql_cacti_stats.txt
systemctl restart zabbix-agent
cd /var/lib/zabbix/percona/scripts/

[root@zabbix scripts]# ./get_mysql_stats_wrapper.sh gm
0
[root@zabbix scripts]# ./get_mysql_stats_wrapper.sh gw
6558145

# 有输出,证明正常工作了。

在zabbix服务端导入模板

sz /var/lib/zabbix/percona/templates/zabbix_agent_template_percona_mysql_server_ht_2.0.9-sver1.1.7.xml
# 把下载回来的xml文件在zabbix 配置--模板 中导入模板
已转换好的模板:https://image.leolan.top/blog/170820/92kbed6fad.xml

重要:修改文件属性

位于/tmp/localhost-mysql_cacti_stats.txt此文件是临时收集信息然后发送给服务端的,默认用root安装,归属就是root,要改为zabbix用户,不改会出现以下问题

Received value [rm: 无法删除"/tmp/localhost-mysql_cacti_stats.txt": 不允许的操作0] is not suitable for value type [Numeric (float)]

./get_mysql_stats_wrapper.sh gm 和 ./get_mysql_stats_wrapper.sh gw没有返回值

服务端Web页面接收不到数据,显示没有数据

解决:

cd /tmp
chown -R zabbix:zabbix localhost-mysql_cacti_stats.txt 
systemctl restart zabbix-agent

参考:http://blog.csdn.net/xiegh2014/article/details/72859982


libmysqlclient.so.18: cannot open shared objecdirectory in Unknown on line 0

# 报错如下:
[root@linux376 scripts]# ./get_mysql_stats_wrapper.sh gm
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/mysql.so' - libmysqlclient.so.18: cannot open shared objecdirectory in Unknown on line 0

解决:
这时因为安装mysql时不是yum方式安装的,库文件不是在默认的目录里。

find / -name libmysqlclient.so.18   #假如找到的目录是/usr/local/mysql/lib/libmysqlclient.so.18(mysql的安装目录下的此文件)
cp /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib64/
cp /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib64/mysql/    #mysql目录可能没有,在此新建
systemctl restart zabbix-agent          #再次测试就不会报错了。

参考:
http://blog.csdn.net/xiegh2014/article/details/72859982
https://www.linuxidc.com/Linux/2015-04/116304.htm
https://www.linuxidc.com/Linux/2013-05/84800.htm


监控TCP连接数

TCP的11种状态:
mark

TCP连接可以使用命令获取

netstat -an|awk '/^tcp/{++S[$NF]}END{for(a in S) print a,S[a]}' 
TIME_WAIT 22
CLOSE_WAIT 10
FIN_WAIT1 1
FIN_WAIT2 3
ESTABLISHED 193
LAST_ACK 1
LISTEN 22

LISTEN:侦听来自远方TCP端口的连接请求;
SYN-SENT:在发送连接请求后等待匹配的连接请求;
SYN-RECEIVED:在收到和发送一个连接请求后等待对连接请求的确认;
ESTABLISHED:代表一个打开的连接,数据可以传送给用户;
FIN-WAIT-1 :等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
FIN-WAIT-2 :从远程TCP等待连接中断请求;
CLOSE-WAIT :等待从本地用户发来的连接中断请求;
CLOSING :等待远程TCP对连接中断的确认;
LAST-ACK :等待原来发向远程TCP的连接中断请求的确认;
TIME-WAIT :等待足够的时间以确保远程TCP接收到连接中断请求的确认;
CLOSED :没有任何连接状态;

# 确定包含配置文件
[root@zabbix ~]# grep "Include" /etc/zabbix/zabbix_agentd.conf
Include=/etc/zabbix/zabbix_agentd.d/*.conf    #确定包含此文件夹,要在此文件夹下建立配置文件。

# 配置文件
vim /etc/zabbix/zabbix_agentd.d/tcp_status.conf
UserParameter=tcp.status[*],/etc/zabbix/zabbix_agentd.d/tcp_status.sh "$1"

# 采集脚本
vim /etc/zabbix/zabbix_agentd.d/tcp_status.sh

#!/bin/bash
#this script is used to get tcp and udp connetion status
#tcp status
metric=$1
tmp_file=/tmp/tcp_status.txt
/bin/netstat -an|awk '/^tcp/{++S[$NF]}END{for(a in S) print a,S[a]}' > $tmp_file
case $metric in
   closed)
          output=$(awk '/CLOSED/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
        ;;
   listen)
          output=$(awk '/LISTEN/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
        ;;
   synrecv)
          output=$(awk '/SYN_RECV/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
        ;;
   synsent)
          output=$(awk '/SYN_SENT/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
        ;;
   established)
          output=$(awk '/ESTABLISHED/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
        ;;
   timewait)
          output=$(awk '/TIME_WAIT/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
        ;;
   closing)
          output=$(awk '/CLOSING/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
        ;;
   closewait)
          output=$(awk '/CLOSE_WAIT/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
        ;;
   lastack)
          output=$(awk '/LAST_ACK/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
         ;;
   finwait1)
          output=$(awk '/FIN_WAIT1/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
         ;;
   finwait2)
          output=$(awk '/FIN_WAIT2/{print $2}' $tmp_file)
          if [ "$output" == "" ];then
             echo 0
          else
             echo $output
          fi
         ;;
         *)
          echo -e "\e[033mUsage: sh  $0 [closed|closing|closewait|synrecv|synsent|finwait1|finwait2|listen|established|lastack|timewait]\e[0m"
esac

设置脚本权限,属组

chmod +x /etc/zabbix/zabbix_agentd.d/tcp_status.sh
touch /tmp/tcp_status.txt
chown zabbix:zabbix /tmp/tcp_status.txt
systemctl restart zabbix-agent
# 如果长时间接收不到数据,就需要重启一下zabbix服务,登录zabbix服务端,systemctl restart zabbix-server

导入模板:https://image.leolan.top/blog/170820/Fk6eli8Ld8.xml
设置主机,出图,如果需要设置报警,TCP连接因业务不同有很大的区别,更具自己的业务去修改。
关于最大连接数,参考:http://www.cnblogs.com/fjping0606/p/4729389.html

参考:https://www.abcdocker.com/abcdocker/2652


监控Web网站

mark
新建场景,起个名称;添加步骤,输入名称,填入网址,状态码。
mark
切换到该主机的触发器页面新建触发器。
mark
监控项选对
mark
mark
插入后返回界面,添加就创建好了,过一会儿就能看到图表了。

参考:https://blog.csdn.net/slovyz/article/details/53101566


监控API接口

参考资料中的是监控一种类型的接口,地址全部放到文本里,去文本取地址,做历遍,改成自动发现;然后用对应的方法取值,返回给你zabbix服务端。
这里简单修改一下;在zabbix服务端的agent新建监控脚本就行,任何一个agent都是可以的。

接口提前测试,确定返回值等信息

curl --connect-timeout 30 -m 30 -d "sCorpCode=XXX&sLocationCode=XXXX&fromcity=hkg&sCorpPassword=XXXX&dReportDateStart=2018-04-27&dReportDateEnd=2018-04-30" "接口地址" -k

脚本部分

cd /etc/zabbix/zabbix_agentd.d

vim api_status.sh

#!/bin/bash 
# function:monitor tcp connect status from zabbix

# set option
# 这里有3套post接口,sources的值来区分接口;soap独立为一套。
adult=1
child=1
fromcity=HKG
# 未来第10天的时间
fromtime=`date -d "$(date +%Y%m%d) +10 day" +%Y-%m-%d`
# 获取soap.xml中的旧时间,下面用sed替换掉。
oldtime=`cat /etc/zabbix/zabbix_agentd.d/soap.xml |grep "fromDate"|grep -Eo '[0-9]+'`
maxrecord=10
tocity=TPE
triptype=1
platformsource=XXXXXXXXXXXX[这里填组织名,有授权的才行]
# api_url_a.txt uapi接口
sources1=uapi
# api_url_b.txt amadeus接口
sources2=amadeus
# api_url_c.txt sabre接口
sources3=sabre

##########################################

source /etc/bashrc >/dev/null 2>&1
source /etc/profile  >/dev/null 2>&1

# eval先扫描变量全部替换后再执行sed;这里的SOAP接口只要修改报文文件里的时间就可以了。
eval sed -i 's/$oldtime/$fromtime/' /etc/zabbix/zabbix_agentd.d/soap.xml

###############################################################
# uapi接口自动发现,注意赋值关键字的命名a、b、c、d、i、j、k、m
api_auto_discovery_a () {
APIa=($(cat /etc/zabbix/zabbix_agentd.d/api_url_a.txt|grep -v "^#"))
        printf '{\n'
        printf '\t"data":[\n'
for((i=0;i<${#APIa[@]};++i))
{
numa=$(echo $((${#APIa[@]}-1)))
        if [ "$i" != ${numa} ];
                then
        printf "\t\t{ \n"
        printf "\t\t\t\"{#APINAME}\":\"${APIa[$i]}\"},\n"
                else
                        printf  "\t\t{ \n"
                        printf  "\t\t\t\"{#APINAME}\":\"${APIa[$numa]}\"}]}\n"
        fi
                }
}
##############################################################
# amadeus接口自动发现,注意赋值关键字的命名a、b、c、d、i、j、k、m
api_auto_discovery_b () {
APIb=($(cat /etc/zabbix/zabbix_agentd.d/api_url_b.txt|grep -v "^#"))
        printf '{\n'
        printf '\t"data":[\n'
for((j=0;j<${#APIb[@]};++j))
{
numb=$(echo $((${#APIb[@]}-1)))
        if [ "$j" != ${numb} ];
                then
        printf "\t\t{ \n"
        printf "\t\t\t\"{#APINAME}\":\"${APIb[$j]}\"},\n"
                else
                        printf  "\t\t{ \n"
                        printf  "\t\t\t\"{#APINAME}\":\"${APIb[$numb]}\"}]}\n"
        fi
                }
}

############################################################
# sabre接口自动发现,注意赋值关键字的命名a、b、c、d、i、j、k、m
api_auto_discovery_c () {
APIc=($(cat /etc/zabbix/zabbix_agentd.d/api_url_c.txt|grep -v "^#"))
        printf '{\n'
        printf '\t"data":[\n'
for((k=0;k<${#APIc[@]};++k))
{
numc=$(echo $((${#APIc[@]}-1)))
        if [ "$k" != ${numc} ];
                then
        printf "\t\t{ \n"
        printf "\t\t\t\"{#APINAME}\":\"${APIc[$k]}\"},\n"
                else
                        printf  "\t\t{ \n"
                        printf  "\t\t\t\"{#APINAME}\":\"${APIc[$numc]}\"}]}\n"
        fi
                }
}

###############################################################
# SOAP 接口指定发现,注意赋值关键字的命名a、b、c、d、i、j、k、m
soap_api_auto_discovery () {
SOAPAPI=($(cat /etc/zabbix/zabbix_agentd.d/soap_api_url.txt|grep -v "^#"))
        printf '{\n'
        printf '\t"data":[\n'
for((m=0;m<${#SOAPAPI[@]};++m))
{
numd=$(echo $((${#SOAPAPI[@]}-1)))
        if [ "$m" != ${numd} ];
                then
        printf "\t\t{ \n"
        printf "\t\t\t\"{#APINAME}\":\"${SOAPAPI[$m]}\"},\n"
                else
                        printf  "\t\t{ \n"
                        printf  "\t\t\t\"{#APINAME}\":\"${SOAPAPI[$numd]}\"}]}\n"
        fi
                }
}

###############################################################
# uapi接口的取值方法,post参数过去,返回结果中过滤一下得到code的值,交由zabbix web去对比。
api_code_a () {
/usr/bin/curl -s --connect-timeout 30 -m 30 -d "adult=$adult&child=$child&fromcity=$fromcity&fromdate=$fromtime&maxrecord=$maxrecord&tocity=$tocity&triptype=$triptype&platformsource=$platformsource&source=$sources1" "$1" | gunzip |awk -vRS='code' 'END{print}'|cut -d "," -f1 |cut -c3-5
}

# amadeus接口的取值方法,post参数过去,返回结果中过滤一下得到code的值,交由zabbix web去对比。
api_code_b () {
/usr/bin/curl -s --connect-timeout 30 -m 30 -d "adult=$adult&child=$child&fromcity=$fromcity&fromdate=$fromtime&maxrecord=$maxrecord&tocity=$tocity&triptype=$triptype&platformsource=$platformsource&source=$sources2" "$1" | gunzip |awk -vRS='code' 'END{print}'|cut -d "," -f1 |cut -c3-5
}

# sabre接口的取值方法,post参数过去,返回结果中过滤一下得到code的值,交由zabbix web去对比。
api_code_c () {
/usr/bin/curl -s --connect-timeout 30 -m 30 -d "adult=$adult&child=$child&fromcity=$fromcity&fromdate=$fromtime&maxrecord=$maxrecord&tocity=$tocity&triptype=$triptype&platformsource=$platformsource&source=$sources3" "$1" | gunzip |awk -vRS='code' 'END{print}'|cut -d "," -f1 |cut -c3-5
}

# SOAP soap请求通过发送xml报文文件到接口服务器就能获得返回数据,判断返回数据有无指定的字段就可判定接口是否正常。
soap_api_met () {
/usr/bin/curl -s --connect-timeout 30 -m 30 -H 'Content-Type: text/xml;charset=UTF-8;SOAPAction:""' -d @/etc/zabbix/zabbix_agentd.d/soap.xml "$1" |grep "sessionId" >/dev/null

if [ $? -eq 0 ]; then
    echo "100"
else
    echo "0"
fi
}

###############################################################
# 执行脚本格式./api_status.sh[$0本身是参数0] [$1参数1] [$2参数2]
# 多选择语句,执行脚本时的$1(参数1),对应自动发现那种类型的接口;$2(参数2)对应那种取值方法。
case "$1" in
api_auto_discovery_a)
        api_auto_discovery_a
;;
api_auto_discovery_b)
        api_auto_discovery_b
;;
api_auto_discovery_c)
        api_auto_discovery_c
;;
soap_api_auto_discovery)
        soap_api_auto_discovery
;;
api_code_a)
        api_code_a $2
;;
api_code_b)
        api_code_b $2
;;
api_code_c)
        api_code_c $2
;;
soap_api_met)
        soap_api_met $2
;;
*)

echo "Usage:$0 {api_auto_discovery|api_code [URL]}"
echo "Usage:$0 {soap_api_auto_discovery|soap_api_met [URL]}"
;;
esac
# 脚本完

# api地址部分
echo "# uapi地址,#开头是注释!" > api_url_a.txt
echo "# amadeus地址,#开头是注释!" > api_url_b.txt
echo "# sabre地址,#开头是注释!" > api_url_c.txt
echo "# SOAP地址,#开头是注释!" > soap_api_url.txt

另外把SOAP请求的报文文件放到/etc/zabbix/zabbix_agentd.d目录下,名称为:soap.xml
是正常情况下的xml文件,无关的东西可以精简掉。


# 监控配置
/etc/zabbix/zabbix_agentd.conf中的UnsafeUserParameters=1值要为1;
Include=/etc/zabbix/zabbix_agentd.d/*.conf 包含改目录下的配置文件

vim userparameter_api_check.conf
# POST API
UserParameter=api.auto.discovery.a,/etc/zabbix/zabbix_agentd.d/api_status.sh api_auto_discovery_a
UserParameter=api.code.a[*],/etc/zabbix/zabbix_agentd.d/api_status.sh api_code_a $1

UserParameter=api.auto.discovery.b,/etc/zabbix/zabbix_agentd.d/api_status.sh api_auto_discovery_b
UserParameter=api.code.b[*],/etc/zabbix/zabbix_agentd.d/api_status.sh api_code_b $1

UserParameter=api.auto.discovery.c,/etc/zabbix/zabbix_agentd.d/api_status.sh api_auto_discovery_c
UserParameter=api.code.c[*],/etc/zabbix/zabbix_agentd.d/api_status.sh api_code_c $1

# SOAP API
UserParameter=soap.api.auto.discovery,/etc/zabbix/zabbix_agentd.d/soap_api_status.sh soap_api_auto_discovery
UserParameter=soap.api.met[*],/etc/zabbix/zabbix_agentd.d/soap_api_status.sh soap_api_met $1

# 赋予权限,重启zabbix-agent
chmod a+x api_status.sh
chown -R zabbix:zabbix /etc/zabbix/zabbix_agentd.d
systemctl restart zabbix-agent

# 简单测试,在zabbix服务端执行,注意替换IP,对应类型的api地址
zabbix_get -s 127.0.0.1 -k api.code.a[http://XXXXXXXX]
zabbix_get -s 127.0.0.1 -k api.code.b[http://XXXXXXXX]
zabbix_get -s 127.0.0.1 -k api.code.c[http://XXXXXXXX]
zabbix_get -s 127.0.0.1 -k soap.api.met[http://XXXXXXXX]

接着配置zabbix web自动发现、监控项和报警项。
我是在zabbix服务端的agent上做的监控,所以找到zabbix server所在主机;配置--》主机--》zabbix server--》自动发现规则

1.创建自动发现规则

键值:填userparameter_api_check.conf中设置的值。
mark
mark
mark

2.然后再点右侧的监控原型,新建监控原型

mark
名称:引用$1(接口地址),报警时会显示:api.code.a ON [http://XXXXXX] ;这样我们就知道是普通post接口的uapi接口的http://XXXXXX有问题
键值为(方法的值):api.code.a[{#APINAME}]

3.新建触发器

名称后面可以加上{#APINAME}这样报警时就能看到接口的地址了。
插入两次,第一次设置计数2,排班15;第二次只设置N值;这样做可以降低误报的概率。
mark
mark
然后再表达式中两个条件之间手动加上and;同时勾选允许手动关闭

4.新建图形

mark

过一段时间就可以看到监控项中已发现了接口。

参考:
https://www.cnblogs.com/smail-bao/p/6043726.html
http://blog.51cto.com/itnihao/1129725


监控群晖NAS

在设置中开启SNMP,简单设置一下
mark
然后telnet一下161端口通不通。不通的话检查一下防火墙。在zabbix中添加主机
mark
改用SNMP方式连接,模板选:Template SNMP OS Linux
mark
其他不用设置,过一会儿就连接上了,感觉用zabbix监控NAS比较鸡肋,没什么功能,群晖自带的监控好很多,就是要单独登陆比较麻烦。


监控IIS

自动发现脚本:IIS_Web_Service
LLD低级自动发现模板下载:Template IIS Web Site3.0
把脚本放到zabbix-agent的conf目录下,修改配置文件,在最底下增加一行(bat的位置改为你自己的)

UserParameter=iis.site.discovery,C:\auto_bat\zabbix_agents_3.2.0.win\conf\IIS_Web_Service.bat

然后重启zabbix-agent;在服务端zabbix_get -s 172.16.16.87 -k iis.site.discovery就能看到返回的json格式的数据了。
在web中导入Template IIS Web Site3.0模板,链接主机。

{#WEB_SERVICE} Bytes Received/sec:IIS站点接收数据字节的速率
{#WEB_SERVICE} Bytes Sent/sec:IIS站点发送数据字节的速率
{#WEB_SERVICE} Bytes Total/sec:IIS站点的总传输数据字节的速率,是Received/sec和Sent/sec的和。
{#WEB_SERVICE} Get Requests/sec:IIS站点的GET请求速率
{#WEB_SERVICE} Post Requests/sec:IIS站点的POST请求速率
以上5个监控项是取的平均值,使监控数据更加准确、平滑。

{#WEB_SERVICE} Current Connections:当前与IIS站点建立连接的数量
{#WEB_SERVICE} Service Uptime:IIS站点的启动时间
以上2个监控项是取的当前瞬时值。

参考:
http://blog.csdn.net/wangdaoge/article/details/53837067
http://qicheng0211.blog.51cto.com/3958621/1857398
http://9036423.blog.51cto.com/9026423/1693007
http://www.iyunv.com/thread-126099-1-1.html
http://magic3.blog.51cto.com/1146917/1375815
https://www.iyunv.com/thread-126099-1-1.html
其他方法:
http://www.cnblogs.com/zhenglisai/p/6673352.html
http://www.jianshu.com/p/f6e52f69658e


监控Linux Disk IO磁盘IO

yum install -y gcc automake
python -V && pip -V
if [ $? != 0 ]; than
  yum install python
  wget --no-check-certificate https://github.com/pypa/pip/archive/9.0.1.tar.gz
  tar zvxf 9.0.1.tar.gz
  cd pip-9.0.1/
  python setup.py install
  pip install simplejson && pip install jsonlib
fi

####################################################
vim /etc/zabbix/zabbix_agentd.d/disk_discovery.py

#/usr/bin/python
import subprocess
import json
args="cat /proc/diskstats |grep -E '\ssd[a-z]\s|\sxvd[a-z]\s|\svd[a-z]\s'|awk '{print $3}'|sort|uniq 2>/dev/null"
t=subprocess.Popen(args,shell=True,stdout=subprocess.PIPE).communicate()[0]
 
disks=[]
 
for disk in t.split('\n'):
    if len(disk) != 0:
       disks.append({'{#DISK_NAME}':disk})
print json.dumps({'data':disks},indent=4,separators=(',',':'))

####################################################
vim /etc/zabbix/zabbix_agentd.d/disk_status.sh

#/bin/sh
device=$1
DISK=$2

case $DISK in
         read.ops)
            /bin/cat /proc/diskstats | grep "\b$device\b" | head -1 | awk '{print $4}'    #//磁盘读的次数
            ;;
         read.ms)
            /bin/cat /proc/diskstats | grep "\b$device\b" | head -1 | awk '{print $7}'    #//磁盘读的毫秒数
            ;;
         write.ops)
            /bin/cat /proc/diskstats | grep "\b$device\b" | head -1 | awk '{print $8}'     #//磁盘写的次数
            ;;
         write.ms)
            /bin/cat /proc/diskstats | grep "\b$device\b" | head -1 | awk '{print $11}'    #//磁盘写的毫秒数
            ;;
         io.active)
            /bin/cat /proc/diskstats | grep "\b$device\b" | head -1 | awk '{print $12}'    #//I/O的当前进度,
            ;;
         read.sectors)
            /bin/cat /proc/diskstats | grep "\b$device\b" | head -1 | awk '{print $6}'      #//读扇区的次数(一个扇区的等于512B)
            ;;
         write.sectors)
            /bin/cat /proc/diskstats | grep "\b$device\b" | head -1 | awk '{print $10}'     #//写扇区的次数(一个扇区的等于512B)
            ;;
         io.ms)
            /bin/cat /proc/diskstats | grep "\b$device\b" | head -1 | awk '{print $13}'      #//花费在IO操作上的毫秒数
            ;;
    
esac

# 增加执行权限
chmod +x /etc/zabbix/zabbix_agentd.d/disk_status.sh
chmod +x /etc/zabbix/zabbix_agentd.d/disk_discovery.py
####################################################

vim /etc/zabbix/zabbix_agentd.conf

UserParameter=disk.discovery,/usr/bin/python /etc/zabbix/zabbix_agentd.d/disk_discovery.py
UserParameter=disk.status[*],/etc/zabbix/zabbix_agentd.d/disk_status.sh $1 $2

# 重启zabbix-agent
systemctl restart zabbix-agent

# 登录zabbix服务器,sda通过cat /proc/diskstats查看到。
zabbix_get -s 172.16.16.85 -k "disk.status[sda,read.ops]"

在web新建模板,然后在模板上添加监控项目,或下载模板:[Linux_Disk IO模板]()

名称: {#DISK_NAME}磁盘读的次数
键值: disk.status[{#DISK_NAME},read.ops]
单位: ops/second
储存值:差量(每秒速率)

名称: {#DISK_NAME}磁盘写的次数
键值: disk.status[{#DISK_NAME},write.ops]
单位: ops/second
储存值:差量(每秒速率)

名称: {#DISK_NAME}磁盘读的毫秒数
键值: disk.status[{#DISK_NAME},read.ms]
单位: ms
储存值:差量(每秒速率)

名称: {#DISK_NAME}磁盘写的毫秒数
键值: disk.status[{#DISK_NAME},write.ms]
单位: ms
储存值:差量(每秒速率)

名称: {#DISK_NAME}读扇区的次数
键值:  disk.status[{#DISK_NAME},read.sectors]
单位:  B/sec
使用自定义倍数: 512
储存值:差量(每秒速率)

名称: {#DISK_NAME}写扇区的次数
键值:  disk.status[{#DISK_NAME},write.sectors]
单位:  B/sec
使用自定义倍数: 512
储存值:差量(每秒速率)

参考:
http://blog.csdn.net/xiegh2014/article/details/68923760
http://blog.51cto.com/qicheng0211/1599776


监控Redis

这里用了网友的采集脚本

vim /etc/zabbix/zabbix_agentd.d/redis-status.sh

#!/bin/bash
############################################################
# $Name:         redis_status.sh
# $Version:      v1.0
# $Function:     Redis Status
# $Author:       xuliangwei
# $organization: www.xuliangwei.com
# $Create Date:  2016-06-23
# $Description:  Monitor Redis Service Status
############################################################
R_COMMAND="$1"
R_PORT="6379"         #根据实际情况调整端口
R_SERVER="127.0.0.1"  #根据具体情况调整IP地址
PASSWD="123456"       #如果没有设置Redis密码,为空即可
redis_status(){
   (echo -en "AUTH $PASSWD\r\nINFO\r\n";sleep 1;) | /usr/bin/nc "$R_SERVER" "$R_PORT" > /tmp/redis_"$R_PORT".tmp
      REDIS_STAT_VALUE=$(grep "$R_COMMAND:" /tmp/redis_"$R_PORT".tmp | cut -d ':' -f2)
       echo "$REDIS_STAT_VALUE"
}
case $R_COMMAND in
    used_cpu_user_children)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    used_cpu_sys)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    total_commands_processed)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    role)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    lru_clock)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    latest_fork_usec)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    keyspace_misses)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    keyspace_hits)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    keys)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    expires)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    expired_keys)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    evicted_keys)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    connected_clients)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    changes_since_last_save)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    blocked_clients)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    bgsave_in_progress)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    bgrewriteaof_in_progress)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    used_memory_peak)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    used_memory)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    used_cpu_user)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    used_cpu_sys_children)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    total_connections_received)
    redis_status "$R_PORT" "$R_COMMAND"
    ;;
    *)
    echo $"USAGE:$0 {used_cpu_user_children|used_cpu_sys|total_commands_processed|role|lru_clock|latest_fork_usec|keyspace_misses|keyspace_hits|keys|expires|expired_keys|connected_clients|changes_since_last_save|blocked_clients|bgrewriteaof_in_progress|used_memory_peak|used_memory|used_cpu_user|used_cpu_sys_children|total_connections_received}"
    esac


# 增加执行权限
chmod +x /etc/zabbix/zabbix_agentd.d/redis-status.sh

# 修改配置文件
vim /etc/zabbix/zabbix_agentd.conf

#Redis
UserParameter=redis_status[*],/bin/bash /etc/zabbix/zabbix_agentd.d/redis-status.sh $1
# 如果报错:ZBX_NOTSUPPORTED: Timeout while executing a shell script.就修改Timeout=30 (因为此脚本执行时间比较长,默认是4s)

# 重启zabbix-agent
systemctl restart zabbix-agent

# 登录zabbix服务器
# 如果报错:ZBX_NOTSUPPORTED: Timeout while executing a shell script.就修改Timeout=30 (因为此脚本执行时间比较长,默认是4s)修改后记得重启服务

zabbix_get -s 172.16.16.75 -k redis_status[used_cpu_sys]

下载模板导入zabbix:Redis_status
ok,完成。

Redis状态参数解释:

server : Redis 服务器信息,包含以下域:
redis_version : Redis 服务器版本
redis_git_sha1 : Git SHA1
redis_git_dirty : Git dirty flag
os : Redis 服务器的宿主操作系统
arch_bits : 架构(32 或 64 位)
multiplexing_api : Redis 所使用的事件处理机制
gcc_version : 编译 Redis 时所使用的 GCC 版本
process_id : 服务器进程的 PID
run_id : Redis 服务器的随机标识符(用于 Sentinel 和集群)
tcp_port : TCP/IP 监听端口
uptime_in_seconds : 自 Redis 服务器启动以来,经过的秒数
uptime_in_days : 自 Redis 服务器启动以来,经过的天数
lru_clock : 以分钟为单位进行自增的时钟,用于 LRU 管理
clients : 已连接客户端信息,包含以下域:
connected_clients : 已连接客户端的数量(不包括通过从属服务器连接的客户端)
client_longest_output_list : 当前连接的客户端当中,最长的输出列表
client_longest_input_buf : 当前连接的客户端当中,最大输入缓存
blocked_clients : 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
memory : 内存信息,包含以下域:
used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量
used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
used_memory_peak : Redis 的内存消耗峰值(以字节为单位)
used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值
used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位)
mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率
persistence : RDB 和 AOF 的相关信息
stats : 一般统计信息
replication : 主/从复制信息
cpu : CPU 计算量统计信息
commandstats : Redis 命令统计信息
cluster : Redis 集群信息
keyspace : 数据库相关的统计信息

参数还可以是下面这两个:
all : 返回所有信息
default : 返回默认选择的信息
当不带参数直接调用 INFO 命令时,使用 default 作为默认参数。

参考:http://www.xuliangwei.com/xubusi/682.html
另一种方案(我测试时有点小问题,没弄成功):https://github.com/pengyao/zabbix/tree/master/redis
Redis自动发现:
http://www.21yunwei.com/archives/4195
https://www.linuxidc.com/Linux/2015-07/120138.htm


监控Nginx

配置nginx;先nginx -V看看要有--with-http_stub_status_module模块才行。
修改Nginx配置文件,在server区增加以下一段(或者修改原有的这一段,把nginx_status改为stub_status)。

location /stub_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }

如果安装了cms,blog,负载均衡等,请求会被转发,无法检测,可以另开一个端口,比如:88。

server {
    listen       88;
    server_name  localhost;

    location /stub_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

reload或重启nginx,检测结果。

[root@VM_82_110_centos ~]# curl -s http://127.0.0.1:80/stub_status
Active connections: 1 
server accepts handled requests
 471 471 894 
Reading: 0 Writing: 1 Waiting: 0 

注:
active connections:活跃的连接数量
server accepts handled requests:总共处理了471个连接 , 成功创建471次握手, 总共处理了894个请求
reading:读取客户端的连接数.
writing:响应数据到客户端的数量
waiting:开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接.

创建数据收集脚本,注意修改检测端口

vim /etc/zabbix/zabbix_agentd.d/nginx-status.sh

#!/bin/bash
##################################################
# AUTHOR: Neo <netkiller@msn.com>
# WEBSITE: http://www.netkiller.cn
# Description:zabbix 通过 status 模块监控 nginx
# Note:Zabbix 3.2
# DateTime: 2016-11-22
##################################################

HOST="localhost"
PORT="80"
stub_status=stub_status

function check() {
    if [ -f /sbin/pidof ]; then
       /sbin/pidof nginx | wc -w
    else
       ps ax | grep "nginx:" | grep -v grep | wc -l
    fi
}

function active() {
    /usr/bin/curl -s "http://$HOST:$PORT/${stub_status}/" 2>/dev/null| grep 'Active' | awk '{print $NF}'
}
function accepts() { 
    /usr/bin/curl -s "http://$HOST:$PORT/${stub_status}/" 2>/dev/null| awk NR==3 | awk '{print $1}'
}
function handled() { 
    /usr/bin/curl -s "http://$HOST:$PORT/${stub_status}/" 2>/dev/null| awk NR==3 | awk '{print $2}'
}
function requests() {
    /usr/bin/curl -s "http://$HOST:$PORT/${stub_status}/" 2>/dev/null| awk NR==3 | awk '{print $3}'
}
function reading() { 
    /usr/bin/curl -s "http://$HOST:$PORT/${stub_status}/" 2>/dev/null| grep 'Reading' | awk '{print $2}'
}
function writing() { 
    /usr/bin/curl -s "http://$HOST:$PORT/${stub_status}/" 2>/dev/null| grep 'Writing' | awk '{print $4}'
}
function waiting() { 
    /usr/bin/curl -s "http://$HOST:$PORT/${stub_status}/" 2>/dev/null| grep 'Waiting' | awk '{print $6}'
}

case "$1" in
    check)
        check
        ;;
    active)
        active
        ;;
    accepts)
        accepts
        ;;
    handled)
        handled
        ;;
    requests)
        requests
        ;;
    reading)
        reading
        ;;
    writing)
        writing
        ;;
    waiting)
        waiting
        ;;

    *)
        echo $"Usage $0 {check|active|accepts|handled|requests|reading|writing|waiting}"
        exit        
esac



# 增加执行权限
chmod +x /etc/zabbix/zabbix_agentd.d/nginx-status.sh
# 检测nginx获取的值。
/etc/zabbix/zabbix_agentd.d/nginx-status.sh {check|active|accepts|handled|requests|reading|writing|waiting}

# 修改配置文件
vim /etc/zabbix/zabbix_agentd.conf

# Return statistics
UserParameter=nginx.status[*],/etc/zabbix/zabbix_agentd.d/nginx-status.sh $1


# 重启zabbix-agent
systemctl restart zabbix-agent
zabbix_get -s 172.16.16.71 -k nginx.status[accepts]    
# zabbix_get只有在服务端执行才有效,在agent中限制了允许访问的ip

下载模板导入zabbix:Nginx_status
ok,完成。

参考:https://github.com/oscm/zabbix/tree/master/nginx


监控系统时间和NTP时间、时区变化

监控WIN服务器用下面的脚本;监控Linux服务器,同步时间请安装ntp服务。

1,配置时间同步服务
时间同步服务脚本,保存为bat,运行一次。

@echo off 
@REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Parameters /v NtpServer /t REG_SZ /d "0.cn.pool.ntp.org,0x9\0 1.cn.pool.ntp.org,0x9\0 2.cn.pool.ntp.org,0x9" /f
@echo off 
@REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Parameters /v Type /t REG_SZ /d NTP /f
@echo off
echo ------------------------------------
@echo off 
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\TimeProviders\NtpClient /v SpecialPollInterval /t REG_DWORD /d 60 /f
@echo off
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Config /v MaxAllowPhaseOffset /t REG_DWORD /d 3600 /f
@echo off
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Config /v MaxNegPhaseCorrection /t REG_DWORD /d 3600 /f
@echo off
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Config /v MaxPosPhaseCorrection /t REG_DWORD /d 3600 /f
@echo off
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Config /v PhaseCorrectRate /t REG_DWORD /d 7 /f
@echo off
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Config /v MinPollInterval /t REG_DWORD /d 3 /f
@echo off
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\W32Time\Config /v MaxPollInterval /t REG_DWORD /d 4 /f
@echo off 
sc triggerinfo w32time start/networkon
@echo off
gpupdate /force
@echo off
w32tm /resync
@echo off
net stop w32time
net start w32time

2,配置监控脚本、自定义key
Python监控脚本,监控WIN服务起可以打包为exe放在zabbix安装目录,业务需要,这里提供打包好的文件:get-time
把Timeout的值改为30
然后在zabbix_agentd.conf中添加自定义的key:UserParameter=custom.timediff.count,"D:\auto_bat\zabbix\get_time.exe"
重启zabbix服务。

#!/usr/bin/env python
# -*- coding:UTF-8 -*-
# 导入库,pytz是一个时区转换库
import time
import ntplib
import pytz
import datetime

# 设置要比对的时区并获取时区时间
tz = pytz.timezone('Asia/Shanghai')
timezone = datetime.datetime.now(tz).strftime('%Y%m%d%H%M%S')

def get_time():
    ntp_client = ntplib.NTPClient()
    response = ntp_client.request('2.cn.pool.ntp.org')
    wtime = time.strftime('%Y%m%d%H%M%S', time.localtime(response.tx_time))
    return wtime

# abs可以获取绝对值
if __name__ == '__main__':
    networktime = get_time()
    local_time = time.strftime('%Y%m%d%H%M%S')
    difference_a = abs(int(networktime) - int(local_time))
    difference_b = abs(int(timezone) - int(local_time))


# 先判断本地时间与NTP的时间差值,小于180(说明与时区时间基本一致),再判断时区;大于180,则需要同步时间。
# 判断时区,差值大于1200(接近20分钟,没有转成十进制时间了)则不是所期望的时区,需要修改时区。
# 配合zabbix报警,0是正常,1是时区错误,2是时间错误。
if difference_a <= 180:
    if difference_b >= 1200:
        print 1
    else:
        print 0
else:
    print 2

3,配置监控项和触发器
直接在WIN模板里添加监控项,设置名称,键值:custom.timediff.count 新应用集:Timezone,其他默认就行。
mark
还是在模板里配置触发器,设置报警级别等。
mark

再配置触发动作,同步时间w32tm /resync

测试

# 登陆zabbix服务端
zabbix_get -s [客户端ip] -k "custom.timediff.count"

参考

https://www.abcdocker.com/abcdocker/category/zabbix/
Zabbix模板网站1:https://monitoringartist.github.io/zabbix-searcher/
Zabbix模板网站2:https://share.zabbix.com/

(●゚ω゚●)