如何在Zabbix中为Nginx配置域名级超时错误自动发现规则
问题背景
我有一台运行Nginx的服务器,承载大量不同Web资源配置,每个配置都有独立重定向规则与upstream。不同域名日志中频繁出现upstream超时错误,示例日志如下:
2023/11/17 16:00:27 [error] 90304#90304: *16977866956 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.0.0.1, server: my1.site.com, request: "GET /papi/1.0/40-a46a-bdd7e4749 HTTP/1.1", upstream: "http://10.0.0.2:30415/60-d74f", host: "my1.site.com"
2023/11/17 16:00:27 [error] 90305#90305: *16977868169 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.0.58.1, server: my2.site.com, request: "PUT /papi/1.0/b9ad-4c28 HTTP/1.1", upstream: "http://10.0.0.3:30415/papi/1.0/c28-b913-02aebafeea", host: "my2.site.com"
2023/11/17 16:00:28 [error] 90301#90301: *16977870167 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 10.0.0.8, server: my3.site.com, request: "GET /papi/1.0/d-6329-4c78-ba08 HTTP/1.1", upstream: "http://10.0.0.92:30415/912d-6329-", host: "my3.site.com"
目前用以下命令统计最近1分钟总错误数上报Zabbix,超阈值告警:
awk '($0 >= from)' from="$(LC_ALL=C date +"%Y/%m/%d %H:%M" -d -1minute)" /var/log/nginx/* | grep "Connection timed out" | wc -l
但总错误数无法定位具体出错域名,需要通过Zabbix自动发现规则,按域名自动创建监控项和触发器,新增域名时自动生成监控项。
实现步骤
1. 编写Zabbix自动发现脚本(服务器端)
在Nginx服务器上创建脚本,用于提取需要监控的域名,推荐从Nginx配置提取更准确,避免漏监控未产生日志的域名:
脚本:/usr/local/bin/zabbix_discover_nginx_domains.sh
#!/bin/bash # 从Nginx配置文件提取所有server_name,去重后输出Zabbix自动发现格式 DOMAINS=$(grep -r "server_name" /etc/nginx/conf.d/ /etc/nginx/sites-available/ | awk '{print $2}' | sed 's/;//g' | sort -u) echo '{"data":[' COUNT=0 for DOMAIN in $DOMAINS; do if [ $COUNT -ne 0 ]; then echo ','; fi echo -n "{\"{#DOMAIN}\":\"$DOMAIN\"}" COUNT=$((COUNT+1)) done echo ']}'
给脚本添加执行权限:
chmod +x /usr/local/bin/zabbix_discover_nginx_domains.sh
2. 配置Zabbix Agent自定义参数
编辑Zabbix Agent配置文件(通常为/etc/zabbix/zabbix_agentd.conf),添加以下参数:
# 自动发现Nginx域名 UserParameter=nginx.domains.discover,/usr/local/bin/zabbix_discover_nginx_domains.sh # 统计指定域名最近1分钟的upstream超时错误数 UserParameter=nginx.upstream.timeout[*],awk '($0 >= from) && /Connection timed out/ && $10 == "'$1'"' from="$(LC_ALL=C date +"%Y/%m/%d %H:%M" -d -1minute)" /var/log/nginx/error.log | wc -l
重启Zabbix Agent生效:
systemctl restart zabbix-agent
3. 在Zabbix Server创建自动发现规则
- 进入Zabbix Web界面,新建模板(或修改现有模板),命名为
Template Nginx Domain Upstream Timeout - 在模板中添加自动发现规则:
- 名称:
Nginx Domains Discovery - 类型:
Zabbix agent - 键值:
nginx.domains.discover - 更新间隔:建议设置为3600秒(1小时),可根据域名新增频率调整
- 检查间隔:与更新间隔保持一致
- 名称:
4. 创建监控项原型
在自动发现规则下添加监控项原型:
- 名称:
Upstream Timeout Errors for {#DOMAIN} (Last 1min) - 类型:
Zabbix agent - 键值:
nginx.upstream.timeout[{#DOMAIN}] - 类型信息:
数字(无正负) - 更新间隔:60秒
- 历史数据保留时间:根据业务需求设置(如7天)
- 趋势数据保留时间:根据业务需求设置(如30天)
5. 创建触发器原型
在自动发现规则下添加触发器原型:
- 名称:
High upstream timeout errors on {#DOMAIN} - 表达式:
{Template Nginx Domain Upstream Timeout:nginx.upstream.timeout[{#DOMAIN}].last()}>5(阈值5可根据实际业务调整) - 严重性:根据需求设置(如警告/严重)
- 描述:
Domain {#DOMAIN} has {ITEM.LASTVALUE} upstream timeout errors in the last 1 minute
6. 关联模板到主机
将创建好的模板关联到目标Nginx服务器主机,等待自动发现规则执行后,Zabbix会自动为每个域名创建对应的监控项和触发器,新增域名时也会自动生成监控项。
内容的提问来源于stack exchange,提问作者archer1

