📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 6.8-6.8(HipChat 功能在更高版本中已废弃或移除)

1. 错误异常的基本描述 #

failed to parse hipchat message, failed to parse [field] field 表示 Elasticsearch Watcher 在解析 HipChat 消息时,某个字段(如 roomuser)存在,但该字段内部的模板或数组元素解析失败。根据附带源码,常见场景是 room 字段中的某个模板元素无法通过 TextTemplate.parse(parser)

这不是字段缺失问题,而是字段值解析失败,可能是数组元素类型错误或模板结构损坏。

常见现象 #

  • 配置 HipChat 通知的 Watcher 时返回 400 Bad Request,提示 failed to parse field。
  • 在创建或更新 Watcher 时,HipChat message 部分解析失败。
  • 错误集中在特定 HipChat 消息配置上,其他通知渠道(如 email、slack)可能正常。
  • Elasticsearch 日志中可以看到 failed to parse hipchat message. failed to parse [field] field 关键字,伴随 ElasticsearchParseException
  • 在 Kibana 的 Watcher 管理界面中,可能无法保存包含 HipChat 通知的 Watcher。

典型报错与异常栈 #

常见日志形态通常类似下面这样:

ElasticsearchParseException: failed to parse hipchat message. failed to parse [room] field
Caused by: java.lang.IllegalArgumentException: Expected START_OBJECT but got VALUE_STRING
	at org.elasticsearch.xpack.watcher.hipchat.HipChatMessage...

或者数组元素类型错误:

ElasticsearchParseException: failed to parse hipchat message. failed to parse [user] field
Caused by: java.io.IOException: Invalid template format
	at org.elasticsearch.xpack.watcher.hipchat.HipChatMessage...

2. 为什么会发生这个错误 #

failed to parse hipchat message, failed to parse [field] field 的根因是"HipChat 消息字段值解析失败"。Elasticsearch Watcher 的 HipChat 通知功能对消息结构有严格要求,数组字段(如 roomuser)中的每个元素必须是合法字符串或模板对象;如果元素类型不对,就会抛出此异常。

常见原因通常包括:

  • 数组元素不是合法字符串或模板roomuser 数组里的元素不是合法字符串或模板对象。
  • 模板对象结构损坏:模板对象结构损坏,无法通过 TextTemplate.parse(parser)
  • 数组里混入了对象、数字等不支持的值:如把对象、数字等不支持的值混入了数组。
  • 手工配置了错误格式的数组:手写 JSON 时,数组元素格式错误。
  • 模板渲染问题:若使用模板生成消息,渲染后可能产生了错误结构。
  • 版本不兼容:使用了旧版本的 HipChat 消息模板。

3. 如何排查和解决这个异常和解决这个异常 #

建议按"先查看报错字段、再检查数组元素、后验证模板格式"的顺序处理:

  1. 查看异常中的字段名:异常信息中的 field 就是导致失败的字段(如 roomuser),记录下来。

    # 查看 Elasticsearch 日志中的具体错误信息
    grep -r "failed to parse hipchat message. failed to parse" /var/log/elasticsearch/
    
  2. 检查字段值的数组元素:确认数组中的每个元素是否是合法字符串或模板对象。

    // 正确的 HipChat 消息结构示例
    {
      "hipchat": {
        "message": {
          "body": "Watch triggered",
          "room": ["ops-room"],  // 正确的数组:字符串元素
          "user": ["bot-user"]  // 正确的数组:字符串元素
        }
      }
    }
       
    // 错误示例(数组元素类型错误)
    {
      "hipchat": {
        "message": {
          "body": "Watch triggered",
          "room": [{"name": "ops-room"}]  // 错误:数组元素应该是字符串,不是对象
        }
      }
    }
    
  3. 验证模板格式:若使用模板,确认模板本身可被 TextTemplate.parse 接受。

    // 正确的模板格式
    {
      "body": "{{ctx.payload.message}}",  // 正确的模板字符串
      }
       
    // 错误示例(模板格式错误)
    {
      "body": { "template": "{{ctx.payload.message}}"}  // 错误:应该是字符串,不是对象
    }
    
  4. 检查 Watcher 配置:查看完整的 Watcher 配置,确认 HipChat message 结构正确。

    # 查看 Watcher 配置
    curl -X GET "localhost:9200/_watcher/watch/my_watch" -u elastic:password
    
  5. 简化配置:暂时移除复杂条件,用最小化配置复现问题。

    # 测试最简单的 HipChat message
    curl -X PUT "localhost:9200/_watcher/watch/test_watch" -H 'Content-Type: application/json' -d'
    {
      "trigger": { "schedule": { "interval": "10s" } },
      "input": { "none": {} },
      "condition": { "always": {} },
      "actions": {
        "send_hipchat": {
          "hipchat": {
            "message": {
              "body": "Test message",
              "room": ["test-room"]
            }
          }
        }
      }
    }
    '
    

