Grafana 使用
Grafana 是一款用 GO 语言开发的开源数据可视化工具,可以做数据监控和数据统计,带有告警功能。
基础概念
组织(Organization) 与用户(User)
Organization 相当于一个 Namespace,一个 Organization 完全独立于另一个 Organization,包括 datasource
、dashboard
等,创建一个 Organization 就相当于打开了一个全新的视图,所有的 datasource
、dashboard
等都需要重新创建。一个用户(User) 可以属于多个 Organization。
User 是 Grafana 里面的用户,用户可以有以下 角色
admin
- 管理员权限,可以执行任何操作。editor
- p不可以创建用户、不可以新增Datasource
、可以创建 Dashboard**viewer
- 仅可以查看 Dashboardread only editor
- 允许用户修改 Dashboard,但是 不允许保存
数据源 Datasource
Grafana 中操作的数据集、可视化数据的来源
Dashboard
在 Dashboard 页面中,可以组织可视化数据图表。
Panel
- 在一个 Dashboard 中,Panel 是最基本的可视化单元。通过 Panel 的Query Editor
可以为每一个 Panel 添加查询的数据源以及数据查询方式。每一个 Panel 都是独立的,可以选择一种或者多种数据源进行查询。一个 Panel 中可以有多个Query Editor
来汇聚多个可视化数据集Row
- 在 Dashboard 中,可以定义一个Row
,来组织和管理一组相关的Panel
Variables
在 Dashboard 的设置页面中,有 Variables
页面,在其中可以为 Dashboard 配置变量,之后可以在 Panel 的 Query Editor
中使用这些预定义的变量。变量的值也可以是通过表达式获取的值。也可以在 Panel 的标题中使用变量
例如以下 Variables 配置
Node label_values(kubernetes_io_hostname) |
在 Dashboard 中定义了这些变量后,可以在 Panel 的 Query Editor
中使用,在 Query Editor
中使用了 Variables 中定义的变量后,在 Dashboard 的顶部下拉菜单中可以选择预定义的变量的值(需要在定义 Variables 时配置 Show on dashboard
为 Label and Value
以使在 Dashboard 顶部显示下拉菜单),Panel 中的 Query
表达式就会使用这些变量的值进行计算以及显示图表。
变量关联查询
有时候需要在一个变量中使用另一个变量的值来筛选结果。例如以下场景:
假如有 2 个 k8s 集群,第一个 k8s 集群名为
k8s-cluster1
,其中有 3 个节点:k8s-cluster1-1
,k8s-cluster1-2
,k8s-cluster1-3
,第二个 k8s 集群名为
k8s-cluster2
, 其中有 3 个节点:k8s-cluster2-1
,k8s-cluster2-2
,k8s-cluster2-3
,从
k8s-cluster1
集群采集的指标都有cluster=k8s-cluster1
的标签,从
k8s-cluster2
集群采集的指标都有cluster=k8s-cluster2
的标签,grafana 中定义变量
cluster
,其值是cluster
标签的值,如何定义变量
node
,其值根据cluster
变量来决定,例如当cluster
的值是k8s-cluster1
时,node
的值只能选择k8s-cluster1-1
,k8s-cluster1-2
,k8s-cluster1-3
,当
cluster
的值是k8s-cluster2
时,node
的值只能选择k8s-cluster2-1
,k8s-cluster2-2
,k8s-cluster2-3
,
要实现以上需求,可以使用如下的表达式定义 node
变量
- 添加 Variables,
variable type
选择Query
Data source
选择对应的 PrometheusQuery
中选择Query Type
为Label values
,Label *
选择kubernetes_io_hostname
,后面的Metric
中配置表达式up{cluster=~"$cluster"}
以限制筛选结果这里的 主要配置为
Metric
中配置表达式up{cluster=~"$cluster"}
,用来限制Label values
是从up{cluster=~"$cluster"}
的结果中筛选值
对应的 Variables Definition 为 label_values(up{cluster_name=~"$k8sClusterName"},kubernetes_io_hostname)
常用配置示例
Gauge 类型
Gauge 类型的数据是一个标量值,代表了当前的值。
选择图标显示的数据格式
例如要配置百分比类型的图标,可以在 Panel
配置中的 Standard options
中选择 Unit
为 Misc
-> Percent(0-100)
配置 Gauge 图标显示渐变色
要配置 Gauge 仪表盘的渐变色,可以在 Panel
配置中的 Thresholds
中添加渐变颜色
要使 Gauge 仪表盘内部显示度量值,需要配置 Standard options
–> Min
、Standard options
–> Max
、 Standard options
–> Decimals
Time series
自定义图形的 Legend
默认情况下,Legend 会显示指标中的所有标签,会比较长,为了缩短简化 Legend,需要自定义 Legend。在 图形的编辑界面,表达式下的 Options 中,选择 Legend
进行自定义,可以使用已有的标签 {{label}}
,或者 Variables $variable
来格式化 Lengend
下图为默认的 Legend
下图为为自定义后的 Legend
Grafana 展示 Zabbix 监控数据
安装 Zabbix 插件
在 Grafana 的 Administration
–> Plugins
中搜索 Zabbix
插件并 install
。安装后在插件中找到 Zabbix
插件并 Enable
添加 Data source
直接使用 Zabbix 的 API 性能较差,建议让 Zabbix 的 Data Source 直连 Zabbix 数据库。
首先要添加一个 Mysql 的数据源(此处示例 Zabbix 数据库为 Mysql)
Mysql 配置成功后,选择
Zabbix
添加为 Data Source,使用 Zabbix 的 API 链接及认证用户名和密码配置 Data source,配置Direct DB Connection
为Enable
并选择数据库为第一步配置的 Mysql Data source
常用查询
因为 Grafana 直连了 Zabbix 数据库,有些查询可以直接查询 Zabbix 的 Mysql 数据库
Zabbix 监控的主机数量
SQL : SELECT COUNT(*) AS host_count FROM hosts;
使用 Prometheus 数据源展示 Kubernetes 中 Ingress Nginx Controller 监控数据
Prometheus 监控 Kubernetes 中 Ingress Nginx Controller 指标配置参考.
在 Grafana Dashboard 中配置以下 Variables
k8sClusterName label_values(cluster_name)
k8sNamespace label_values(kube_namespace_labels{cluster_name=~"$k8sClusterName"},namespace)
Ingress label_values(kube_ingress_info{cluster_name=~"${k8sClusterName}", namespace=~"${k8sNamespace}"},ingress)
Host label_values(kube_ingress_path{cluster_name=~"$k8sClusterName",namespace=~"$k8sNamespace",ingress=~"$Ingress"},host)
Ingress Nginx Controller 发送的数据总和
使用表达式: sum(rate(nginx_ingress_controller_bytes_sent_sum{cluster_name=~"$k8sClusterName", namespace=~"$k8sNamespace", ingress=~"$Ingress",host=~"$Host"}[2m]))
Ingress Nginx Controller 各个实例的连接数
sum by (instance)(rate(nginx_ingress_controller_nginx_process_connections{cluster_name=~"$k8sClusterName"}[2m]))
Ingress Nginx Controller 请求成功率
sum(rate(nginx_ingress_controller_requests{cluster_name=~"$k8sClusterName",ingress=~"$Ingress",namespace=~"$k8sNamespace",status!~"[4-5].*"}[2m])) / sum(rate(nginx_ingress_controller_requests{cluster_name=~"$k8sClusterName",ingress=~"$Ingress",namespace=~"$k8sNamespace"}[2m]))
Ingress Nginx Controller 请求持续时间
计算平均请求持续时间:sum by (namespace, ingress) (nginx_ingress_controller_request_duration_seconds_sum) / sum by (namespace, ingress) (nginx_ingress_controller_request_duration_seconds_count)
计算平均上游占用时间:sum by (namespace, ingress) (nginx_ingress_controller_ingress_upstream_latency_seconds_sum) / sum by (namespace, ingress) (nginx_ingress_controller_ingress_upstream_latency_seconds_count)
Grafana Alerting and Notification Policies
Grafana Notification Template 语法总结
- 使用版本 Grafana v10.4.1
Grafana 集成的 Alert Rule 和 Notification Policies 在发送告警时一般是以 Group 的形式发送告警信息。 [1]
.Alerts
告警和恢复消息存放在 .Alerts
中,为 切片(slice)
类型
.Alerts.Firing
- 存放了告警消息对象.Alerts.Resolved
- 存放了告警恢复消息对象
以下语句打印出所有的告警及其标签,标签以 ,
分割: [2]
{{ range .Alerts }} |
参考以下语句打印出所有的告警以及对应实例的标签,标签按行分割 [2]
{{ range .Alerts }} |
参考以下语句可以获取到告警列表中指定的 Labels 或者 Annotations 的所有值 [2]
{{ range .Alerts }} |
参考以下语句获取告警消息的数量
{{ len .Alerts }} |
使用以下语句获取告警及恢复告警的时间
UTC 时间 |
如果 启用了 Grafana Image Renderer Plugin,在告警消息模板中使用变量 {{ .ImageURL }}
引用图片。
Grafana 告警中发送图片
版本信息:
- Grafana v11.2
为了在告警中直观的展示告警发生时的监控项的图形,Grafana 支持在告警中发送 Panel 对应的图片(PNG 图片)。当告警产生时,Grafana 会生成对应的临时 PNG 图片并保存在文件系统中($GRAFANA_DATA_DIR/data/png/
),后台定时任务每隔 10 分钟会删除这些临时图片。要自定义多久删除这些临时图片,可以通过修改配置 temp_data_lifetime
实现 [3]
此功能由 Grafana Image Renderer plugin
实现,使用之前需要先 安装
grafana-cli plugins install grafana-image-renderer |
插件将会安装到 Grafana 插件目录,默认为 /var/lib/grafana/plugins
在 Docker Compose 部署的 Prometheus 和 Grafana 的基础上配置 Grafana Image Renderer
[4]
version: "3" |
./config/grafana_image_renderer/config.json
文件内容参考官网示例
- 要自定义图片中显示的时区,可以修改
timezone
选项,如Asia/Shanghai
Grafana Image Renderer plugin
配置选项说明
Grafana Image Renderer plugin
会比较消耗内存,因为其工作机制为在后台启动浏览器实例进行图片获取。
配置完成后,重启 grafana
,可以通过 clicking Panel > Share > Direct link rendered image in the Link tab.
来测试是否正常。
要支持在告警中发送图片,需要在 Grafana 配置中启用以下配置,并且不同告警通道对 Image Renderer 的支持情况也不不同,具体可参考官网说明 [5]
[unified_alerting.screenshots] |
在告警消息模板中,可以通过变量 {{ .ImageURL }}
引用图片链接。相关限制参考官网说明 [5]
常见错误
部署 Grafana Image Renderer plugin 后生成的图像空白
在部署 Grafana Image Renderer plugin 后,通过点击 Panel 的 Share > Direct link rendered image
测试,显示生成的图片空白。检查 Grafana Image Renderer
的容器日志,报错如下:
grafana_image_renderer-1 | {"failure":"net::ERR_CONNECTION_REFUSED","level":"error","message":"Browser request failed","method":"GET","url":"http://grafana:3000/d-solo/bduz8o5q2tcsgc/cdn-domains-traffic-data?orgId=1&from=1725247462795&to=1725269062795&panelId=1&width=1000&height=500&scale=1&tz=Asia%2FShanghai&render=1"} |
错误原因 :
根据错误提示,是因为 grafana_image_renderer
无法连通 http://grafana:3000
,测试发现的确如此,因主机防火墙限制,防火墙放通限制即可
常见错误
Grafana 集成的 Telegram 发送消息失败
- Grafana v10.4.1
Grafana 配置 Contact points
,Integration
选择 Telegram
,Parse Mode
选择 HTML
,使用以下模板发送消息失败 Failed to send test alert.: failed to send telegram message: webhook response status 400 Bad Request
{{ define "MyNotificationTemplate" }} |
修改为以下内容后(去掉 html
和 body
标签),可以正常发送消息
{{ define "MyNotificationTemplate" }} |
经测试,在 Grafana notification template
中使用 HTML
格式发送消息到 Telegram,不能使用以下标签,否则报错: Failed to send test alert.: failed to send telegram message: webhook response status 400 Bad Request
html
body
br
p
支持以下标签:
<b>粗体</b>
<i>斜体</i>
<u>下划线</u>
<s>删除线</s>
常见问题
Dashboard 顶部的选择下拉单初始值无法固定
使用 Variables 后,Dashboard 顶部的选择下拉单中想让初始值为 All
(假设所有变量都有 All 选项),在 Dashboard 选择所有的下拉选项选择 All
,然后保存 Dashboard。重新刷新页面或者重新登陆后,很多下拉选项都不是保存是设置的 All
选项。
要解决此问题,参考以下方法:
- 在 Dashboard 选择所有的下拉选项选择
All
- 点击
Dashboard settings
,在设置页面中选择JSON Model
,点击左下角的Save changes
。重新刷新或者重新登陆后,Dashboard 顶部的选择下拉选项默认值都为All
Grafana Table 中对字段排序
Grafana 中的 Table 类型的数据,默认的列顺序是和查询语句返回的顺序一致,像 Prometheus 返回的列不支持通过 ProQL 调整结果中标签的顺序,此种情况下要在 Grafana Table 中调整列的排列顺序,需要使用 Grafana 提供的 Transform data
功能,具体操作步骤如下:
- 在
Transform data
标签页中点击Add transformation
。 - 在弹出的子页面中找到或者搜索
Organize fields by name
。 - 在页面中拖动调整字段的顺序,即可完成调整 Table 中列顺序的目的。
Grafana Table 中组合多个查询到同一个 Table 中
若需要将多个查询表的内容整合到一个表中,参考以下思路:
- 首先确保每个查询得到想要的数据
- 在
Transform data
标签页中点击Add transformation
。 - 在弹出的子页面中找到或者搜索
Merge series/tables
。 - 多个表的内容会被合并到一张表中,如果多张表中的字段名重复,会自动合并成一个字段。若要修改字段名和属性,可以使用
overrides
功能。
Grafana 统一告警发送的通知中时区修改为东八区
Grafana 统一告警发送的通知中时区固定为 UTC 时间,要修改为东八区,参考以下模板((.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05"
)将时间改为东八区时间并指定时间显示的格式:
{{ define "MyNotificationTemplate" }} |