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

使用Promtail解析嵌套JSON数组至Grafana Loki:解决元素数量不固定的数组字段提取问题

解决Promtail Pipeline解析可变长度JSON数组的问题

问题根源

你当前的配置里,第三个json stage的source是transferring,但这个字段是JSON数组,而普通的json stage只能处理单个JSON对象,所以无法从数组中提取eta和name字段,导致这两个字段生成失败。


方案1:将数组元素拆分为独立日志条目(推荐)

如果希望每个传输的文件对应一条独立的日志(方便后续查询单个文件的传输状态),可以用unpack stage先展开数组,再解析每个元素:

pipeline_stages:
  # 1. 解析顶层JSON,提取基础字段和stats对象
  - json:
      expressions:
        level: level
        msg: msg
        timestamp: time
        stats: stats
  # 2. 解析stats对象,提取bytes、checks和transferring数组
  - json:
      expressions:
        bytes: bytes
        checks: checks
        transferring: transferring
      source: stats
  # 3. 展开transferring数组,每个元素生成一条新日志,原有字段会被保留
  - unpack:
      source: transferring
      target: transferring_item  # 将数组中的单个对象存入这个字段
  # 4. 解析单个transferring_item对象,提取eta和name
  - json:
      expressions:
        transferring_eta: eta
        transferring_name: name
      source: transferring_item
  # 5. 设置标签(注意:长路径类的值不适合做标签,比如transferring_name建议作为日志字段保留)
  - labels:
      level:
      bytes:
      checks:
      transferring_eta:
  # 可选:指定日志内容的来源(默认会保留所有字段)
  - output:
      source: msg

效果说明:

  • 原来的1条日志会被拆分成与transferring数组元素数量相同的日志条目
  • 每条新日志都会保留原有的level、msg、bytes、checks等字段,同时新增transferring_eta和transferring_name字段

方案2:在单条日志中保留所有数组元素(不拆分)

如果不想拆分日志,希望把数组中所有元素的eta和name提取为带索引的字段(比如transferring_0_eta、transferring_1_name),需要用到lua stage来动态处理可变长度的数组,配置示例如下:

pipeline_stages:
  # 1. 解析顶层JSON,提取所有字段
  - json:
      expressions:
        level: level
        msg: msg
        timestamp: time
        bytes: stats.bytes
        checks: stats.checks
        transferring: stats.transferring
  # 2. 用Lua脚本遍历数组,动态生成带索引的字段
  - lua:
      script: |
        transferring = log.transferring
        if type(transferring) == "table" then
          for i, item in ipairs(transferring) do
            log["transferring_" .. i .. "_eta"] = item.eta
            log["transferring_" .. i .. "_name"] = item.name
          end
        end
        -- 可选:删除原始的transferring数组字段
        log.transferring = nil
  # 3. 设置标签
  - labels:
      level:
      bytes:
      checks:

效果说明:

  • 单条日志中会新增transferring_1_eta、transferring_1_name、transferring_2_eta等字段,数量与数组元素一致
  • 适合需要保留日志完整性,且数组长度不会特别大的场景

注意事项

  • 标签值不宜过长,像文件路径这类内容建议作为日志字段保留,不要添加到标签中,避免影响Loki的查询性能
  • 如果使用unpack stage,记得确认你的日志场景适合拆分条目(比如监控单个文件传输状态时非常适用)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:37:48