好的仪表盘不是数据的堆砌,而是问题的答案。 一个优秀的 Grafana Dashboard 应该在 5 秒内让观者理解系统状态,在 30 秒内定位到问题方向。
一、Grafana 核心概念
1.1 数据流
Grafana 架构:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Dashboard │ ←── │ Grafana │ ←── │ Data Source │
│ (Panel集合) │ │ Server │ │ (Plugin) │
└─────────────┘ └──────┬──────┘ └──────┬──────┘
│ │
┌────────┴────────┐ │
↓ ↓ │
┌──────────┐ ┌──────────┐ │
│ Prometheus│ │ Loki │ │
└──────────┘ └──────────┘ │
│
┌──────────┐ ┌──────────┐ │
│ Tempo │ │ InfluxDB │ │
└──────────┘ └──────────┘ │
│
┌──────────┐ ┌──────────┐ │
│MySQL/Post│ │Elasticsearch │
└──────────┘ └──────────┘ │
1.2 组织层级
Grafana 权限模型:
Organization
├── Users(角色:Admin / Editor / Viewer)
│
├── Folders
│ ├── Dashboard 1
│ │ ├── Panel A(Time Series)
│ │ ├── Panel B(Stat)
│ │ └── Panel C(Table)
│ │
│ └── Dashboard 2
│
└── Alert Rules
├── Notification Policies
└── Contact Points
二、仪表盘设计原则
2.1 OLAP 设计原则
OLAP = Overview(概览) → List(列表) → Afferent(关联) → Particulars(详情)
第一层:Overview — 全局健康
├── 4 大黄金信号:流量、延迟、错误、饱和度
├── 用 Stat/Gauge 展示核心 KPI
└── 时间范围:1h / 6h
第二层:List — 受影响的服务列表
├── 按错误率/延迟排序的服务表格
├── 红色 = 异常,黄色 = 警告
└── 可点击跳转到详情页面
第三层:Afferent — 关联上下文
├── Metrics + Logs + Traces 叠加
├── Annotation 标记部署/告警事件
└── 时间范围缩小到相关窗口
第四层:Particulars — 下钻详情
├── 单个服务的全维度指标
├── 该服务的日志面板
└── 该服务的追踪面板
2.2 颜色语义
| 颜色 | 含义 | 使用场景 |
|---|---|---|
| 绿色 | 正常/健康 | 成功率、健康状态 |
| 黄色 | 警告/注意 | 接近阈值、资源紧张 |
| 红色 | 异常/错误 | 错误率上升、服务不可用 |
| 蓝色 | 信息/中性 | 总量、正常流量 |
| 灰色 | 禁用/无数据 | 未启用、无指标 |
不要:用绿色表示"错误"(色盲友好设计)
2.3 信息层次
Dashboard 从上到下的信息密度递减:
┌─────────────────────────────────────────────┐
│ Row 1: KPI 关键指标(最大字号) │
│ [99.9%] [45ms] [0.01%] ┌──────────────┐│
│ 成功率 P99延迟 错误率 │ 状态灯 ││
│ │ ●●●●○ ││
├─────────────────────────────────────────────┤
│ Row 2: 趋势图(Time Series) │
│ ┌────────────────────────────────────┐ │
│ │ QPS / Error Rate / Latency over time│ │
│ └────────────────────────────────────┘ │
├─────────────────────────────────────────────┤
│ Row 3: 分布与热力图 │
│ ┌────────────┐ ┌────────────────┐ │
│ │ Top N 表格 │ │ Latency Heatmap│ │
│ └────────────┘ └────────────────┘ │
├─────────────────────────────────────────────┤
│ Row 4: 日志/追踪(按需展开) │
│ ┌────────────────────────────────────┐ │
│ │ Error Log Stream / Trace List │ │
│ └────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
三、变量与模板化
3.1 变量类型
Grafana 变量:
├── Query — 从数据源查询(如所有 job 名称)
├── Custom — 手动输入列表
├── Text box — 自由文本输入
├── Constant — 隐藏常量
├── Data source — 切换数据源
├── Interval — 时间间隔
├── Ad hoc filters — 动态标签过滤
└── Global — $__interval, $__range, $__timeFilter
# Query 变量:获取所有 namespace
Query: label_values(kube_namespace_labels, namespace)
# 级联变量:选择 namespace 后,只显示该 ns 的 pod
Query: label_values(kube_pod_container_info{namespace=~"$namespace"}, pod)
3.2 模板化 Dashboard
-- MySQL 慢查询面板(变量化)
SELECT
query,
COUNT(*) as count,
AVG(query_time) as avg_time,
MAX(query_time) as max_time
FROM mysql_slow_log
WHERE $__timeFilter(ts)
AND db = '$database' -- 变量
GROUP BY query
ORDER BY avg_time DESC
LIMIT $top_n -- 变量
四、面板类型选择
| 面板类型 | 最佳场景 | 示例 |
|---|---|---|
| Time Series | 趋势变化 | QPS、延迟、错误率随时间变化 |
| Stat | 当前值 + 变化 | 当前在线用户、今日订单数 |
| Bar Chart | 分类对比 | 各服务错误数对比 |
| Gauge | 占比/进度 | CPU 使用率、磁盘使用率 |
| Table | 详细列表 | Top 慢查询、Pod 列表 |
| Heatmap | 分布密度 | 延迟分布直方图热力图 |
| Pie Chart | 占比构成 | 错误类型占比 |
| Logs | 日志流 | Loki 日志实时输出 |
| Node Graph | 拓扑关系 | 服务调用拓扑 |
| Trace | 追踪详情 | Tempo 分布式追踪 |
| Canvas | 自定义图表 | 机房机架图、自定义拓扑 |
4.1 Time Series 面板配置
{
"type": "timeseries",
"title": "Request Rate",
"targets": [{
"expr": "sum by (job) (rate(http_requests_total[5m]))",
"legendFormat": "{{ job }}"
}],
"fieldConfig": {
"defaults": {
"unit": "reqps",
"custom": {
"drawStyle": "line",
"lineInterpolation": "linear",
"fillOpacity": 10,
"pointSize": 0
},
"thresholds": {
"steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 1000 },
{ "color": "red", "value": 5000 }
]
}
}
}
}
4.2 Heatmap 延迟分布
{
"type": "heatmap",
"title": "Request Latency Distribution",
"targets": [{
"expr": "sum by (le) (rate(http_request_duration_seconds_bucket[5m]))",
"format": "heatmap",
"legendFormat": "{{ le }}"
}],
"heatmap": {
"yAxis": {
"unit": "s",
"logBase": 2
},
"color": {
"scheme": "YlOrRd"
}
}
}
五、多数据源联动
5.1 Metrics + Logs + Traces
联动面板设计:
┌─────────────────────────────────────────────────┐
│ [Time Series] Error Rate by Service │
│ │
│ ▲ 点击 spike 处(14:32) │
│ ↓ │
│ ┌─────────────────────────────────────────────┐ │
│ │ [Logs Panel] Loki 查询自动过滤时间+服务 │ │
│ │ error="timeout" service="payment-svc" │ │
│ │ │ │
│ │ ▲ 点击日志行的 trace_id │ │
│ │ ↓ │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ [Trace Panel] Tempo 打开完整 Trace │ │ │
│ │ │ 显示从 API → Auth → Payment → DB 链路 │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
5.2 Annotation 事件叠加
# 数据源:从 Prometheus Alertmanager 或自定义 API
# Dashboard → Settings → Annotations
# 示例:标注所有部署事件
Query: ALERTS{alertname="DeploymentEvent"}
# 显示效果:
# 在时间序列图上以竖线标记部署时间点
# 鼠标悬停显示:"v1.2.3 deployed by ci@14:32"
六、Grafana Alerting
6.1 Grafana 告警 vs Alertmanager
| 维度 | Grafana Alerting | Prometheus Alertmanager |
|---|---|---|
| 数据源 | 多数据源统一 | 仅 Prometheus |
| 查询语言 | PromQL/LogQL/Flux/SQL | 仅 PromQL |
| 规则存储 | Grafana DB / 文件 | YAML 文件 |
| 分组/抑制 | 基础 | 强大 |
| 静默 | ✅ | ✅ |
| 推荐 | 混合数据源场景 | 纯 Prometheus 生态 |
6.2 Grafana Alert Rule
# provisioning/alerting/alert-rules.yaml
apiVersion: 1
groups:
- orgId: 1
name: service-health
folder: Production
interval: 60s
rules:
- uid: high-error-rate
title: High Error Rate
condition: C
data:
- refId: A
relativeTimeRange: { from: 300, to: 0 }
datasourceUid: prometheus
model:
expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
- refId: B
relativeTimeRange: { from: 0, to: 0 }
datasourceUid: __expr__
model:
type: threshold
expression: A
conditions: [{ evaluator: { type: gt, params: [0.05] } }]
- refId: C
datasourceUid: __expr__
model:
type: math
expression: $B
noDataState: NoData
execErrState: Error
for: 5m
annotations:
summary: "High error rate detected"
labels:
severity: critical
七、Loki + Tempo 面板
7.1 Loki 日志查询
# 基础查询
{app="payment-svc"} |= "error"
# 结构化解析
{app="api"}
| json
| status_code = "500"
| line_format "{{.timestamp}} {{.method}} {{.path}} {{.error}}"
# 聚合
sum by (level) (count_over_time({app="api"}[1m]))
# 与 Metrics 关联(log-to-metric)
sum(rate({app="api"} |= "error" | json [5m]))
7.2 Tempo 追踪查询
TraceQL 查询:
{resource.service.name="payment-svc"}
&& duration > 2s
&& .http.status_code = 500
在 Grafana:
Explore → Tempo → TraceQL 搜索
或使用 TraceID 直接跳转
八、权限与安全
# grafana.ini
[security]
# 禁止匿名访问
allow_embedding = false
cookie_secure = true
cookie_samesite = strict
[auth]
# SSO 集成
disable_login_form = false
oauth_auto_login = true
[auth.generic_oauth]
enabled = true
name = SSO
allow_sign_up = true
client_id = ${GF_AUTH_GENERIC_OAUTH_CLIENT_ID}
client_secret = ${GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET}
scopes = openid profile email
token_url = https://auth.example.com/oauth/token
api_url = https://auth.example.com/oauth/userinfo
九、Grafana Checklist
| 检查项 | 说明 |
|---|---|
| 每 Dashboard 聚焦一个主题 | 不要混搭不相关的指标 |
| 变量模板化 | 支持环境/服务/时间范围切换 |
| 链接下钻 | 从概览到详情的连接 |
| 注释事件 | 部署、告警事件叠加 |
| 阈值颜色 | 语义一致(绿黄红) |
| 刷新策略 | 实时面板 5s,历史面板 30s-1m |
| 权限隔离 | 生产环境只读,开发环境可编辑 |
| 版本管理 | Dashboard JSON 存入 Git |
参考与延伸阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。