前言

Grafana 是一个开源的数据可视化和监控平台,支持多种数据源(Prometheus、InfluxDB、MySQL 等),可以通过仪表盘(Dashboard)对指标数据进行实时展示和告警。

记录使用 Grafana + InfluxDB + Telegraf 搭建服务器监控系统

项目结构

服务关联图(添加了有其他数据源的示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌─────────────────────────────────────────────────────────────┐
│ Ubuntu 服务器 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Telegraf │──▶│ InfluxDB │───▶│ Grafana │ │
│ │ (采集自身+ │ │ (时序存储) │ │ (大屏展示) │ │
│ │ 接收Win数据) │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ▲ │
└─────────┼───────────────────────────────────────────────────┘
│ HTTP API (通过 InfluxDB 写入)

┌─────────┴─────────────────────────────────────────────────────┐
│ Windows 机器 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Telegraf (采集CPU/内存/磁盘/网络,直接写入InfluxDB) │ │
│ └──────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
monitor-lab/
├── docker-compose.yml
├── influxdb/
│ └── init-scripts/
│ └── retention-policy.iql
├── grafana/
│ └── provisioning/
│ ├── datasources/
│ │ └── influxdb.yml
│ └── dashboards/
│ ├── dashboards.yml
│ └── system.json
└── telegraf/
└── telegraf.conf

部署

创建目录

1
2
mkdir -p monitor-lab/{influxdb/init-scripts,grafana/provisioning/{datasources,dashboards},telegraf}
cd monitor-lab

配置文件

  1. .env
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# ================================================================
# 生产环境变量配置文件
# ⚠️ 重要:此文件包含敏感信息,务必加入 .gitignore,不要提交到代码仓库!
# ================================================================

# ---------- 时区 ----------
# 设置容器的时区,影响日志时间和数据时间戳
# 中国标准时间 = Asia/Shanghai
TZ=Asia/Shanghai

# ---------- InfluxDB 认证信息 ----------
# 管理员用户名 - 用于登录InfluxDB UI和执行管理操作
# 生产环境建议使用复杂且唯一的用户名
INFLUXDB_ADMIN_USER=prod_admin

# 管理员密码 - 必须使用高强度密码!
# 要求:至少12位,包含大小写字母、数字、特殊字符
INFLUXDB_ADMIN_PASSWORD=YourStrongP@ssw0rd_2026!

# 组织名称 - InfluxDB 2.x 中的组织概念,用于资源隔离
# 可以理解为一个租户或项目分组
INFLUXDB_ORG=myorg

# 存储桶名称 - 类似数据库中的"表",用于存放时序数据
# 所有监控数据都会写入这个存储桶
INFLUXDB_BUCKET=telegraf

# ---------- Grafana 认证信息 ----------
# Grafana 管理员用户名
GF_SECURITY_ADMIN_USER=admin

# Grafana 管理员密码 - 同样需要高强度密码
GF_SECURITY_ADMIN_PASSWORD=Grafana@Prod#2026

# ---------- 数据生命周期 ----------
# 数据保留天数:超过此天数的原始数据将被自动删除
# 权衡:保留越长,查询历史趋势越远,但存储成本越高
# 生产环境建议 30-90 天,可根据业务需要调整
RETENTION_DAYS=30
  1. docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# ================================================================
# Docker Compose 配置文件 - 生产环境设备监控系统
# 版本 3.8 支持 deploy.resources 等生产级特性
# ================================================================
version: '3.8'

# ---------- 自定义网络 ----------
# 创建专属网络,让容器之间通过容器名(如 influxdb)互相访问
# 好处:不依赖宿主机IP,容器重启后IP变化也不影响通信
networks:
monitor-net:
# 网络名称,在宿主机上执行 docker network ls 可见
name: monitor-net
# bridge 是默认网络驱动,适合单机部署
driver: bridge
# 生产环境可配置 MTU(最大传输单元),避免网络包过大导致的问题
# 如果网络环境有特殊要求(如VPN、隧道),可以调整此值
# driver_opts:
# com.docker.network.driver.mtu: 1450

# ---------- 服务定义 ----------
services:

# =============================================================
# 服务1: InfluxDB - 时序数据库
# 职责:存储所有监控指标数据,提供查询API
# =============================================================
influxdb:
# 使用官方 2.7 版本镜像,稳定且长期支持
image: influxdb:2.7
# 容器名称,便于 docker ps 和 docker logs 识别
container_name: influxdb
# 容器内部主机名,其他容器可通过此名称访问
hostname: influxdb
# 加入自定义网络
networks:
- monitor-net
# ---------- 端口映射 ----------
ports:
# 格式:宿主机IP:宿主机端口:容器端口
# "127.0.0.1:8086:8086" 表示只监听本机回环地址
# ⚠️ 生产环境不直接暴露端口,通过 Nginx 反向代理对外提供服务
# 好处:① 防止外部直接攻击数据库 ② 统一入口便于管理TLS证书
- 8086:8086
# ---------- 数据卷挂载 ----------
volumes:
# 命名卷:存放InfluxDB数据文件
# 使用命名卷而非直接挂载目录的原因:
# ① Docker自动管理权限,不会出现 Permission Denied
# ② 数据与代码分离,项目目录保持整洁
# ③ 便于备份和迁移(docker volume 命令统一管理)
- influxdb-storage:/var/lib/influxdb2

# 绑定挂载:初始化脚本目录(只读)
# 容器启动时会自动执行此目录下的脚本
# :ro 表示只读,防止容器意外修改宿主机文件
- ./influxdb/init-scripts:/docker-entrypoint-initdb.d:ro
# ---------- 环境变量 ----------
environment:
# 启用初始化模式(必须设置为 setup)
- DOCKER_INFLUXDB_INIT_MODE=setup
# 管理员用户名(必须与 .env 中的 INFLUXDB_ADMIN_USER 一致)
- DOCKER_INFLUXDB_INIT_USERNAME=prod_admin
# 管理员密码(必须与 .env 中的 INFLUXDB_ADMIN_PASSWORD 一致)
- DOCKER_INFLUXDB_INIT_PASSWORD=YourStrongP@ssw0rd_2026!
# 组织名称(必须与 .env 中的 INFLUXDB_ORG 一致)
- DOCKER_INFLUXDB_INIT_ORG=myorg
# 存储桶名称(必须与 .env 中的 INFLUXDB_BUCKET 一致)
- DOCKER_INFLUXDB_INIT_BUCKET=telegraf
# 数据保留策略:30天 = 720小时
- DOCKER_INFLUXDB_INIT_RETENTION=720h
# 管理员 Token(格式:用户名:密码,Grafana 将使用此 Token 连接)
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=prod_admin:YourStrongP@ssw0rd_2026!

# 从 .env 文件读取,避免硬编码
- INFLUXDB_DB=telegraf
- INFLUXDB_ADMIN_USER=prod_admin
- INFLUXDB_ADMIN_PASSWORD=YourStrongP@ssw0rd_2026!
# 启用HTTP认证,所有请求都需要携带Token
- INFLUXDB_HTTP_AUTH_ENABLED=true
- TZ=${TZ}
# ---------- 重启策略 ----------
restart: unless-stopped
# unless-stopped 含义:除非手动停止,否则始终自动重启
# 适用场景:宿主机重启、容器崩溃等情况
# ---------- 资源限制 ----------
deploy:
resources:
limits:
# CPU限制:最多使用2个核心
# 防止容器占用过多CPU导致宿主机卡顿
cpus: '2.0'
# 内存限制:最多使用2GB
# 超出限制会被内核OOM Killer杀死,然后由restart策略重启
memory: 2G
reservations:
# 资源预留:保证至少有0.5核和512MB可用
# 调度器会优先保证预留资源
cpus: '0.5'
memory: 512M
# ---------- 健康检查 ----------
healthcheck:
# 测试命令:curl访问 /health 端点,返回200表示健康
test: ["CMD", "curl", "-f", "http://localhost:8086/health"]
# 每30秒检查一次
interval: 30s
# 单次检查超时时间
timeout: 5s
# 连续失败3次才标记为 unhealthy
retries: 3
# 启动后等待30秒才开始检查(给服务启动留足时间)
start_period: 30s
# ---------- 日志配置 ----------
logging:
# 使用JSON File驱动,将日志写入宿主机文件
driver: "json-file"
options:
# 单个日志文件最大50MB
max-size: "50m"
# 最多保留3个文件(总日志量 ≤ 150MB)
# 防止日志无限增长撑爆磁盘
max-file: "3"

# =============================================================
# 服务2: Grafana - 可视化大屏
# 职责:提供Web界面,展示监控数据,配置告警
# =============================================================
grafana:
# 使用企业版镜像,包含更多功能和插件支持
image: grafana/grafana-enterprise:latest
container_name: grafana
hostname: grafana
networks:
- monitor-net
ports:
# 同样只监听本地,通过Nginx代理对外
- 3000:3000
volumes:
# 绑定挂载:provisioning目录(只读)
# 包含数据源和仪表盘的自动配置
# 好处:配置即代码,便于版本控制和批量部署
- ./grafana/provisioning:/etc/grafana/provisioning:ro

# 命名卷:存放Grafana配置数据库(SQLite)、插件、用户数据
# 所有仪表盘配置、数据源配置、用户信息都在此
# 备份此卷即可完整恢复Grafana
- grafana-storage:/var/lib/grafana
environment:
# ---------- 认证配置 ----------
- GF_SECURITY_ADMIN_USER=${GF_SECURITY_ADMIN_USER}
- GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD}

