Skip to content

仪表板设计 ​

仪表板是 Grafana 中组织的可视化页面,包含多个面板和配置。

仪表板结构 ​

基础结构 ​

json
{
  "title": "Application Monitoring",
  "uid": "app-monitoring",
  "tags": ["app", "monitoring"],
  "timezone": "browser",
  "schemaVersion": 38,
  "version": 1,
  "panels": [],
  "variables": [],
  "annotations": []
}

网格布局 ​

┌─────────────────────────────────────────────────────┐
│ Title: Application Monitoring Dashboard             │
├────────────┬────────────┬────────────┬─────────────┤
│ Panel 1    │ Panel 2    │ Panel 3    │ Panel 4     │
│ (QPS)      │ (Latency)  │ (Errors)   │ (Status)    │
│ 6x4        │ 6x4        │ 6x4        │ 6x4         │
├────────────┴────────────┴────────────┴─────────────┤
│ Panel 5 (Time Series - CPU/Memory)                 │
│ 24x8                                                │
├─────────────────────────────────────────────────────┤
│ Panel 6 (Table - Service Details)                  │
│ 24x6                                                │
└─────────────────────────────────────────────────────┘

gridPos 配置 ​

json
{
  "gridPos": {
    "x": 0,      // 横向位置 (0-23)
    "y": 0,      // 纵向位置
    "w": 12,     // 宽度 (1-24)
    "h": 8       // 高度
  }
}

变量系统 ​

查询变量 ​

json
{
  "name": "service",
  "type": "query",
  "datasource": {
    "type": "prometheus",
    "uid": "prometheus"
  },
  "definition": "label_values(up, job)",
  "query": {
    "query": "label_values(up, job)",
    "refId": "StandardVariableQuery"
  },
  "refresh": 1,
  "multi": true,
  "includeAll": true,
  "allValue": ".+",
  "sort": 1
}

自定义变量 ​

json
{
  "name": "interval",
  "type": "custom",
  "options": [
    {"text": "1m", "value": "1m"},
    {"text": "5m", "value": "5m"},
    {"text": "15m", "value": "15m"},
    {"text": "1h", "value": "1h"}
  ],
  "current": {
    "text": "5m",
    "value": "5m"
  }
}

文本框变量 ​

json
{
  "name": "threshold",
  "type": "textbox",
  "current": {
    "text": "80",
    "value": "80"
  }
}

常量变量 ​

json
{
  "name": "app_version",
  "type": "constant",
  "current": {
    "text": "v1.0.0",
    "value": "v1.0.0"
  }
}

变量使用 ​

promql
# 单选变量
sum(rate(http_requests_total{service="$service"}[5m]))

# 多选变量
sum(rate(http_requests_total{service=~"$service"}[5m]))

# 排除变量
sum(rate(http_requests_total{service!~"$service"}[5m]))

# 使用间隔变量
rate(http_requests_total[$interval])

# 使用阈值变量
http_requests_total > $threshold

注解 ​

添加注解 ​

json
{
  "list": [
    {
      "datasource": {
        "type": "prometheus",
        "uid": "prometheus"
      },
      "enable": true,
      "expr": "changes(deploy_event_total[1h]) > 0",
      "iconColor": "blue",
      "name": "Deployments",
      "step": "1h",
      "tagKeys": "event,type",
      "titleFormat": "{{ event }}"
    }
  ]
}

查询注解 ​

bash
# 通过 API 添加注解
curl -X POST http://admin:admin@localhost:3000/api/annotations \
  -H "Content-Type: application/json" \
  -d '{
    "dashboardId": 1,
    "time": 1612345678000,
    "timeEnd": 1612345678000,
    "tags": ["deploy", "production"],
    "text": "Deployed version v1.2.3"
  }'

仪表板链接 ​

内部链接 ​

json
{
  "links": [
    {
      "title": "Go to Infrastructure Dashboard",
      "type": "link",
      "url": "/d/infrastructure",
      "icon": "external link",
      "asDropdown": false,
      "includeVars": true,
      "keepTime": true,
      "targetBlank": false
    }
  ]
}

外部链接 ​

json
{
  "links": [
    {
      "title": "View Logs",
      "type": "link",
      "url": "http://loki:3100/logs",
      "icon": "external link",
      "asDropdown": false,
      "includeVars": true,
      "keepTime": false,
      "targetBlank": true
    }
  ]
}

仪表板配置文件 ​

provisioning 配置 ​

yaml
# /etc/grafana/provisioning/dashboards/dashboard.yml
apiVersion: 1

providers:
  - name: 'default'
    orgId: 1
    folder: ''
    folderUid: ''
    type: file
    disableDeletion: false
    updateIntervalSeconds: 30
    allowUiUpdates: true
    options:
      path: /var/lib/grafana/dashboards

仪表板 JSON 文件 ​

