hello world

stay foolish, stay hungry

grafana plugin 查询结果列名 bug 排查

问题描述

有用户反馈,使用 grafanaplugin ,在 alerting 页面数据查询时,展示的列名不对。

查看页面的返回数据,第二列的列名的确有问题。

问题排查

首先怀疑是插件代码的bug,添加日志排查插件 QueryData 方法输出,发现输出的数据没问题。

由此怀疑可能是 grafana 内部的转换逻辑引起的。

下载 grafana 源码,看到有 ngalert 包,应该是 8.0 之后加的 unified alert 代码实现,相关代码应该是在这里。grafana 日志级别改成 debug,希望能打出来部分有用的日志,最终找到了插件返回之后就打印这行日志。

DBUG [11-22|16:43:12] expression datasource query (seriesSet)  logger=expr query=A

全局搜索,这行日志在 expr 包下面,顺着调用关系往上找,可以找到 ngalert/eval/eval.go,现在 unified alert 的调用关系应该就比较清晰了。

nglaert 的调度器顶层接口是 ScheduleService,调度器会一层一层的调用 ConditionEvaluator 接口的 Execute 方法,该方法会调用插件的 gRPC 接口查询数据,然后调用 eval 包进行数据转换。顺藤摸瓜,最终执行数据转换的方法是 Node 接口的 Execute 方法,该方法有两个实现,分别是 CMDNode 和 DSNode,而 debug 日志是 DSNode 打印的,所以进到 DSNode 的 Execute 方法进行排查。该方法的 284 行调用的 WideToMany 进行数据格式转换,继续排查,最终终于定位到问题。

数据转换时,会调用 SeriesFromFrame 函数,该函数有如下代码

// We use the frame name as series name if the frame name is set
if s.Frame.Name != "" {
    s.Frame.Fields[seriesTypeValIdx].Name = s.Frame.Name
}

插件代码中,如果设置了 Frame 的 name, 会拿 Frame.Name 覆盖数据列的 Name。