# ---------- 服务器配置 ----------
# 根URL:必须设置正确的域名,否则回调地址可能出错
#- GF_SERVER_ROOT_URL=https://monitor.yourcompany.com
# 强制匹配域名,防止Host头攻击
#- GF_SERVER_ENFORCE_DOMAIN=true

# ---------- 安全配置 ----------
# 禁用登录表单(如使用OAuth可开启)
- GF_AUTH_DISABLE_LOGIN_FORM=false
# 禁用匿名访问(生产环境必须关闭)
- GF_AUTH_ANONYMOUS_ENABLED=false

# ---------- 插件 ----------
# 启动时自动安装额外插件
# 时钟面板:显示美观的时钟
# JSON数据源:支持从HTTP API读取数据
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource

- TZ=${TZ}
restart: unless-stopped
# ---------- 依赖关系 ----------
depends_on:
influxdb:
# condition: service_healthy 表示等待 InfluxDB 健康后才启动
# 比默认的 depends_on 更可靠,确保数据源就绪
condition: service_healthy
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.25'
memory: 256M
healthcheck:
# Grafana 的健康检查端点
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"

# =============================================================
# 服务3: Telegraf - Ubuntu本机数据采集
# 职责:采集宿主机的CPU、内存、磁盘、网络等系统指标
# =============================================================
telegraf-ubuntu:
image: telegraf:latest
container_name: telegraf-ubuntu
# 设置主机名,作为数据标签(tag)的一部分
# 在Grafana中可以用 host="ubuntu-server" 筛选数据
hostname: ubuntu-server
networks:
- monitor-net
# ---------- 特权挂载 ----------
volumes:
# 配置文件挂载(只读)
- ./telegraf/telegraf-ubuntu.conf:/etc/telegraf/telegraf.conf:ro

