
前面八篇把指标采集、告警规则和 Alertmanager 路由全梳理了一遍但若全配置成面板只能看见满屏的曲线和一堆意义不明的下拉框。这是可视化层面最典型的问题数据全了但信息没出来。本篇集中解决三个事——变量让面板动态起来、下钻从宏观到微观的一条路、以及统一 Dashboard一张屏看完所有层。本篇不是教 Grafana 所有功能而是提供一套经过验证的「从 Overview 到根因」的面板结构。本篇基于 Grafana 13.0.7PromQL 指标名沿用本系列第37篇变量与标签约定沿用第2篇的job/svc/type标签体系。一、变量让面板不再一把死尺没有变量的 Dashboard 是一幅静态截图。有了变量同一个面板可以根据选中的 job、svc、ip、instance 切换数据源不需要为每种组合重复建图。1、变量的类型选择Grafana 支持七种变量类型日常监控用得最多的只有三种变量类型作用典型用法Query从数据源实时查出一组值作为选项查所有 job、svc、instanceCustom手写固定选项组环境快捷切换、固定标签值Interval按时间范围自动匹配间隔给$__rate_interval或$interval传参其余类型Constant、Ad hoc filters、Data sources、Text box在监控场景下用得少Ad hoc 适合临时过滤但不可控Text box 需要用户手输——值班场景下「能选就不让输」。2、一套实用的变量体系变量之间不追求多层级联而是按维度拆平。全局变量推荐清单按选值粒度从粗到细变量名类型定义或 PromQL用途$jobQuerylabel_values(up, job)系统/应用标识最顶层筛选$svcQuerylabel_values(up{job~$job}, svc)服务标识第二层一个系统/应用一般包含多组服务$typeQuerylabel_values(up{job~$job, svc~$svc}, type)资源类型如 node / jvm / …在告警抑制中用于跨层压制见第8篇一组服务涉及多种资源$ipQuerylabel_values(up{job~$job, svc~$svc}, ip)服务器 IP一台服务器部署了多个实例时有用或同时查看一台服务器多层监控数据时有用一组服务一般涉及多台服务器$instanceQuerylabel_values(up{job~$job, svc~$svc, ip~$ip}, instance)具体实例一组服务涉及多个实例$envCustomprod, emergency一般分为生产、应急一个系统/应用可能会部署多套环境但只有一套时该变量无意义$intervalIntervalauto自适应时间窗口联动逻辑每一级变量在 PromQL 中引用了上一级的值作为过滤条件切换$job时$svc自动刷新切换$svc时$type、$ip、$instance自动刷新。# 定义 $svc 的查询语句关联 $job label_values(up{job~$job}, svc) # 定义 $type 的查询语句关联 $job、$svc label_values(up{job~$job, svc~$svc}, type) # 定义 $ip 的查询语句 label_values(up{job~$job, svc~$svc}, ip) # 定义 $instance 的查询语句关联 $job、$svc、$ip label_values(up{job~$job, svc~$svc, ip~$ip}, instance)⚠️$ip和$instance的区别在于$ip是服务器维度的筛选当一台服务器上同时跑了多个实例例如同一台机器上既跑 node_exporter 又跑 jvm exporter时用$ip可以把这台机器的主机层和 JVM 层数据同时展示出来$instance是具体实例维度的筛选只看某个单一进程或 exporter。两者不可互相替代。变量间的层级关系$job系统/应用最顶层 ├── $svc服务第二层一个 job 包含多组服务 │ ├── $type资源类型一组服务涉及多种资源 │ ├── $ip服务器 IP一组服务涉及多台服务器 │ └── $instance具体实例一组服务涉及多个实例 └── $env环境一个系统/应用可能部署多套变量体系控制在三层以内$job→$svc→ 其余同级$svc是 Dashboard 中最核心的筛选维度下钻链路中按$svc聚合、按$ip和$instance展开。3、$type在告警抑制中的关键作用抑制规则依赖type标签# 第8篇 inhibit_rules - 跨层抑制依赖 type 标签inhibit_rules:# 规则 1主机层 critical 压住同 jobsvc 的应用层 warning-source_matchers:-severity critical-type nodetarget_matchers:-severity warningequal:[job,svc]$type变量在 Dashboard 中不仅用于过滤面板数据更是值班人员通过面板上的$type能一眼看出当前的资源归属哪一层结合告警面板确认抑制链路是否按预期工作。4、变量的三个常见坑坑一label_values()与query_result()的区别label_values(up, job)直接从指标返回的标签取值速度快。query_result(count by (job) (up))会执行完整查询再提取结果慢一到两个数量级。能用label_values就别用query_result。坑二标签值不存在时面板报错当$job选了某个应用而$svc下的$type没有「node」时面板会显示空白并报No data。这不是故障但值班的人看到会慌。解法在面板的查询选项里加过滤条件或者在变量定义时增加正则排除。坑三Multi-value 开启后的曲线显示问题当变量允许多选Multi-value且面板查询中用了svc~$svc如果用户没选任何值默认会匹配全部。这个行为在小环境里没事但在有几十个服务的大环境里一次全选会让 Dashboard 加载慢到不可用。建议只对$ip和$instance开多选$job、$svc、$type保持单选。二、下钻从 Overview 到根因的一条路变量解决了「同一面板看不同对象」的问题但值班的人面对 Dashboard 时的真实操作路径常常是这样的入口面板发现「应用层错误率 5%」点进去看具体是哪个 svc 在报错再点进去看这个 svc 对应的主机资源通过$svc传递最后定位到是某台服务器的磁盘 I/O 排队了每一步都需要从一个更宏观的面板「钻进」一个更微观的面板。Grafana 里实现这个链路不靠插件只靠链接。1、三种下钻方式对比方式实现如何传递上下文适用场景Dashboard 链接在面板配置里加 Link → Dashboard手动映射变量名var-svc$svc跨 Dashboard 下钻数据链接在面板配置里加 Link → 自定义 URL 或字段提取当前数据点的标签值从曲线点到日志、追踪系统Explore 跳转面板上选「Inspect → Query → Run in Explore」自动携带 PromQL 和变量临时排查不需要长期保留日常用最多的是 Dashboard 链接从入口 Overview 跳到主机的 USE 面板跳转时把 job、svc、type、instance 带过去到目标面板后变量自动选好不用再手选一次。2、配置一个标准的 Dashboard 链接以「从总览面板点击某个 instance 跳转到主机 USE 面板」为例类型Dashboard 目标 Dashboard选择「主机 USE 面板」 在 URL 参数里添加 var-job → ${__field.labels.job} var-svc → ${__field.labels.svc} var-instance → ${__field.labels.instance} var-type → node # 固定值因为目标面板只看主机层关键在这个var-前缀Grafana 的 Dashboard 链接中var-变量名值的格式会把值自动填入目标面板的同名变量里。如果目标面板里有多个变量job、svc、type、instance链接里至少要把必需的传过去否则目标面板打开后变量是空的图也空着。⚠️注意使用 Dashboard 链接时目标面板的变量定义和源面板的标签命名必须对齐。3、下钻链路设计一张 Dashboard 里塞进所有指标不是「统一」是「堆砌」。建议按下钻深度拆成三层核心传递标识是$svc第一层服务 Overview入口一行延迟 流量 错误 饱和度黄金信号四条曲线第二行按 svc 拆开的小图阵列每个 svc 一张 RED 三图 Row变量$job、$svc、$instance下钻路径点击 instance → 跳转到对应的资源 USE 面板第二层资源 USE下钻一层CPU、内存、磁盘、网络 各一块面板变量$job、$svc、$type、$ip、$instance下钻路径点击「磁盘 I/O 高」→ 跳转到专项磁盘面板第三层专项深度下钻两层只有特定场景才需要看不在主面板中展示例如磁盘延迟分布、CPU 各核心使用率、网络重传率具体趋势变量$svc、$ip、$instance为主下钻链表示例[服务 Overview] ──点击 instance──→ [资源 USE 面板] ──点击高磁盘→ [磁盘专项面板] │ │ └──点击 instance──→ [JVM 面板] ──────┘ 如果 typejvm跳 JVM下钻链路一旦固定排查路径就是条件反射。不需要每次出故障重新想「该看哪个面板」。4、数据链接从曲线点到根因Dashboard 链接跳的是另一个 Dashboard数据链接跳的是某个数据点关联的外部系统。// Grafana 面板 → 数据链接配置示例// 链接类型自定义 URL// URL 模板https://your-jaeger.example.com/search?service$svctagsinstance%3D$instance这个链接会被渲染成点击曲线上的任意数据点 → 弹出菜单 → 一键跳转到 Jaeger 搜索页自动带上当前 svc 和 instance。前提是你已经部署了链路追踪。告警面板也可以用同样的思路从告警规则直接链到 Alertmanager 的 UI查看当前告警是否被抑制或静默。三、统一 Dashboard一张屏看完所有层有了变量和下钻下面再聊一聊 Layout 。一张合格的监控 Dashboard 不是把图全部平铺而是按层组织、按行对齐、从左到右流动。1、Row 组织原则推荐按「监控对象的层次」排 Row而不是按「指标类型」Row 1: 入口层黄金信号 —— 延迟、流量、错误、饱和度 Row 2: 应用层RED —— QPS、错误率、响应时间 Row 3: 运行时层JVM 等 —— 堆内存、GC、线程池 Row 4: 主机层USE —— CPU、内存、磁盘、网络 Row 5: 依赖层探活/外部 —— probe_success、证书过期每一行内部再按「左状态 / 中趋势 / 右下钻」来布局左侧当前时刻的 Stat 或 Gauge一眼知道「现在好不好」中间Time Series 趋势曲线看「什么时候开始变差的」右侧有需要时最近告警列表或表格布局的好处从上往下看就是一次排查路径。入口层发现延迟高 → 到应用层看哪个 svc 慢了 → 到运行时看 GC 是否频繁 → 到主机层看哪台 ip 的资源有没有打满。2、一个可复制的 Row 模板以下是第7篇的分层指标清单表对应的 Dashboard Row 骨架所有 PromQL 中的$job/$svc/$instance均由 Dashboard 面板变量传入Row 1 - 入口层黄金信号面板指标 / PromQL位置存活状态up{job~$job}左上黄金延迟histogram_quantile(0.99, sum(rate(http_server_requests_seconds_bucket[5m])) by (le))中上黄金流量sum(rate(http_server_requests_seconds_count[5m]))中黄金错误sum(rate(http_server_requests_seconds_count{status~5..}[5m])) / sum(rate(http_server_requests_seconds_count[5m])) * 100中下告警列表—右下Row 2 - 应用层RED面板指标 / PromQL位置总 QPSsum(rate(http_server_requests_seconds_count{job~$job, svc~$svc}[5m])) by (instance)左5xx 错误率sum(rate(http_server_requests_seconds_count{job~$job, svc~$svc, status~5..}[5m])) by (instance) / sum(rate(http_server_requests_seconds_count{job~$job, svc~$svc}[5m])) by (instance) * 100中平均响应时间sum(rate(http_server_requests_seconds_sum{job~$job, svc~$svc}[5m])) by (instance) / sum(rate(http_server_requests_seconds_count{job~$job, svc~$svc}[5m])) by (instance)右指标来源第4篇 Spring Boot 应用监控 / 第5篇 Nginx 监控。如果监控对象是 NginxOSS 版RED 只能做到半个只有 QPS 完整状态码和延迟需要看应用层。Row 3 - 主机层USE# CPU 使用率 100 - avg(rate(node_cpu_seconds_total{job~$job, svc~$svc, modeidle}[5m])) by (instance) * 100 # 内存使用率 (node_memory_MemTotal_bytes{job~$job, svc~$svc} - node_memory_MemAvailable_bytes{job~$job, svc~$svc}) / node_memory_MemTotal_bytes{job~$job, svc~$svc} * 100 # 磁盘空间使用率 100 - (node_filesystem_avail_bytes{job~$job, svc~$svc, fstype!~tmpfs|overlay|devtmpfs} / node_filesystem_size_bytes{job~$job, svc~$svc, fstype!~tmpfs|overlay|devtmpfs}) * 100 # 磁盘 I/O 延迟读写平均 rate(node_disk_io_time_seconds_total{job~$job, svc~$svc}[5m]) / rate(node_disk_io_time_weighted_seconds_total{job~$job, svc~$svc}[5m])主机层面板里的$type已经被 Dashboard 链接固定为node其实不固定也可以因为指标名与其他层的不一样但$svc需要保留联动。3、$env变量的处理$env只推荐在以下场景使用同一套监控系统覆盖了生产与应急emergency环境不同环境的指标需要严格隔离展示如果只有一套环境建议直接省略$env变量减少 Dashboard 加载时的额外查询。当有$env时建议在 Prometheus 的 file_sd 或 relabel 配置中增加env标签然后在 Grafana 变量定义中用label_values(up, env)拉取值。# 定义 $env 的查询语句当 env 标签存在时 label_values(up, env) # 面板 PromQL 中使用带环境过滤 sum(rate(http_server_requests_seconds_count{job~$job, svc~$svc, env~$env}[5m])) by (instance)4、时间轴同步Grafana 默认所有面板共享右上角的全局时间选择器——不要对单个面板设独立时间范围除非是在做对比。唯一可以单独设置的是$__rate_interval它由 Grafana 根据抓取间隔自动计算在 Dashboard 的 PromQL 查询里代替硬编码的[5m]# 用 $__rate_interval 代替固定 [5m] sum(rate(http_server_requests_seconds_count[$__rate_interval]))好处是如果后续在 Prometheus 端调整了scrape_intervalDashboard 不需要手动改窗口。5、导入导出与版本管理一个生产级 Dashboard 不是一次配好的会随着监控目标变更、指标增减不断调整。建议Dashboard 的 JSON 模型纳入 Git 管理每次修改后用 Grafana 的「Save → Copy JSON」导出替换// 在 Dashboard 的 description 字段里标注{description:统一监控 Dashboard v2\n依赖标签规范第2篇 Prometheus 服务发现job/svc/type 标签体系\n指标来源第3篇 node_exporter / 第4篇 Spring Boot / 第5篇 Nginx\n变量约定$job系统/应用、$svc服务、$type资源类型、$ip服务器IP、$instance具体实例\n下钻链路本面板 → 资源 USE 面板 → 磁盘专项面板}四、常见问题1、图太多Dashboard 加载慢优先用 Stat 面板代替 Time Series一张 Stat 相当于一条 Gauge加载开销一个数量级变量不超过三层减少label_values()的查询次数同一 Row 内不要放超过 4 张 Time Series 图水平滚动不解决问题考虑用 Dashboard 的「Refresh」间隔避开 1s 刷新生产环境 30s1m 完全够用2、变量下拉框里的值太多几十个 ip 或 instance 时给$ip和$instance加搜索提示变量配置里启用「Include All option」 搜索即可或者用 Ad hoc filter 代替但风险是值班的人不一定知道怎么用3、下钻跳转后目标面板空白确认目标面板的变量名和源链接中的var-参数完全一致确认目标面板里的 PromQL 使用了$svc/$type/$instance等变量使用 Debug 模式在目标面板 URL 后面加debug1查看传入的变量值是否符合预期4、$env只有一套环境时意义不大如果生产环境只有一套$env变量不产生任何实际过滤效果反而增加了 Dashboard 加载时的查询开销。建议在这种情况下直接移除$env变量用固定配置替代。五、小结监控体系的核心组件包括 Prometheus Server、Exporters、Alertmanager 和 Grafana前面把前三块全拆了一遍本篇补上可视化这一环。变量让面板不再一把死尺下钻从 Overview 到根因只有三次点击统一 Dashboard 让值班的人从上往下扫一遍就知道该看哪一层。三件事做完之后这套监控体系才真正从「指标能采到」走到了「人拿到信息就能做决策」。