将管道多行 grep 输出捕获到变量中

将管道多行 grep 输出捕获到变量中

我正在使用 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

这是我的方法。

  1. 使用 zabbix“log”类型键来监控日志文件中的错误模式(这里是/var/log/uwsgi.log)。
  2. 调用上述1触发的zabbix远程命令。该远程命令通过linux命令tail(1)获取错误周围的行。

这种方法的优点是:

  1. 不需要安装和设置代理主机端特殊脚本(如上面讨论的 zabbix_sender.sh)。zabbix“日志”类型项目已经提供了这种用途。
  2. 代理主机上没有类似 zabbix_sender.sh 的脚本意味着没有额外的 CPU 和内存消耗。仅在触发时才会获取日志中错误周围的几行。

让我详细解释一下如何设置:

  1. 在 zabbix 中注册正则表达式,从管理 > 常规 > 正则表达式 > [新正则表达式],如“error|fail|fatal”。我们假设变量名称是@uwsgi_error_pattern。
  2. 从配置 > 主机 > [目标主机] 行 > 项目 > [创建项目] 注册项目,具有以下属性:
    • 描述:[任意名称]
    • 类型:Zabbix 代理(主动)
    • 密钥:log[/var/log/uwsgi.log,@uwsgi_error_pattern]
    • 信息类型:日志
  3. 从配置 > 主机 > [目标主机] 行 > 项目 > [创建项目] 注册第二项,并具有以下属性,以接受 zabbix 远程命令发送的获取日志标志(稍后提到):
    • 描述:[任意名称]
    • 类型:Zabbix诱捕器
    • 密钥: my_app.fetch_uwsgi_log
    • 信息类型:文本
  4. 从配置 > 主机 > [目标主机] 行 > 触发器 > [创建触发器] 注册触发器,具有以下属性:
    • 名称:{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
  5. 注册操作远程执行以获取日志文件错误行周围的数据,如下所示:
    • 名称:获取最新的 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有了新行。

相关内容