# 挂载Docker套接字,用于采集容器指标
# :ro 表示只读,安全考虑不授予写入权限
- /var/run/docker.sock:/var/run/docker.sock:ro

# 挂载宿主机的 /proc 文件系统,获取进程和系统信息
# /proc 是Linux内核提供的虚拟文件系统,包含运行时信息
- /proc:/host/proc:ro

# 挂载 /sys 文件系统,获取硬件和设备信息
- /sys:/host/sys:ro

# 挂载根文件系统,用于磁盘使用率统计
- /:/host:ro
# ---------- 环境变量 ----------
environment:
# Telegraf 默认读取 /proc,但容器内需要指向宿主机的挂载点
- HOST_PROC=/host/proc
- HOST_SYS=/host/sys
- HOST_ROOT=/host
- TZ=${TZ}
restart: unless-stopped
depends_on:
influxdb:
condition: service_healthy
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.1'
memory: 64M
logging:
driver: "json-file"
options:
max-size: "20m"
max-file: "2"

# ================================================================
# 数据卷声明
# 所有命名卷必须在这里显式声明
# ================================================================
volumes:
# InfluxDB 数据卷
influxdb-storage:
# 指定卷名称,不指定则自动生成随机名称
name: influxdb-storage
# 生产环境可配置外部存储驱动(如NFS、云存储)
# 便于多机共享数据或迁移
# driver_opts:
# type: nfs
# o: addr=192.168.1.100,rw,noatime
# device: :/exports/influxdb