排查时需要注意的问题 #

  • 这个错误是消息字段值问题,不是字段缺失或网络问题,需要重点关注字段值,而不是通知渠道配置。
  • HipChat 的数组字段(如 roomuser)要求每个元素是字符串,不是对象或其他类型。
  • 如果问题出现在模板使用后,很可能是模板格式错误,需要检查模板语法。
  • HipChat 功能在 Elasticsearch 7.x 中已废弃,在 8.x 中已移除,如果计划升级,需要考虑迁移到其他通知渠道(如 Slack、Webhook)。

4. 如何解决这个错误 #

常用修复思路 #

  • 修正数组元素类型:确保 roomuser 等数组字段的每个元素是字符串。

    // 错误示例(元素是对象)
    {
      "room": [{"name": "ops-room"}]  // 错误
    }
      
    // 正确示例(元素是字符串)
    {
      "room": ["ops-room"]  // 正确
    }
    
  • 修正模板格式:确保模板是合法字符串,且 Mustache 语法正确。

    // 错误示例(模板是对象)
    {
      "body": { "template": "{{ctx.payload.message}}"}  // 错误
    }
      
    // 正确示例(模板是字符串)
    {
      "body": "{{ctx.payload.message}}"  // 正确
    }
    
  • 使用正确的数组格式:避免混用对象、数字等不支持的类型。

    // 错误示例(混合类型)
    {
      "room": ["ops-room", 123]  // 错误:不能混用字符串和数字
    }
      
    // 正确示例
    {
      "room": ["ops-room", "alerts-room"]  // 正确:都是字符串
    }
    
  • 考虑迁移到其他通知渠道:如果计划升级到 7.x 或 8.x,HipChat 功能已废弃,需要迁移到 Slack、Webhook 等渠道。

    // 迁移到 Slack 通知(示例)
    {
      "actions": {
        "send_slack": {
          "slack": {
            "message": {
              "text": "Watch triggered: {{ctx.payload.message}}",
              "channel": "#alerts"
            }
          }
        }
      }
    }
    

后续注意事项与推荐建议 #

  • 在应用层对 HipChat 消息进行校验,确保数组元素类型正确。
  • 在 CI/CD 流程中加入消息结构校验步骤,在发送到 Elasticsearch 前验证其正确性。
  • 如果计划升级 Elasticsearch,提前规划 HipChat 迁移方案,改用其他通知渠道。
  • 为 Watcher 配置错误配置专门的监控和告警,在消息解析失败时及时通知。
  • 定期审查 Watcher 配置,清理不被支持的字段,避免遗留兼容性问题。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 适合查看集群的 Watcher 配置、通知渠道状态、错误趋势和消息内容,帮助快速定位 failed to parse hipchat message 是字段问题、模板问题还是渠道问题,并提供可视化的 Watcher 管理和编辑功能。
  • INFINI Gateway 可以记录所有 Watcher 相关的请求日志,帮助定位 HipChat 消息解析失败的具体环节,同时提供请求审计功能。
  • 建议将 Watcher 执行状态、通知成功率和消息解析错误统一接入监控面板,结合 INFINI Console 的告警功能,在消息解析失败时及时通知管理员。

5. 小结 #

failed to parse hipchat message, failed to parse [field] field 本质是一个严格的消息字段值校验错误。修复重点是确保数组元素类型正确和模板格式合法,而不是索引、节点或网络问题。大多数情况下,这个问题可以通过修正数组元素类型、修正模板格式和考虑渠道迁移来解决。

只要把消息结构校验、模板管理和渠道迁移规划固定下来,大多数 HipChat 消息解析类异常都可以被提前拦截,也更容易通过 INFINI Console 和 INFINI Gateway 实现持续防护。

相关错误 #

参考文档 #

附:日志上下文 #

下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:

if (token == XContentParser.Token.START_ARRAY) {
    while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
        try {
            templates.add(TextTemplate.parse(parser));
        } catch (ElasticsearchParseException epe) {
            throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [" + epe + "] field",
                Field.ROOM.getPreferredName());
        }
    }
} else {
    try {