TT Lab
开始
学习 学习路径 课程

Grafana — 仪表盘是一个问题

副本从那天起就各自老去

在 TT Lab 中继续学习

一句话总结

每多一个对象就复制一次仪表板,副本从那天起就各自变旧。变量把这种复制变成一个下拉框,面板重复则把这个下拉框展开成多个面板。

为什么需要它

仪表板第一次被弄坏的方式,几乎总是一样的。有一个做得很好的仪表板,想看别的服务的人把它复制过去,只改了查询里的名称。一周后,原件多了一个面板;一个月后,原件的查询窗口从 [5m] 改成了 $__rate_interval。副本对这两件事一无所知。

这种状态可怕之处在于界面完好无损。副本也显示数字,图表也画得出来。只不过它回答的是与原件不同的问题,事件发生时把两个仪表板并排打开的人,会先去找这两个数字为什么不同。需要修改的地方有仪表板数量 × 面板数量那么多,这一点平时也看不见。必须遇到要修改一次查询的情况,在手工改八处的时候才会明白。

所以本模块先真正做出副本。上传四份之后,先用数字写下“要把这个查询改一次,需要改几处”,再开始。有了这个数字,才能切实感受到变量消除了什么。

工作原理

模板变量放在仪表板 JSON 的 templating.list 数组中。有手工列出值的 custom 类型,和向数据源询问的 query 类型。像对象列表这样可能增加的东西,必须用 query。手写的列表会在出现第五个对象的那天悄悄变旧。

让变量可以选择多个值的那一刻,有一件事发生了变化。要把选中了多个值的变量放进查询,必须把这些值变成一个字符串,而变成什么样,由数据源决定。官方文档写明,Prometheus 和 InfluxDB 使用正则表达式,所以会展开成 (값1|값2|값3)(占位符依次为各个选中的值),并且每个值都会做正则转义。因此查询中的匹配器也必须一起改变。label="$var" 只在只有一个值时才成立,要接收多个值,必须写成 label=~"$var"。如果不改,选一个值时一切正常,选两个值的那一刻就成了空图表。人们通常会读成“没有数据”就过去了。

全选(includeAll)还附带一个设置。把 allValue 留空,Grafana 会把所有值连接起来,生成一个很长的字符串;如果写了值(例如 .+),就会用它来代替。在对象有几百个的地方,后者要便宜得多。不过它不做转义,所以这个值在数据源中是否有效,要由人来负责。

面板重复就从这里开始。给面板设置 repeat 并指定多值变量后,Grafana 会为每个选中的值各创建一个面板。横向展开还是纵向展开(repeatDirection)、每行最多放几个(maxPerRow)也要一并确定。在重复出来的面板里,变量会被解析为该面板的那一个值,所以如果在标题里放入变量,标题就能告诉你这是哪个对象的图。

也可以让变量依赖于另一个变量。在第二个变量的查询中使用第一个变量,Grafana 就会察觉这种关联,并在前一个值改变时重新读取后一个值。这里有两点重要。一是顺序——templating.list 中靠前的变量先被解析,所以依赖别人的一方必须在后面。另一点是刷新时机——选择只在打开仪表板时重新读取,还是时间范围改变时也重新读取。如果把候选项会随时间范围变化的变量设成前一种,去看昨天的人就会看到今天的列表。

便利是要付出代价的。一个重复面板会变成选项数那么多的面板,每个面板至少会发出一个查询。如果有两个重复面板,选项分别是四个和三个,界面上就会画出七个面板,再加上固定面板就是八个。在对象有四十个的环境中,同一个仪表板会变成八十个面板。所以使用重复的仪表板,最好先确定展开后面板数量的上限,超过这个上限,就应该先加一个收窄列表的变量,或者把仪表板拆开。

最后写明在这个环境中能确认什么、不能确认什么。本实验的评分只依据仪表板 JSON 模型和实际的查询结果——变量是否已声明、类型是什么、值列表是否真的从数据源填充、面板的查询是否使用了变量、该查询是否给出值。相反,界面上究竟画出了几个面板,是无法判定的。重复是浏览器绘制仪表板时发生的事,而这个 Pod 中没有图像渲染器插件。服务器返回的仪表板 JSON 中只有重复之前的一个面板,变量的 options 数组也是空的(null)。所以选项数不是看变量声明,而必须直接向数据源询问来数。重复实际看起来如何,只能通过网页预览用眼睛确认。

在现场相遇的样子

有一个团队有十二个服务,也有十二个仪表板。出了故障,需要修改一个查询,修改的人只改了六个就下班了。下一周,另一个人看了剩下六个中的一个,判断“这里没问题”。而那是运行同一份代码的服务。

反过来,也有因为过于相信重复而出的事。有一个仪表板把 Pod 名称设为变量,并把全选作为默认值,自动扩缩容把 Pod 增加到两百个的那天,打开这个仪表板的人的浏览器卡住了。是在前面加上收窄变量列表的第二个变量(命名空间),并把默认值改成一个之后,才重新能用。重复不是免费的,而是要按选项数相乘的成本。

下一项实验要做什么

先实际上传为每个对象复制出的四份仪表板,数一数需要修改的地方有几处。接着创建一个查询变量,确认值列表是从数据中填充的,打开多选和全选之后,把查询的匹配器改成正则表达式。用面板重复让面板数量与对象数量相同,再加一个依赖该变量的第二个变量,确定顺序和刷新时机。最后数出展开后的面板数量并写下上限,把作为副本留下来的旧仪表板用一个变量合并,然后证明合并后的面板与原来的四个面板给出相同的答案。