# Grafana 数据卷
grafana-storage:
name: grafana-storage

  1. telegraf/telegraf-ubuntu.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# ================================================================
# Telegraf 配置文件 - Ubuntu 系统指标采集
# ================================================================

[global_tags]
host = "ubuntu-server"
env = "production"

[agent]
interval = "30s"
flush_interval = "30s"
metric_batch_size = 5000
metric_buffer_limit = 50000
collection_jitter = "0s"

# ===== 输出到 InfluxDB =====
[[outputs.influxdb_v2]]
urls = ["http://influxdb:8086"]
token = "prod_admin:YourStrongP@ssw0rd_2026!"
organization = "myorg"
bucket = "telegraf"
content_encoding = "gzip"

# ===== CPU =====
[[inputs.cpu]]
percpu = false
totalcpu = true
fieldpass = ["usage_user", "usage_system", "usage_idle"]

# ===== 内存 =====
[[inputs.mem]]
fieldpass = ["used_percent", "available", "used", "total"]

# ===== 磁盘 =====
[[inputs.disk]]
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]
fieldpass = ["used_percent", "free", "total"]

# ===== 磁盘 I/O =====
[[inputs.diskio]]
fieldpass = ["read_bytes", "write_bytes", "read_time", "write_time"]

# ===== 网络 =====
[[inputs.net]]
interfaces = ["eth0", "ens*", "enp*", "bond*"]
fieldpass = ["bytes_sent", "bytes_recv", "packets_sent", "packets_recv"]

# ===== 系统负载 =====
[[inputs.system]]
fieldpass = ["load1", "load5", "load15"]

# ===== 进程 =====
[[inputs.processes]]
fieldpass = ["total", "running", "sleeping", "zombies"]
  1. grafana/provisioning/datasources/influxdb.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# ================================================================
# Grafana 数据源自动配置
# 容器启动时自动加载,无需手动配置
# ================================================================

apiVersion: 1

datasources:
# 数据源名称,在Grafana UI中显示
- name: InfluxDB
# 数据源类型
type: influxdb
# 访问方式:proxy 表示通过Grafana后端代理请求
# 优点:避免跨域问题,统一认证
access: proxy
# InfluxDB 服务地址(容器内访问)
url: http://influxdb:8086
# 数据库名称(兼容1.x语法)
database: telegraf
# 设为默认数据源,新建面板时自动选中
isDefault: true
# 敏感信息(加密存储)
secureJsonData:
# InfluxDB 2.x 使用Token认证
token: ${INFLUXDB_ADMIN_USER}:${INFLUXDB_ADMIN_PASSWORD}
# 常规配置
jsonData:
# 使用Flux查询语言(InfluxDB 2.x推荐)
version: Flux
# 组织名称
organization: myorg
# 默认存储桶
defaultBucket: telegraf
# HTTP方法
httpMode: POST
  1. grafana/provisioning/dashboards/dashboards.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# ================================================================
