Grafana 变量必须与查询语言的语义一致
Grafana 仪表盘变量让同一组面板能够切换环境、服务或实例,而不必复制多份仪表盘。查询变量从数据源获得选项,自定义变量则可以维护一份有意固定的列表。这两种方式没有绝对优劣:当选项应跟随数据源发现结果变化时,可以使用查询变量;当选择范围就是一份较小且稳定的约定时,维护静态列表同样合理。变量是否合适,取决于它如何表达实际使用需求。 数据源执行查询之前,变量会先被代入查询表达式,所以变量格式本身属于查询正确性的一部分。Prometheus 多选场景应使用正则标签匹配,例如 environment=~"$environment"。Grafana 的 Prometheus 插值逻辑会把选中值处理为正则候选项,并执行所需转义。如果改用精确等号匹配,组合后的文本只会被当成一个标签值,并不会自动变成希望表达的多个环境选择。变量编辑器里的 label_values 是发现选项的辅助语法,不是可以直接复制到面板表达式中使用的 PromQL 函数。 检查最终送出的表达式 这里存在两层语法:正则表达式,以及包裹它的 PromQL 字符串。production.eu 中的点号应表示字面字符,不能成为同时匹配 productionXeu 的通配符。应让数据源按其约定完成插值;使用显式格式覆盖时,要检查真正发送出去的查询。raw 格式会绕过数据源格式化,并不是解决复杂变量值的通用办法。表面上省掉反斜线,可能只是把错误隐藏在返回的数字中。 全部选项也有明确语义。本例没有设置自定义的全部值,因此会展开经过筛选的可用选项。菜单只包含 production.eu 和 staging,全部选择就应覆盖这两个环境。如果把全部值改成点星号等自定义表达式,范围则可能扩大到后台正则允许匹配的其他标签。需要先决定这里的全部究竟指当前菜单中的值,还是更广的查询范围,再用刻意排除的数据验证这种决定。 坏掉的样子 查询变量不会保证永远新鲜,刷新设置决定了 Grafana 何时重新执行选项查询。选项依赖时间范围时,通常还需要随时间范围变化刷新。存在链式变量,也不保证每组上游选择都能找到下游组合;数据本来不存在时,结果完全可能为空。应当区分真实的空集合、已经陈旧的选择和查询错误,不能看到无数据提示,就直接把它解释为服务故障。 变量筛选不是权限控制。菜单里隐藏一个环境,并不会从数据源删除它,也不会阻止其他获准查询请求这些数据。访问边界需要在对应的 Grafana 配置与后台数据服务中落实。分享链接携带的同样只是选中状态,不是权限声明。多个环境通过重复的 var-environment 参数传递,不能随意发明一个逗号拼接的权限列表,再期望后台自动按访问规则理解它。 快速验证 保存代码为 grafana-variables.py,在准备好 Python 和 Docker 后,运行 python3 grafana-variables.py –serve。脚本在专用桥接网络中创建可删除的 Grafana 12.1.0 与 Prometheus 3.5.1 容器,仅通过本机回环地址暴露 Grafana,不挂载宿主机目录。打开输出的仪表盘地址,结束后按控制键加 C,脚本会删除两个容器及本次网络。不带服务参数运行时,只执行后台检查并立即清理。 ...