Scala采集EMC Recovery Point数据写入InfluxDB失败求助
解决Scala从EMC Recovery Point写数据到InfluxDB的两类错误
一、修复java.util.NoSuchElementException: key not found: measurement错误
这个错误的核心是构造InfluxDB数据点时缺少必填的measurement名称,按以下步骤排查修复:
- 检查
collector.xml配置:确认是否存在指定measurement的配置项,比如:
如果没有,添加该配置项,指定你要写入InfluxDB的measurement名称(等同于数据库表名)。<influxdb> <measurement>rp_vms_monitor</measurement> <!-- 其他配置如url、db、username等 --> </influxdb> - 检查
influxdb.scala中的代码:避免直接用强制取值的方式获取measurement,改用安全取值逻辑:// 错误写法(会抛出NoSuchElementException) val measurement = config("measurement").as[String] // 正确写法1:从配置中安全获取,带默认值 val measurement = config.getAs[String]("measurement").getOrElse("rp_default_monitor") // 正确写法2:从RP返回的JSON中提取,先判断字段是否存在 val measurement = (json \ "measurement").asOpt[String].getOrElse("rp_default_monitor") - 确认InfluxDB数据点构造逻辑:确保每个写入的Point都明确指定measurement,比如:
import org.influxdb.dto.Point val point = Point.measurement(measurement) .addField("field1", value1) .time(System.currentTimeMillis(), TimeUnit.MILLISECONDS) .build()
二、修复JSON映射时JObject无法转为String的错误
vmsInformation是嵌套的JSON对象(JObject),直接调用.as[String]会触发类型转换失败,有两种处理方案:
方案1:将整个JObject序列化为JSON字符串存储
如果需要把vmsInformation作为整体存入InfluxDB的某个字段,用JSON库将其序列化为字符串(以Play JSON为例):
import play.api.libs.json._ // 假设json是从RP拉取的根JSON对象 val vmsInfoObj = (json \ "vmsInformation").as[JsObject] // 序列化为紧凑的JSON字符串 val vmsInfoStr = Json.stringify(vmsInfoObj) // 写入InfluxDB时作为字符串字段 val point = Point.measurement(measurement) .addField("vmsInformation", vmsInfoStr) // 其他字段... .build()
方案2:展开嵌套JObject为扁平字段
如果需要将vmsInformation中的子字段单独作为InfluxDB的字段存储,展开嵌套结构:
import play.api.libs.json._ val vmsInfoObj = (json \ "vmsInformation").as[JsObject] val pointBuilder = Point.measurement(measurement) // 遍历JObject的所有键值对,添加到Point中 vmsInfoObj.fields.foreach { case (key, value) => value match { case JsNumber(num) => pointBuilder.addField(s"vms_$key", num.doubleValue()) case JsString(str) => pointBuilder.addField(s"vms_$key", str) case JsBoolean(bool) => pointBuilder.addField(s"vms_$key", bool) // 根据实际数据类型扩展处理逻辑 } } val point = pointBuilder.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS).build()
额外排查建议
- 打印RP拉取的原始JSON数据,确认
vmsInformation的结构和内容,避免处理不存在的字段 - 检查
output.scala中处理vmsInformation的代码逻辑,确认没有错误的类型转换调用 - 启用更详细的日志,定位错误抛出的具体代码行,精准修复问题
内容的提问来源于stack exchange,提问作者Yalcin
相关产品推荐
相关产品推荐

