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

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

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

failed to parse hipchat message. failed to parse [notify] field, expected a boolean value but found [VALUE_STRING] 表示 Elasticsearch Watcher 在解析 HipChat 消息时,某个字段(如 notify)存在,但值类型不符合解析器预期。典型场景是 notify 字段必须是布尔值;如果传入字符串、数字或对象,就会抛出此异常。

从源码片段可以看出,对 notify 的处理非常直接:检查 token 是否为 VALUE_BOOLEAN,如果是则读取布尔值;否则抛出异常。

常见现象 #

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

典型报错与异常栈 #

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

ElasticsearchParseException: failed to parse hipchat message. failed to parse [notify] field, expected a boolean value but found [VALUE_STRING]
	at org.elasticsearch.xpack.watcher.hipchat.HipChatMessage...

或者字段值类型是数字:

ElasticsearchParseException: failed to parse hipchat message. failed to parse [notify] field, expected a boolean value but found [VALUE_NUMBER]
	at org.elasticsearch.xpack.watcher.hipchat.HipChatMessage...

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

failed to parse hipchat message. failed to parse [field] field, expected a boolean value 的根因是"HipChat 消息字段值类型错误"。Elasticsearch Watcher 的 HipChat 通知功能对消息字段有严格类型要求,如 notify 必须是布尔类型(true/false);如果字段值类型不对,就会抛出此异常。

常见原因通常包括:

  • 把字段写成了字符串:如 notify: "true" 代替 notify: true(字符串 vs 布尔值)。
  • 把 UI 参数原样透传成数字或对象:如 notify: 1notify: { ... }
  • 模板渲染后输出了非法 token:如果字段来自模板,渲染后可能产生了字符串形式的布尔值。
  • 上游系统错误:上游系统输出的字段类型不符合 Elasticsearch 要求。
  • JSON 序列化问题:如果使用 SDK 或客户端,可能因为序列化配置导致布尔值变成了字符串。

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

建议按"先查看报错字段和值、再对照官方文档、后检查消息构造"的顺序处理:

  1. 查看报错中的字段名和值类型:异常信息中的 field 就是导致失败的字段,token 就是实际的值类型。

    # 查看 Elasticsearch 日志中的具体错误信息
    grep -r "expected a boolean value" /var/log/elasticsearch/
    
  2. 对照官方文档:确认当前 Elasticsearch 版本的 HipChat 消息字段类型要求。

    HipChat 消息字段类型(以 6.8 为例):

    • body(字符串,必需)
    • room(字符串数组,必需)
    • notify(布尔值,可选)
    • color(字符串,可选)
    • from(字符串,可选)
  3. 检查消息 JSON 结构:确认字段值是正确类型,不是字符串形式。

    // 错误示例(notify 是字符串)
    {
      "hipchat": {
        "message": {
          "body": "Watch triggered",
          "room": ["alerts"],
          "notify": "true"  // 错误:应该是布尔值
        }
      }
    }
       
    // 正确示例
    {
      "hipchat": {
        "message": {
          "body": "Watch triggered",
          "room": ["alerts"],
          "notify": true  // 正确:布尔值
        }
      }
    }
    
  4. 检查模板渲染:如果字段来自模板,确认渲染后没有变成字符串形式的布尔值。

    # 查看 Watcher 配置
    curl -X GET "localhost:9200/_watcher/watch/my_watch" -u elastic:password
    
  5. 检查 SDK 或客户端:如果使用 SDK,确认布尔值序列化正确。

    // 正确构造 HipChat 消息
    // 确保 notify 是布尔类型
    boolean notify = true;  // 不是 "true"
    

排查时需要注意的问题: #

  • 这个错误是字段值类型问题,不是字段缺失或网络问题,需要重点关注字段值类型。
  • JSON 中的 true"true" 是不同的:true 是布尔值,"true" 是字符串。
  • HipChat 功能在 Elasticsearch 7.x 中已废弃,在 8.x 中已移除,如果计划升级,需要考虑迁移到其他通知渠道(如 Slack、Webhook)。

4. 如何解决这个错误 #

常用修复思路 #

  • 修正字段值类型:确保布尔字段是布尔值,不是字符串。

    // 错误示例(字符串形式的布尔值)
    {
      "notify": "true",   // 错误
      "color": "red"    // 正确:字符串
    }
      
    // 正确示例(布尔值)
    {
      "notify": true,     // 正确
      "color": "red"
    }
    
  • 修正模板渲染:如果字段来自模板,确保渲染后输出正确的 JSON 类型。

    // 错误示例(模板渲染后变成字符串)
    {
      "notify": "{{#is_notify}}true{{/is_notify}}"  // 可能渲染成 "true"
    }
      
    // 正确示例(使用 Mustache 布尔值)
    {
      "notify": {{#is_notify}}true{{/is_notify}}{{^is_notify}}false{{/is_notify}}
    }
    
  • 修正 SDK 使用:确保使用正确的数据类型构造消息。

    // 错误示例(字符串)
    message.setNotify("true");  // 错误:字符串
      
    // 正确示例(布尔值)
    message.setNotify(true);   // 正确:布尔值
    
  • 使用正确的 JSON 格式:避免手动拼接 JSON,使用 JSON 库确保类型正确。

    // 正确:使用 JSON 库构造
    {
      "body": "Alert message",
      "room": ["alerts"],
      "notify": true  // 注意:没有引号
    }
    
  • 考虑迁移到其他通知渠道:如果计划升级到 7.x 或 8.x,HipChat 功能已废弃,需要迁移。

    // 迁移到 Webhook 通知(示例)
    {
      "actions": {
        "send_webhook": {
          "webhook": {
            "scheme": "https",
            "host": "webhook.site",
            "port": 443,
            "path": "/{your_webhook_url}",
            "method": "post",
            "body": "Alert: {{ctx.payload.message}}"
          }
        }
      }
    }
    

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

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

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

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

5. 小结 #

failed to parse hipchat message. failed to parse [field] field, expected a boolean value 本质是一个严格的消息字段类型校验错误。修复重点是字段值类型,而不是索引、节点或网络问题。大多数情况下,这个问题可以通过修正字段值类型、检查模板渲染和确保 JSON 序列化正确来解决。

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

相关错误 #

参考文档 #

附:日志上下文 #

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

} else if (Field.NOTIFY.match(currentFieldName, parser.getDeprecationHandler())) {
    if (token == XContentParser.Token.VALUE_BOOLEAN) {
        notify = parser.booleanValue();
    } else {
        throw new ElasticsearchParseException("failed to parse hipchat message. failed to parse [" + Field.NOTIFY.getPreferredName() + "] field, expected a " +
            "boolean value but found [" + token + "]");
    }
} else if (Field.BODY.match(currentFieldName, parser.getDeprecationHandler())) {
    try {
        body = TextTemplate.parse(parser);