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

如何使用jq过滤器迭代提取每个{}块中的元素

实现Prometheus指标块的逐块迭代提取与处理

需求说明

现有以下两个Prometheus指标块:

{ __name__: sc_pcd_g2version, container: mgmtbroker, endpoint: vxexporter, instance: 10.42.24.132:9116, job: prometheus, namespace: delivery, pod: chn1-d1-ac-0, service: prometheus }
{ __name__: sc_pcd_g2version, container: mgmtbroker, endpoint: vxexporter, instance: 10.42.3.110:9116, job: prometheus, namespace: delivery, pod: chn1-d1-ia-0, service: prometheus }

需要通过jq过滤器迭代处理,第一次提取第一个{}块,第二次提取第二个{}块,并完善Shell代码实现逐块提取和每个指标的状态判断逻辑。

完善后的Shell代码

function get_prometheus_vector_value {
  local _RESULT
  # 动态获取向量元素总数
  local count=$(echo "$1" | jq -r '. | length')
  for ((i=0; i<count; i++)); do
    # 提取每个元素的value(Prometheus向量value格式为[时间戳, 值])
    echo $(echo "$1" | jq -r '.['$i'].value?')
  done
}

function get_prometheus_vector_metric {
  local _RESULT
  # 动态获取向量元素总数
  local count=$(echo "$1" | jq -r '. | length')
  for ((i=0; i<count; i++)); do
    # 提取每个元素的metric元数据,转为紧凑格式
    echo $(echo "$1" | jq -r '.['$i'].metric?' | xargs)
  done
}

# 设置退出处理函数
trap on_exit EXIT TERM

# 处理命令行参数
process_command_line "$@"

# 获取Prometheus原始查询结果
PROMETHEUS_RAW_RESULT="$( get_prometheus_raw_result )"

# 解析Prometheus结果
if [[ "${PROMETHEUS_QUERY_TYPE}" = "scalar" ]]; then
    PROMETHEUS_RESULT=$( get_prometheus_scalar_result "$PROMETHEUS_RAW_RESULT" )
    PROMETHEUS_METRIC=UNKNOWN
else
    # 获取所有向量值,每行对应一个指标的value
    PROMETHEUS_VALUES=$( get_prometheus_vector_value "$PROMETHEUS_RAW_RESULT" )
    # 获取所有指标元数据,每行对应一个指标的metric块
    PROMETHEUS_METRICS=$( get_prometheus_vector_metric "$PROMETHEUS_RAW_RESULT" )

    # 配对值和元数据,逐行处理每个指标
    paste <(echo "$PROMETHEUS_VALUES") <(echo "$PROMETHEUS_METRICS") | while read -r val metric; do
        # 提取实际指标值(取value数组的第二个元素)
        PROMETHEUS_RESULT=$(echo "$val" | jq -r '.[1]')
        printf '当前指标值: %s\n' "${PROMETHEUS_RESULT}"

        # 格式化指标元数据为标准JSON块
        FORMATTED_METRIC=$(echo "$metric" | jq -Rr 'scan("({[^}]*})") | .[0]')
        printf '当前指标元数据: %s\n' "${FORMATTED_METRIC}"

        # 数值校验与Nagios状态判断
        if [[ ${PROMETHEUS_RESULT} =~ ^-?[0-9]+(\.[0-9]+)?$ ]]; then
            if eval [[ ${PROMETHEUS_RESULT} ${COMPARISON_METHOD} ${CRITICAL_LEVEL} ]]; then
                NAGIOS_STATUS=CRITICAL
                NAGIOS_SHORT_TEXT="${METRIC_NAME} 数值为 ${PROMETHEUS_RESULT}"
            elif eval [[ ${PROMETHEUS_RESULT} ${COMPARISON_METHOD} ${WARNING_LEVEL} ]]; then
                NAGIOS_STATUS=WARNING
                NAGIOS_SHORT_TEXT="${METRIC_NAME} 数值为 ${PROMETHEUS_RESULT}"
            else
                NAGIOS_STATUS=OK
                NAGIOS_SHORT_TEXT="${METRIC_NAME} 数值为 ${PROMETHEUS_RESULT}"
            fi
        else
            if [[ "${NAN_OK}" = "true" && "${PROMETHEUS_RESULT}" = "NaN" ]]; then
                NAGIOS_STATUS=OK
                NAGIOS_SHORT_TEXT="${METRIC_NAME} 数值为 ${PROMETHEUS_RESULT}"
            else
                NAGIOS_SHORT_TEXT="无法解析Prometheus响应"
                NAGIOS_LONG_TEXT="${METRIC_NAME} 的返回值为 ${PROMETHEUS_RESULT}"
            fi
        fi

        # 添加元数据到输出文本(如果开启)
        if [[ "${NAGIOS_INFO}" = "true" ]]; then
            NAGIOS_SHORT_TEXT="${NAGIOS_SHORT_TEXT} | 指标元数据: ${FORMATTED_METRIC}"
        fi

        # 添加性能数据(如果开启)
        if [[ "${PERFDATA}" = "true" ]]; then
            NAGIOS_SHORT_TEXT="${NAGIOS_SHORT_TEXT} | query_result=${PROMETHEUS_RESULT}"
        fi

        # 输出当前指标的处理结果
        printf '%s: %s\n' "${NAGIOS_STATUS}" "${NAGIOS_SHORT_TEXT}"
    done
fi

核心修改说明

  • 动态迭代支持:通过jq获取向量元素总数,不再硬编码循环次数,适配任意数量的指标块。
  • 指标数据配对:将每个指标的value和metric分别按行输出,用paste命令一一配对,确保处理时数据对应准确。
  • 数值解析修复:针对Prometheus向量返回的[timestamp, value]格式,提取第二个元素作为实际指标值。
  • 循环逻辑修正:使用while read逐行处理配对后的指标数据,实现每个{}块的单独提取与处理。
  • 语法错误修复:移除原代码中无效的元数据提取语句,改为通过jq scan准确提取每个{}块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:47:02