# Grafana 仪表盘自动加载配置
# 将 JSON 格式的仪表盘文件自动导入
# ================================================================

apiVersion: 1

providers:
# 提供者名称,可配置多个
- name: 'default'
# 所属组织ID(默认1)
orgId: 1
# 文件夹名称(在Grafana中分类)
folder: ''
# 提供者类型:file 表示从文件系统读取
type: file
# 是否允许更新已存在的仪表盘
# true 表示如果仪表盘ID相同,会覆盖更新
allowUiUpdates: true
options:
# 仪表盘JSON文件存放路径(容器内路径)
path: /etc/grafana/provisioning/dashboards

快速启动命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1. 进入项目目录
cd ~/monitor-lab

2. 后台启动所有服务
docker compose up -d

3. 查看运行状态
docker compose ps

4. 查看实时日志
docker compose logs -f

5. 停止所有服务
docker compose down

6. 重启所有服务
docker compose restart

7. 重启指定服务
docker compose restart influxdb
docker compose restart grafana
docker compose restart telegraf-ubuntu

Grafana 监控

访问 Grafana 监控界面

1
http://localhost:3000

grafana 仪表盘json导入

可获得的模板社区链接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
{
"title": "Ubuntu 系统监控",
"uid": "ubuntu-system-monitor",
"tags": ["ubuntu", "system", "telegraf", "production"],
"timezone": "browser",
"schemaVersion": 36,
"version": 0,
"refresh": "30s",
"panels": [
{
"id": 1,
"title": "CPU 使用率",
"type": "timeseries",
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 0},
"targets": [
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"cpu\" and r._field == \"usage_user\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"用户态使用率\" })) |> yield(name: \"用户态使用率\")",
"refId": "A"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"cpu\" and r._field == \"usage_system\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"系统态使用率\" })) |> yield(name: \"系统态使用率\")",
"refId": "B"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"cpu\" and r._field == \"usage_idle\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"空闲率\" })) |> yield(name: \"空闲率\")",
"refId": "C"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"cpu\" and r._field == \"usage_iowait\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"I/O 等待\" })) |> yield(name: \"I/O 等待\")",
"refId": "D"
}
],
"options": {
"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max", "last"]},
"tooltip": {"mode": "multi", "sort": "desc"}
},
"fieldConfig": {
"defaults": {
"unit": "percent",
"max": 100,
"min": 0,
"color": {"mode": "palette-classic"},
"custom": {"lineWidth": 2, "fillOpacity": 20, "drawStyle": "line", "lineInterpolation": "smooth"}
},
"overrides": [
{"matcher": {"id": "byName", "options": "空闲率"}, "properties": [{"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "用户态使用率"}, "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "系统态使用率"}, "properties": [{"id": "color", "value": {"fixedColor": "red", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "I/O 等待"}, "properties": [{"id": "color", "value": {"fixedColor": "orange", "mode": "fixed"}}]}
]
}
},
{
"id": 2,
"title": "内存使用率",
"type": "timeseries",
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 0},
"targets": [
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"mem\" and r._field == \"used_percent\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"已用百分比\" })) |> yield(name: \"已用百分比\")",
"refId": "A"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"mem\" and r._field == \"available\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"可用内存\" })) |> yield(name: \"可用内存\")",
"refId": "B"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"mem\" and r._field == \"used\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"已用内存\" })) |> yield(name: \"已用内存\")",
"refId": "C"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"mem\" and r._field == \"total\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"总内存\" })) |> yield(name: \"总内存\")",
"refId": "D"
}
],
"options": {
"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max", "last"]},
"tooltip": {"mode": "multi"}
},
"fieldConfig": {
"defaults": {
"unit": "percent",
"max": 100,
"min": 0,
"color": {"mode": "palette-classic"},
"custom": {"lineWidth": 2, "fillOpacity": 20, "drawStyle": "line", "lineInterpolation": "smooth"}
},
"overrides": [
{"matcher": {"id": "byName", "options": "可用内存"}, "properties": [{"id": "unit", "value": "bytes"}, {"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "已用内存"}, "properties": [{"id": "unit", "value": "bytes"}, {"id": "color", "value": {"fixedColor": "orange", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "总内存"}, "properties": [{"id": "unit", "value": "bytes"}, {"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "已用百分比"}, "properties": [{"id": "color", "value": {"fixedColor": "red", "mode": "fixed"}}]}
]
}
},
{
"id": 3,
"title": "磁盘使用率",
"type": "timeseries",
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 8},
"targets": [
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"disk\" and r._field == \"used_percent\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"磁盘使用率\" })) |> yield(name: \"磁盘使用率\")",
"refId": "A"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"disk\" and r._field == \"free\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"剩余空间\" })) |> yield(name: \"剩余空间\")",
"refId": "B"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"disk\" and r._field == \"total\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"总空间\" })) |> yield(name: \"总空间\")",
"refId": "C"
}
],
"options": {
"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max", "last"]},
"tooltip": {"mode": "multi"}
},
"fieldConfig": {
"defaults": {
"unit": "percent",
"max": 100,
"min": 0,
"color": {"mode": "palette-classic"},
"custom": {"lineWidth": 2, "fillOpacity": 20, "drawStyle": "line", "lineInterpolation": "smooth"}
},
"overrides": [
{"matcher": {"id": "byName", "options": "剩余空间"}, "properties": [{"id": "unit", "value": "bytes"}, {"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "总空间"}, "properties": [{"id": "unit", "value": "bytes"}, {"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}]}
]
}
},
{
"id": 4,
"title": "网络流量",
"type": "timeseries",
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 8},
"targets": [
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"net\" and r._field == \"bytes_recv\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"接收流量\" })) |> yield(name: \"接收流量\")",
"refId": "A"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"net\" and r._field == \"bytes_sent\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"发送流量\" })) |> yield(name: \"发送流量\")",
"refId": "B"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"net\" and r._field == \"packets_recv\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"接收包数\" })) |> yield(name: \"接收包数\")",
"refId": "C"
},
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"net\" and r._field == \"packets_sent\" and r.host == \"ubuntu-server\") |> aggregateWindow(every: 1m, fn: mean) |> map(fn: (r) => ({ r with _field: \"发送包数\" })) |> yield(name: \"发送包数\")",
"refId": "D"
}
],
"options": {
"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max", "last"]},
"tooltip": {"mode": "multi"}
},
"fieldConfig": {
"defaults": {
"unit": "bps",
"color": {"mode": "palette-classic"},
"custom": {"lineWidth": 2, "fillOpacity": 20, "drawStyle": "line", "lineInterpolation": "smooth"}
},
"overrides": [
{"matcher": {"id": "byName", "options": "接收流量"}, "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "发送流量"}, "properties": [{"id": "color", "value": {"fixedColor": "red", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "接收包数"}, "properties": [{"id": "unit", "value": "short"}, {"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}]},
{"matcher": {"id": "byName", "options": "发送包数"}, "properties": [{"id": "unit", "value": "short"}, {"id": "color", "value": {"fixedColor": "orange", "mode": "fixed"}}]}
]
}
},
{
"id": 5,
"title": "CPU 核心数",
"type": "stat",
"gridPos": {"h": 4, "w": 3, "x": 0, "y": 16},
"targets": [
{
"datasource": {"type": "influxdb", "uid": "influxdb-1"},
"query": "from(bucket: \"telegraf\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == \"cpu\" and r._field == \"usage_user\" and r.host == \"ubuntu-server\") |> last