You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本循环重复执行问题求助:tail -F日志监听异常

解决Hive日志实时监听脚本循环重复执行的问题

我一眼就看出问题出在哪了——你的脚本每次匹配到select日志时,会全量扫描整个hive-server2.log文件,还取最后一行输出,这就导致只要有新的select日志进来,你就会重复处理之前已经处理过的历史记录,自然会出现循环重复执行的情况。

核心优化思路

放弃全量扫描日志文件的方式,改为流式逐行处理:实时跟踪当前日志流中的queryId,只关联当前select语句对应的s3路径,不碰历史日志内容。

修改后的脚本示例

# 初始化变量,用于跟踪当前的queryId和审计类型
current_query_id=""
AuditTypeID=""

tail -n 0 -F hive-server2.log | while read -r LINE; do
    # 匹配"Executing command(queryId="行,提取当前queryId
    if echo "$LINE" | grep -q "Executing command(queryId="; then
        # 用sed提取queryId(根据你的日志格式调整正则)
        current_query_id=$(echo "$LINE" | sed 's/.*queryId=\([^: ]*\):.*/\1/')
        # 判断是否是select语句,设置对应的AuditTypeID
        if echo "$LINE" | grep -qi "select "; then
            AuditTypeID=15
        else
            # 非select语句重置审计类型
            AuditTypeID=""
        fi
    # 匹配包含s3://的行,且当前有有效的select类型queryId
    elif [ -n "$current_query_id" ] && [ "$AuditTypeID" = "15" ] && echo "$LINE" | grep -q "s3://"; then
        # 提取s3路径(根据实际日志格式调整正则,这里取s3://到空格前的内容)
        s3_path=$(echo "$LINE" | grep -o "s3://[^ ]*")
        # 输出你需要的格式(这里是","+queryId,可按需调整)
        echo ",$current_query_id"
        # 处理完后重置变量,避免关联到后续不相关的日志
        current_query_id=""
        AuditTypeID=""
    fi
done

关键优化点说明

  1. 流式处理:只处理tail -F实时输出的新增日志行,不再全量读取整个日志文件,彻底避免重复处理历史内容。
  2. 实时跟踪queryId:当捕获到包含queryId的执行命令行时,先记录当前的queryId,同时判断是否是select语句并设置审计类型。
  3. 关联对应s3路径:只有当当前存在有效的select类型queryId时,再关联后续出现的s3路径,处理完成后立即重置变量,防止重复匹配。

额外注意事项

  • 请根据你的hive-server2.log实际格式调整正则表达式,比如queryId的提取规则、s3路径的匹配规则,确保能精准捕获需要的内容。
  • 使用read -r来避免转义字符干扰,保留日志行的原始内容。
  • 如果日志中select语句的大小写不固定,用grep -qi来忽略大小写匹配,避免漏判。

内容的提问来源于stack exchange,提问作者Jeyamahesan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:29:56