json
{
  "annotations": {
    "list": []
  },
  "editable": true,
  "fiscalYearStartMonth": 0,
  "graphTooltip": 1,
  "id": 1,
  "links": [],
  "liveNow": false,
  "panels": [
    {
      "type": "timeseries",
      "title": "HTTP QPS",
      "gridPos": {
        "x": 0,
        "y": 0,
        "w": 12,
        "h": 8
      },
      "targets": [
        {
          "datasource": {
            "type": "prometheus",
            "uid": "prometheus"
          },
          "expr": "sum(rate(http_requests_total[5m]))",
          "refId": "A"
        }
      ]
    }
  ],
  "refresh": "5s",
  "schemaVersion": 38,
  "tags": ["monitoring", "app"],
  "templating": {
    "list": []
  },
  "time": {
    "from": "now-1h",
    "to": "now"
  },
  "timepicker": {},
  "timezone": "browser",
  "title": "Application Monitoring",
  "uid": "app-monitoring",
  "version": 1
}

仪表板 API ​

创建仪表板 ​

bash
curl -X POST http://admin:admin@localhost:3000/api/dashboards/db \
  -H "Content-Type: application/json" \
  -d '{
    "dashboard": {
      "title": "My Dashboard",
      "uid": "my-dashboard",
      "panels": []
    },
    "overwrite": false
  }'

更新仪表板 ​

bash
curl -X PUT http://admin:admin@localhost:3000/api/dashboards/db \
  -H "Content-Type: application/json" \
  -d '{
    "dashboard": {
      "id": 1,
      "title": "Updated Dashboard",
      "uid": "my-dashboard",
      "version": 2,
      "panels": []
    },
    "overwrite": true
  }'

查询仪表板 ​

bash
# 列出所有仪表板
curl http://admin:admin@localhost:3000/api/search?type=dash-db

# 获取仪表板详情
curl http://admin:admin@localhost:3000/api/dashboards/uid/my-dashboard

# 删除仪表板
curl -X DELETE http://admin:admin@localhost:3000/api/dashboards/uid/my-dashboard

导入导出 ​

导出仪表板 ​

  1. 打开仪表板
  2. 点击 Share → Export
  3. 选择导出格式(JSON)
  4. 下载文件

导入仪表板 ​

  1. 导航到 Dashboards → Import
  2. 上传 JSON 文件或输入 ID
  3. 配置数据源映射
  4. 点击 Import

通过 API 导入 ​

bash
curl -X POST http://admin:admin@localhost:3000/api/dashboards/import \
  -H "Content-Type: application/json" \
  -d @dashboard.json

仪表板最佳实践 ​

布局原则 ​

  1. 层次结构:重要信息在顶部,细节在底部
  2. 逻辑分组:相关指标放在一起
  3. 响应式设计:考虑不同屏幕尺寸
  4. 避免拥挤:每个仪表板不超过 20 个面板

设计模式 ​

三段式布局 ​

顶部: 关键指标 (QPS, 错误率, 响应时间)
中间: 时间序列 (详细趋势图)
底部: 表格/详情 (服务列表、日志)

分组布局 ​

应用监控组: QPS, 错误率, 响应时间
资源监控组: CPU, 内存, 磁盘
网络监控组: 流量, 连接数, 延迟

变量使用 ​

yaml
# 推荐变量
variables:
  - service: 服务选择
  - instance: 实例选择
  - interval: 时间间隔
  - datasource: 数据源选择

刷新策略 ​

yaml
# 推荐刷新间隔
refresh_intervals:
  - 5s: 实时监控
  - 10s: 近实时监控
  - 30s: 一般监控
  - 1m: 离线分析
  - 5m: 趋势分析

标签使用 ​

yaml
# 推荐标签
tags:
  - app: 应用监控
  - infra: 基础设施
  - business: 业务监控
  - security: 安全监控

仪表板模板 ​

应用监控仪表板 ​

json
{
  "title": "Application Monitoring",
  "panels": [
    {
      "type": "stat",
      "title": "Total QPS",
      "gridPos": {"x": 0, "y": 0, "w": 6, "h": 4},
      "targets": [
        {"expr": "sum(rate(http_requests_total[5m]))"}
      ]
    },
    {
      "type": "stat",
      "title": "Error Rate",
      "gridPos": {"x": 6, "y": 0, "w": 6, "h": 4},
      "targets": [
        {"expr": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) / sum(rate(http_requests_total[5m])) * 100"}
      ]
    },
    {
      "type": "timeseries",
      "title": "Request Rate by Service",
      "gridPos": {"x": 0, "y": 4, "w": 24, "h": 8},
      "targets": [
        {"expr": "sum(rate(http_requests_total[5m])) by (service)", "legendFormat": "{{service}}"}
      ]
    }
  ]
}

资源监控仪表板 ​

json
{
  "title": "Infrastructure Monitoring",
  "panels": [
    {
      "type": "gauge",
      "title": "CPU Usage",
      "gridPos": {"x": 0, "y": 0, "w": 8, "h": 6},
      "targets": [
        {"expr": "100 - avg(irate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100"}
      ]
    },
    {
      "type": "gauge",
      "title": "Memory Usage",
      "gridPos": {"x": 8, "y": 0, "w": 8, "h": 6},
      "targets": [
        {"expr": "(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100"}
      ]
    },
    {
      "type": "gauge",
      "title": "Disk Usage",
      "gridPos": {"x": 16, "y": 0, "w": 8, "h": 6},
      "targets": [
        {"expr": "(node_filesystem_size_bytes - node_filesystem_free_bytes) / node_filesystem_size_bytes * 100"}
      ]
    }
  ]
}

参考:https://grafana.com/docs/grafana/latest/dashboards/