我正在使用 Zabbix 的zabbix_sender.sh
脚本将异常堆栈跟踪推送到我的远程 Zabbix 监控服务器。
zabbix_sender.sh
需要它发送的任何数据的一个键和一个值。它可以从中读取数据stdin
,但这会覆盖指定的任何键变量。由于我的stdin
数据格式不符合 Zabbix 的预期,因此我需要传入“值”作为参数。希望这能提供一些背景信息。
我想要完成的是将多行结果捕获到grep
一个变量中,保留换行符,以便我可以使用zabbix_sender.sh
该变量作为参数来调用脚本。
到目前为止我尝试过的情况如下:
tail -Fn0 /var/log/uwsgi.log | grep "Exception:" -A 100 | (read tback; /usr/local/zabbix/bin/zabbix_sender -z myzserver.com -s MyHostName -k uwsgi_traceback -o $tback)
据我所知,那永远不会调用zabbix_sender.sh
。
为了测试,我尝试使用这个命令,但它似乎也不起作用:
tail -Fn0 /var/log/uwsgi.log | grep "Exception:" -A 100 | (read errorlines; echo "$errorlines" > /tmp/errorlines.txt)
该/tmp/errorlines.txt
文件从未被创建。
我如何将grep
的输出行捕获到变量中,以便我可以使用该变量作为参数调用另一个脚本?
答案1
问题在于尾部;由于它处于连续模式,因此它永远不会吐出一些可供“读取”的内容。
这应该有效:
#!/bin/bash
echo "0" >/tmp/numberoflines
IFS=''
while [ 1 ]
do
NUMBER=$(cat /tmp/numberoflines)
LINES=$(wc -l < /var/log/uwsgi.log)
DIFFERENCE=$(($LINES-$NUMBER))
if [ $DIFFERENCE != 0 ]; then
exception=$(tail -n $DIFFERENCE /var/log/uwsgi.log | grep "Exception:" -A 100)
/zabbix/bin/zabbix_sender -z myzserver.com -s MyHostName -k uwsgi_traceback -o $tback) $exception;
fi
sleep 5;
echo "$LINES" >/tmp/numberoflines
done
答案2
这是我的方法。
- 使用 zabbix“log”类型键来监控日志文件中的错误模式(这里是/var/log/uwsgi.log)。
- 调用上述1触发的zabbix远程命令。该远程命令通过linux命令tail(1)获取错误周围的行。
这种方法的优点是:
- 不需要安装和设置代理主机端特殊脚本(如上面讨论的 zabbix_sender.sh)。zabbix“日志”类型项目已经提供了这种用途。
- 代理主机上没有类似 zabbix_sender.sh 的脚本意味着没有额外的 CPU 和内存消耗。仅在触发时才会获取日志中错误周围的几行。
让我详细解释一下如何设置:
- 在 zabbix 中注册正则表达式,从管理 > 常规 > 正则表达式 > [新正则表达式],如“error|fail|fatal”。我们假设变量名称是@uwsgi_error_pattern。
- 从配置 > 主机 > [目标主机] 行 > 项目 > [创建项目] 注册项目,具有以下属性:
- 描述:[任意名称]
- 类型:Zabbix 代理(主动)
- 密钥:log[/var/log/uwsgi.log,@uwsgi_error_pattern]
- 信息类型:日志
- 从配置 > 主机 > [目标主机] 行 > 项目 > [创建项目] 注册第二项,并具有以下属性,以接受 zabbix 远程命令发送的获取日志标志(稍后提到):
- 描述:[任意名称]
- 类型:Zabbix诱捕器
- 密钥: my_app.fetch_uwsgi_log
- 信息类型:文本
- 从配置 > 主机 > [目标主机] 行 > 触发器 > [创建触发器] 注册触发器,具有以下属性:
- 名称:{HOSTNAME} 上的 uwsgi 日志监视器
- 表达式 ({[目标主机]:log[/var/log/uwsgi.log,@uwsgi_error_pattern].iregexp(@uwsgi_error_pattern)})#0&({[目标主机]:log[/var/log/uwsgi.log,@uwsgi_error_pattern].nodata(300)})=0
- 注册操作远程执行以获取日志文件错误行周围的数据,如下所示:
- 名称:获取最新的 uwsgi 登录错误
- 动作操作:
- 操作类型:远程命令
- 远程命令:{HOSTNAME}:zabbix_sender -z [zabbix-server] -s {HOSTNAME} -k my_app.fetch_uwsgi_log -o“`tail -200 /var/log/uwsgi.log`”
注 1:上述步骤中的键名“my_app.fetch_uwsgi_log”仅作为示例。我们可以定义任何唯一的名称来绑定 zabbix_sender 和项目。
注2:您可能需要在 /etc/zabbix/zabbix_agentd.conf 上设置 AllowRoot=1 来允许 zabbix-agent 读取 uwsgi.log。
答案3
您必须关闭单词拆分在 bash 中,例如通过清除 IFS:
export IFS=""
set NEWVAR=`your tail|grep expression`
现在echo $NEWVAR
有了新行。