Agent开发工程师成长指南 · 工程实践篇

本教程的目标不是简单教你安装 Grafana,而是带你从零搭建一套真正可以用于企业项目的可观测性平台。
我们将以 Docker Compose 为基础,逐步构建:
-
Grafana:统一监控与可视化中心。
-
Prometheus:指标采集与时序数据存储。
-
Node Exporter:服务器资源监控。
-
cAdvisor:Docker 容器监控。
-
Loki:日志采集与分析。
-
Alloy:统一遥测数据采集。
-
Tempo:分布式链路追踪。
-
OpenTelemetry:应用程序遥测标准。
-
Alerting:异常检测与告警通知。
最终实现一个完整的监控体系,并将 Spring Boot、FastAPI、MySQL 以及 AI Agent 接入其中。
第一部分:认识 Grafana 与可观测性
1.1 什么是 Grafana?
Grafana 是一个开源的数据可视化与可观测性平台。
它能够连接不同的数据源,将来自服务器、数据库、应用程序、容器和 AI 服务的数据统一呈现在 Dashboard 中。
例如,一个企业管理平台可能包含:
| 监控对象 | 监控内容 |
|---|---|
| Linux / Windows 服务器 | CPU、内存、磁盘、网络 |
| Java 服务 | JVM、GC、线程、接口响应 |
| Python 服务 | 请求量、异常率、执行耗时 |
| MySQL | 连接数、慢 SQL、事务 |
| Redis | 内存、命中率、连接数 |
| Docker | 容器状态、资源使用率 |
| Kubernetes | Pod、Node、Deployment |
| AI Agent | Token、模型耗时、调用成功率 |
Grafana 的核心作用是将这些数据统一关联和展示。
1.2 先理解三个核心概念
可观测性通常围绕三个核心维度展开。

Metrics:指标
回答系统运行得怎么样。
例如 CPU 使用率 85%、接口平均耗时 300ms、请求失败率 2%。

Logs:日志
回答系统具体发生了什么。
例如数据库连接失败、用户登录异常、Agent 工具调用失败。

Traces:链路追踪
回答一次请求经过了哪些服务,以及时间消耗在哪里。
例如 API → Agent → RAG → 向量数据库 → LLM。
三者结合,才能从发现问题、分析问题到定位问题形成完整闭环。
1.3 监控与可观测性有什么区别?
| 对比 | 传统监控 | 可观测性 |
|---|---|---|
| 主要目的 | 发现已知问题 | 分析未知问题 |
| 数据 | 预设指标 | 指标、日志、链路、事件 |
| 分析方式 | 阈值告警 | 多维关联分析 |
| 典型问题 | CPU 是否超过 90% | 为什么接口突然变慢 |
| 适用场景 | 服务器运维 | 微服务、云原生、AI 系统 |
理解重点:监控告诉我们哪里出现异常,可观测性帮助我们理解异常为什么发生。
第二部分:Grafana 技术架构
2.1 整体架构

我们采用经典的 LGTM 架构,并增加 Prometheus Exporter、OpenTelemetry 和 Grafana Alloy。

这里有几个容易混淆的地方:
-
Prometheus 负责指标抓取与存储,不是 Grafana 的组成依赖。
-
Loki 是日志后端,Grafana 可以直接查询它。
-
Tempo 是链路追踪后端。
-
Alloy 是数据采集和处理代理,不是数据存储系统。
-
OpenTelemetry 是开放标准及其生态,不等于某一个具体数据库。
2.2 LGTM 分别代表什么?
| 字母 | 产品 | 主要功能 |
|---|---|---|
| L | Loki | Logs |
| G | Grafana | Visualization |
| T | Tempo | Traces |
| M | Mimir | Metrics |
本教程的入门实战先使用 Prometheus 存储指标,后续再介绍 Mimir。
这样既可以降低初期部署复杂度,又方便后续扩展到企业级规模。
第三部分:实战环境准备
3.1 本次实验的技术环境
本教程以 Windows 11 + Docker Desktop 为主要开发环境,同时兼容 Linux。
实验环境配置
| 软件 | 用途 |
|---|---|
| Windows 11 | 宿主机 |
| Docker Desktop | 容器运行环境 |
| Docker Compose | 多容器编排 |
| Grafana | 可视化 |
| Prometheus | 指标存储 |
| Node Exporter | 主机指标 |
| cAdvisor | 容器指标 |
| Loki + Alloy | 日志采集 |
| Tempo | 链路追踪 |
| Spring Boot / FastAPI | 被监控的业务应用 |
适合本地学习和功能验证
先确认 Docker 环境:
docker --version
docker compose version
确保 Docker Desktop 已经启动。
3.2 创建项目目录
创建一个独立的 Grafana 实战工程:
bash
grafana-observability/
│
├── docker-compose.yml
│
├── prometheus/
│ └── prometheus.yml
│
├── grafana/
│ └── provisioning/
│ └── datasources/
│ └── datasources.yml
│
├── loki/
│ └── loki.yml
│
├── alloy/
│ └── config.alloy
│
├── tempo/
│ └── tempo.yml
│
└── data/
各目录的作用:
-
prometheus:指标采集配置。
-
grafana:数据源、Dashboard 自动配置。
-
loki:日志存储配置。
-
alloy:日志和遥测采集配置。
-
tempo:分布式链路追踪配置。
-
data:持久化数据目录(本实验主要使用 Docker Volumes)。
3.3 编写 Docker Compose
在根目录创建 docker-compose.yml:
java
services:
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: admin123
GF_USERS_ALLOW_SIGN_UP: "false"
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
depends_on:
- prometheus
- loki
- tempo
networks:
- observability
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention.time=15d"
networks:
- observability
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
ports:
- "9100:9100"
networks:
- observability
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
ports:
- "8088:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
- /dev/disk:/dev/disk:ro
privileged: true
devices:
- /dev/kmsg
networks:
- observability
loki:
image: grafana/loki:3.7.0
container_name: loki
restart: unless-stopped
ports:
- "3100:3100"
command:
- "-config.file=/etc/loki/loki.yml"
volumes:
- ./loki/loki.yml:/etc/loki/loki.yml:ro
- loki_data:/loki
networks:
- observability
alloy:
image: grafana/alloy:latest
container_name: alloy
restart: unless-stopped
ports:
- "12345:12345"
volumes:
- ./alloy/config.alloy:/etc/alloy/config.alloy:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
- "run"
- "--server.http.listen-addr=0.0.0.0:12345"
- "/etc/alloy/config.alloy"
depends_on:
- loki
networks:
- observability
tempo:
image: grafana/tempo:latest
container_name: tempo
restart: unless-stopped
command:
- "-config.file=/etc/tempo/tempo.yml"
ports:
- "3200:3200"
- "4317:4317"
- "4318:4318"
volumes:
- ./tempo/tempo.yml:/etc/tempo/tempo.yml:ro
- tempo_data:/var/tempo
networks:
- observability
volumes:
grafana_data:
prometheus_data:
loki_data:
tempo_data:
networks:
observability:
driver: bridge
说明:
-
Grafana 对外提供 3000 端口。
-
Prometheus 对外提供 9090 端口。
-
Loki 对外提供 3100 端口。
-
Tempo 使用 3200 端口查询,4317/4318 接收 OTLP 数据。
-
Alloy 的 12345 端口用于查看采集代理状态。
Windows 环境注意: Node Exporter 和 cAdvisor 的主机指标采集方式与 Linux 不完全相同。Docker Desktop 中运行的容器通常不能代表 Windows 宿主机的完整 CPU、磁盘和内存状态。后续若要监控 Windows 宿主机,应单独安装 Windows Exporter。
3.4 配置 Prometheus
创建 prometheus/prometheus.yml:
java
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
# Prometheus 自身
- job_name: prometheus
static_configs:
- targets:
- prometheus:9090
# Node Exporter
- job_name: node
static_configs:
- targets:
- node-exporter:9100
# Docker 容器
- job_name: cadvisor
static_configs:
- targets:
- cadvisor:8080
这里有一个重要概念:Prometheus 使用 Pull 模式。
也就是说,Prometheus 会按照配置的时间间隔主动访问各个监控目标的 /metrics 接口,拉取指标数据。
例如:
http://node-exporter:9100/metrics
http://cadvisor:8080/metrics
http://prometheus:9090/metrics
这就是 Prometheus 的核心工作机制。
3.5 配置 Grafana 数据源自动注册
创建:
grafana/provisioning/datasources/datasources.yml
java
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
- name: Loki
type: loki
access: proxy
url: http://loki:3100
editable: true
- name: Tempo
type: tempo
access: proxy
url: http://tempo:3200
editable: true
这样启动 Grafana 后,三个数据源就会自动注册,不需要手动添加。
3.6 配置 Loki
创建 loki/loki.yml:
java
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
path_prefix: /loki
replication_factor: 1
ring:
kvstore:
store: inmemory
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
schema_config:
configs:
- from: "2024-01-01"
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
allow_structured_metadata: true
retention_period: 168h
compactor:
working_directory: /loki/compactor
delete_request_store: filesystem
retention_enabled: true
这个配置使用本地文件系统存储日志,保留周期设置为 7 天。
这是单机学习环境,不适合直接作为生产集群配置。生产环境还需要考虑对象存储、认证、租户隔离、容量规划和数据生命周期。
3.7 配置 Grafana Alloy
创建 alloy/config.alloy:
java
discovery.docker "containers" {
host = "unix:///var/run/docker.sock"
}
loki.source.docker "containers" {
host = "unix:///var/run/docker.sock"
targets = discovery.docker.containers.targets
forward_to = [loki.write.default.receiver]
}
loki.write "default" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}
这段配置完成了三个动作:
-
发现 Docker 容器。
-
读取 Docker 容器日志。
-
将日志发送到 Loki。
Alloy 在这里充当日志采集代理。官方也提供了类似的 Docker 容器日志采集实践。
安全提醒: Docker Socket 具有较高权限,即使以只读方式挂载,也不能简单视为完全安全。生产环境应考虑专门的日志采集节点和最小权限设计。
3.8 配置 Tempo
创建 tempo/tempo.yml:
java
server:
http_listen_port: 3200
distributor:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
ingester:
max_block_duration: 5m
compactor:
compaction:
block_retention: 24h
storage:
trace:
backend: local
local:
path: /var/tempo/traces
wal:
path: /var/tempo/wal
这里使用本地存储,接收来自应用程序的 OpenTelemetry Trace 数据。
3.9 启动整个监控平台
在项目根目录执行:
docker compose config
docker compose pull
docker compose up -d
查看运行状态:
docker compose ps
查看异常日志:
docker compose logs -f grafana
docker compose logs -f prometheus
docker compose logs -f loki
docker compose logs -f alloy
docker compose logs -f tempo
部署完成后
访问以下地址:
| 服务 | 地址 | 初始账号 |
|---|---|---|
| Grafana | http://localhost:3000 | admin / admin123 |
| Prometheus | http://localhost:9090 | 无 |
| Loki | http://localhost:3100/ready | 无 |
| Tempo | http://localhost:3200/ready | 无 |
| Alloy | http://localhost:12345 | 无 |
首次登录 Grafana 后建议立即修改管理员密码。
第四部分:Prometheus 指标监控实战
4.1 理解 Prometheus 数据模型
Prometheus 将监控数据存储为时间序列(Time Series)。
一条时间序列由:
-
Metric Name:指标名称。
-
Labels:标签。
-
Timestamp:时间戳。
-
Value:数值。
例如:
java
http_requests_total{
method="GET",
status="200",
service="user-service"
} 1250
这条数据表示:
用户服务通过 GET 请求成功返回 200 的累计请求次数为 1250。
4.2 Prometheus 四种核心指标类型
| 类型 | 含义 | 示例 |
|---|---|---|
| Counter | 只增不减的累计值 | 请求总数、异常总数 |
| Gauge | 可增可减的瞬时值 | CPU、内存、在线人数 |
| Histogram | 观测值分布及桶统计 | 接口耗时 |
| Summary | 观测值分位数统计 | 请求延迟分位数 |
要特别理解 Counter 和 Gauge 的区别。
例如:
http_requests_total = 1000
表示累计请求量。
system_memory_usage = 75
表示当前内存使用率为 75%。
4.3 学习 PromQL
PromQL 是 Prometheus 的查询语言。
在 Prometheus 页面进入 Graph,尝试以下查询。
查询 1:CPU 相关数据
node_cpu_seconds_total
查询 2:内存可用量
node_memory_MemAvailable_bytes
查询 3:内存使用率
100 * (
1 -
node_memory_MemAvailable_bytes
/
node_memory_MemTotal_bytes
)
查询 4:CPU 使用率
100 * (
1 -
avg by (instance) (
rate(node_cpu_seconds_total{mode="idle"}[5m])
)
)
查询 5:容器 CPU 使用率
sum by (name) (
rate(container_cpu_usage_seconds_total[5m])
) * 100
查询 6:每秒请求量
假设应用暴露了 http_requests_total:
sum(
rate(http_requests_total[5m])
)
查询 7:接口错误率
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
* 100
注意:最后一个表达式需要请求总数不为零,并且应用需要正确暴露对应指标。
4.4 理解 rate() 和 increase()
这两个函数在实际监控中非常常见。
rate(http_requests_total[5m])
计算过去 5 分钟的平均每秒增长速率。
increase(http_requests_total[1h])
计算过去 1 小时的累计增长量。
例如,接口累计请求量从 1000 增加到 1600,那么这一小时的请求增长量约为 600。
为什么不能直接拿 Counter 做减法?
因为 Counter 可能在服务重启后归零,rate() 和 increase() 会考虑 Counter 重置的情况。
4.5 创建第一个 Grafana Dashboard

操作步骤:
-
登录 Grafana。
-
点击 Dashboards。
-
点击 New。
-
选择 New Dashboard。
-
点击 Add Visualization。
-
选择 Prometheus 数据源。
-
输入 PromQL。
-
选择图表类型。
-
保存 Dashboard。
建议创建以下 Panel:
| Panel | PromQL | 可视化 |
|---|---|---|
| CPU 使用率 | CPU 查询表达式 | Gauge |
| 内存使用率 | 内存查询表达式 | Gauge |
| CPU 变化趋势 | CPU 查询表达式 | Time series |
| 可用内存 | node_memory_MemAvailable_bytes |
Time series |
| 磁盘剩余空间 | node_filesystem_avail_bytes |
Time series |
| 网络流量 | rate(node_network_receive_bytes_total[5m]) |
Time series |
Dashboard 还可以配置:
-
时间范围。
-
自动刷新。
-
变量筛选。
-
Panel 联动。
-
多行布局。
-
阈值颜色。
-
数据链接。
实战建议: 不要把所有监控数据堆在一个页面。可以按基础设施、应用服务、数据库、AI Agent 分成多个 Dashboard。
第五部分:Loki 日志采集与分析实战
指标告诉我们系统是否异常,日志则帮助我们查找异常原因。
5.1 Loki 的工作原理

日志采集链路:
Spring Boot
|
v
Docker Container Logs
|
v
Grafana Alloy
|
v
Loki
|
v
Grafana Explore
|
v
日志查询与分析
Loki 与 Elasticsearch 有一个重要区别:
-
Elasticsearch 通常会对日志内容建立全文索引。
-
Loki 主要对标签建立索引,日志内容本身不采用传统全文索引方式。
因此,Loki 特别适合与 Grafana 生态组合使用。
5.2 验证日志采集
先启动一个测试容器:
bash
docker run -d \
--name log-demo \
alpine \
sh -c 'while true; do echo "$(date) INFO application running"; sleep 3; done'
等待几秒,然后进入 Grafana:
Explore → Loki
在查询框输入:
{container_name="log-demo"}
如果能够看到持续产生的日志,就说明:
-
Docker 日志正常产生。
-
Alloy 能够读取容器日志。
-
Loki 能够接收日志。
-
Grafana 能够查询日志。
具体标签名称可能随 Alloy 版本和 Docker 发现配置有所不同,可先通过 Explore 的标签浏览器查看实际标签。
5.3 学习 LogQL
LogQL 是 Loki 的日志查询语言。
查询所有容器日志:
{container_name=~".+"}
查询包含 ERROR 的日志:
{container_name=~".+"} |= "ERROR"
查询包含异常信息的日志:
{container_name=~".+"} |~ "(?i)exception|error|failed"
排除健康检查日志:
{container_name=~".+"} != "health"
统计过去 5 分钟的错误日志数量:
sum(
count_over_time(
{container_name=~".+"} |= "ERROR" [5m]
)
)
统计不同容器的错误日志数量:
sum by (container_name) (
count_over_time(
{container_name=~".+"} |= "ERROR" [5m]
)
)
5.4 企业级日志规范
实际开发中,不建议只输出无结构的日志:
用户登录失败
更推荐使用 JSON 结构化日志:
{
"timestamp": "2026-11-13T10:00:00+08:00",
"level": "ERROR",
"service": "user-service",
"trace_id": "abc123",
"user_id": "10001",
"operation": "login",
"message": "Database connection failed",
"duration_ms": 1200
}
这样可以进一步进行字段解析、过滤和统计。
例如:
{service="user-service"}
| json
| level="ERROR"
注意:实际采集时需要确保 JSON 日志没有被额外包装,且字段名称与实际日志一致。
5.5 日志标签设计原则
Loki 的标签设计尤其重要。
推荐:
| 推荐标签 | 不推荐标签 |
|---|---|
| service | user_id |
| environment | request_id |
| level | trace_id |
| region | |
| cluster | 完整 URL |
原因是 Loki 的索引主要依赖标签,标签基数过高会增加索引和查询成本。
用户 ID、Trace ID 等动态字段更适合保留在日志内容中,需要时再进行解析。
第六部分:Tempo 分布式链路追踪实战
6.1 为什么需要链路追踪?
假设一个企业 Agent 系统收到用户请求:
用户提问
|
v
API Gateway
|
v
Agent Service
|
v
意图识别
|
v
RAG 检索
|
v
Vector Database
|
v
LLM API
|
v
返回答案
用户反馈:系统响应非常慢。
仅仅查看服务器 CPU、内存,可能无法找到问题。
因为真正的问题可能是:
-
LLM 响应时间过长。
-
向量数据库查询过慢。
-
某个外部 API 超时。
-
Agent 重复执行了工具调用。
这就需要分布式链路追踪。
6.2 Trace、Span 和 Trace ID

三个核心概念:
| 概念 | 含义 |
|---|---|
| Trace | 一次完整请求的调用链 |
| Span | 链路中的一个执行单元 |
| Trace ID | 一次请求的唯一追踪标识 |
例如:
Trace ID: abc123
API Request 2000ms
|
+-- Agent 1800ms
|
+-- RAG 200ms
|
+-- LLM 1500ms
|
+-- Tool 100ms
通过 Span 的开始时间、结束时间和父子关系,可以定位时间消耗。
6.3 OpenTelemetry 的作用
OpenTelemetry 是跨语言、跨平台的可观测性标准。
它主要解决:
-
如何生成指标。
-
如何生成日志。
-
如何生成 Trace。
-
如何在不同服务间传递上下文。
-
如何将遥测数据发送到不同后端。
常见数据传输协议:
| 协议 | 端口 | 用途 |
|---|---|---|
| OTLP gRPC | 4317 | 遥测数据传输 |
| OTLP HTTP | 4318 | 遥测数据传输 |
6.4 Spring Boot 接入 OpenTelemetry
Java 项目可以使用 OpenTelemetry Java Agent 自动埋点。
例如使用 Spring Boot:
bash
java \
-javaagent:opentelemetry-javaagent.jar \
-Dotel.service.name=epm-backend \
-Dotel.exporter.otlp.endpoint=http://localhost:4317 \
-Dotel.exporter.otlp.protocol=grpc \
-Dotel.traces.exporter=otlp \
-jar app.jar
注意:
如果 Java 应用运行在 Docker Compose 网络内,应该把地址改为:
http://tempo:4317
而不是 localhost。
localhost 指的是应用容器本身,不是 Tempo 容器。
生产项目中还应配置采样率、资源属性、服务版本和环境信息。
6.5 FastAPI 接入 OpenTelemetry
安装依赖:
bash
pip install \
fastapi \
uvicorn \
opentelemetry-api \
opentelemetry-sdk \
opentelemetry-exporter-otlp \
opentelemetry-instrumentation-fastapi
创建 main.py:
python
from fastapi import FastAPI
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
BatchSpanProcessor
)
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
OTLPSpanExporter
)
from opentelemetry.instrumentation.fastapi import (
FastAPIInstrumentor
)
resource = Resource.create({
"service.name": "ai-agent-service",
"deployment.environment": "development"
})
provider = TracerProvider(resource=resource)
exporter = OTLPSpanExporter(
endpoint="localhost:4317",
insecure=True
)
provider.add_span_processor(
BatchSpanProcessor(exporter)
)
trace.set_tracer_provider(provider)
app = FastAPI()
FastAPIInstrumentor.instrument_app(app)
tracer = trace.get_tracer(__name__)
@app.get("/agent")
async def agent():
with tracer.start_as_current_span("agent.execute"):
with tracer.start_as_current_span("rag.retrieve"):
# 模拟知识库检索
pass
with tracer.start_as_current_span("llm.generate"):
# 模拟大模型调用
pass
return {
"message": "Agent execution completed"
}
如果 FastAPI 运行在 Docker 容器中,将 localhost:4317 改成 tempo:4317。
这个例子通过手动创建 Span,演示如何将 Agent 内部步骤纳入 Trace。
在真实项目中,可以进一步给 RAG、LLM、Tool Calling、数据库调用分别创建 Span,并记录耗时和异常。
6.6 在 Grafana 查看 Trace
操作步骤:
-
打开 Grafana。
-
进入 Explore。
-
选择 Tempo。
-
使用 TraceQL 或搜索界面查询。
-
打开一条 Trace。
-
查看各 Span 的执行时间。
-
找出耗时最长的调用。
示例 TraceQL:
{ resource.service.name = "ai-agent-service" }
还可以按 Span 名称过滤:
{ name = "llm.generate" }
至此,应用程序就可以将调用链发送到 Tempo,Grafana 可以负责展示和分析。
第七部分:Grafana Dashboard 企业级设计
这一部分是实际项目中非常重要的内容。
Grafana 不应该只做一个简单的 CPU、内存大屏,而应该围绕企业的业务、技术架构和运维管理进行设计。
7.1 企业监控中心

推荐设计:
| 模块 | 展示内容 |
|---|---|
| 系统概览 | 系统总数、运行数、异常数 |
| 服务器监控 | CPU、内存、磁盘 |
| 网络监控 | 入站流量、出站流量 |
| 服务监控 | 服务状态、可用率 |
| 数据库监控 | 连接数、查询耗时 |
| 容器监控 | 容器数量、异常容器 |
| 告警中心 | 当前告警、历史告警 |
7.2 Java 应用监控 Dashboard

推荐监控指标:
| 监控分类 | 具体指标 |
|---|---|
| JVM 内存 | Heap、Non-Heap |
| GC | GC 次数、GC 耗时 |
| 线程 | 活跃线程、线程池 |
| HTTP | 请求量、响应时间 |
| 错误 | 4xx、5xx |
| 数据库 | 连接池使用率 |
| 应用 | 启动状态、运行时间 |
Spring Boot 可以通过 Actuator 和 Micrometer 暴露 Prometheus 指标。
主要依赖:
java
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
配置:
management:
endpoints:
web:
exposure:
include: health,info,prometheus
endpoint:
health:
show-details: when_authorized
metrics:
tags:
application: epm-backend
environment: dev
访问:
http://localhost:8080/actuator/prometheus
然后在 Prometheus 中增加:
- job_name: spring-boot
metrics_path: /actuator/prometheus
static_configs:
- targets:
- host.docker.internal:8080
这里假设 Spring Boot 运行在 Windows 宿主机上,Prometheus 运行在 Docker Desktop 中。
如果 Spring Boot 也在 Compose 网络内,应该改成对应服务名和容器端口。
7.3 数据库监控 Dashboard

MySQL 可以使用 MySQL Exporter 暴露数据库指标。
主要监控:
-
MySQL 活跃连接数。
-
最大连接数。
-
QPS。
-
TPS。
-
慢查询。
-
Buffer Pool 命中率。
-
InnoDB 行锁等待。
-
主从复制延迟。
注意:MySQL Exporter 需要专门的监控账户,不建议使用 root 账户。
7.4 AI Agent 监控 Dashboard

这是传统系统监控与 AI 系统监控之间的重要区别。
建议监控:
| 分类 | 指标 |
|---|---|
| 模型调用 | LLM 请求总数 |
| Token | Input Token、Output Token |
| 成本 | 模型调用费用 |
| 性能 | 首 Token 时间、总响应时间 |
| 成功率 | 成功调用率、失败率 |
| RAG | 检索耗时、召回数量 |
| Agent | 执行次数、执行步骤 |
| Tool | 工具调用次数、失败次数 |
| Workflow | 工作流执行时间、成功率 |
这里需要特别说明:
Grafana 本身不会自动知道模型消耗了多少 Token,也不会自动理解 Agent 的业务执行步骤。
这些数据需要由应用程序、OpenTelemetry 埋点,或者 Langfuse 等 AI 可观测性平台提供。
第八部分:Grafana Alerting 告警实战
8.1 告警工作原理

Grafana Alerting 的主要组成:
-
Alert Rule:告警规则。
-
Evaluation:规则计算。
-
Pending:等待持续满足条件。
-
Firing:告警触发。
-
Contact Point:通知渠道。
-
Notification Policy:通知路由策略。
8.2 创建 CPU 告警规则
进入:
Alerting
└── Alert rules
└── New alert rule
查询表达式:
100 * (
1 -
avg by (instance) (
rate(node_cpu_seconds_total{mode="idle"}[5m])
)
)
配置:
| 参数 | 设置 |
|---|---|
| Rule Name | High CPU Usage |
| 条件 | IS ABOVE 85 |
| Evaluate every | 1m |
| Pending period | 5m |
| Severity | Warning |
表示 CPU 使用率持续超过 85% 达到 5 分钟,才触发告警。
8.3 创建内存告警
100 * (
1 -
node_memory_MemAvailable_bytes
/
node_memory_MemTotal_bytes
)
设置:
阈值:90%
持续时间:5 分钟
级别:Critical
8.4 创建服务不可用告警
up == 0
设置:
阈值:1
持续时间:1 分钟
如果某个监控目标无法被 Prometheus 正常抓取,up 就会变为 0。
8.5 配置告警通知
可以配置:
-
Email。
-
Webhook。
-
Slack。
-
Microsoft Teams。
-
其他支持的通知集成。
企业环境推荐:
告警规则
|
v
Notification Policy
|
+---- Critical → 运维负责人
|
+---- Warning → 运维群
|
+---- Info → 日志记录
同时应配置告警分组、重复通知间隔、静默时间和恢复通知,避免告警风暴。
第九部分:Grafana 与 Langfuse / LangSmith 集成
这一部分建议作为 Agent 开发工程师的重点实践。
9.1 为什么要结合 AI 可观测性平台?
Grafana 更偏向通用基础设施和应用可观测性。
Langfuse 和 LangSmith 更关注 LLM 与 Agent 的执行过程。

可以这样分工:
| 监控对象 | 推荐工具 |
|---|---|
| 服务器资源 | Prometheus + Grafana |
| 应用性能 | Prometheus + Grafana |
| 系统日志 | Loki + Grafana |
| 分布式调用链 | Tempo + Grafana |
| LLM Token | Langfuse |
| LLM 调用成本 | Langfuse |
| Prompt 管理 | Langfuse |
| Agent 调试 | LangSmith |
| Agent 评估 | LangSmith / Langfuse |
9.2 企业 AI Agent 监控架构
以设备故障诊断 Agent 为例:
用户提出:
主轴温度过高,设备运行异常
Agent 执行:
用户请求
|
v
Agent API
|
v
意图识别
|
v
RAG 检索设备维修知识
|
v
调用设备 API
|
v
LLM 分析故障
|
v
生成维修建议
|
v
人工确认
监控体系:
AI Agent
|
┌─────────┼─────────┐
v v v
Metrics Logs Traces
| | |
v v v
Prometheus Loki Tempo
| | |
└─────────┼─────────┘
v
Grafana
Agent 专属业务数据
|
v
Langfuse
这里可以将 Trace ID 作为跨系统关联标识。
当 Langfuse 中发现某次模型调用耗时异常时,可以利用相同的业务请求标识,在 Grafana 中继续查询对应的系统日志和链路。
但需要在埋点和上下文传递中主动实现标识关联,不能认为安装这两个产品后就会自动完成关联。
9.3 推荐监控指标
agent_requests_total
agent_execution_duration_seconds
agent_execution_errors_total
llm_requests_total
llm_input_tokens_total
llm_output_tokens_total
llm_request_duration_seconds
rag_retrieval_duration_seconds
rag_retrieval_results_total
tool_calls_total
tool_call_duration_seconds
tool_call_errors_total
建议把指标名称、标签和单位统一规划。
特别注意:不要把 user_id、request_id、trace_id 等高基数字段直接作为 Prometheus 标签,否则容易造成时序数量爆炸。
第十部分:企业级生产部署与安全
前面的实验属于单机学习环境。企业正式部署时,需要进一步考虑可靠性、安全性和可扩展性。
10.1 生产架构建议

建议划分为:
| 层级 | 生产设计 |
|---|---|
| 访问层 | Nginx / Ingress / HTTPS |
| 展示层 | Grafana 多实例 |
| 指标层 | Prometheus / Mimir |
| 日志层 | Loki + 对象存储 |
| 链路层 | Tempo + 对象存储 |
| 采集层 | Alloy / OpenTelemetry Collector |
| 存储层 | S3 兼容对象存储 |
| 通知层 | 邮件、Webhook、企业消息 |
10.2 安全设计
重点关注:
-
修改默认管理员密码。
-
启用 HTTPS。
-
禁止匿名访问。
-
配置组织与用户权限。
-
不将 Prometheus、Loki、Tempo 的内部端口直接暴露公网。
-
使用专用服务账户访问数据库。
-
敏感日志脱敏。
-
限制 Docker Socket 权限。
-
对 Dashboard、数据源和告警配置进行备份。
-
设置日志与指标保留周期。
10.3 存储容量规划
生产环境必须关注数据增长。
例如:
| 数据类型 | 主要影响因素 |
|---|---|
| Metrics | 指标数量、标签基数、采集间隔 |
| Logs | 每秒日志量、日志大小、保留周期 |
| Traces | 请求量、Span 数量、采样率 |
对于 Trace,可以采用采样策略:
正常请求:采样 5%
异常请求:尽可能保留
高价值业务:提高采样比例
这只是策略示例。若要保证错误 Trace 一定保留,需要采用具备尾采样能力的 Collector 架构,而不是单纯依赖应用端固定比例采样。
10.4 备份与恢复
至少需要备份:
-
Grafana 数据库和 Dashboard 配置。
-
Prometheus 持久化数据或快照。
-
Loki 配置及对象存储数据。
-
Tempo 配置及对象存储数据。
-
Alloy 配置。
-
告警规则与通知策略。
对于企业环境,推荐使用配置文件、Git 版本管理和自动化部署管理监控配置,而不是仅依赖网页手工配置。
第十一部分:常见故障排查
| 问题 | 可能原因 | 解决方式 |
|---|---|---|
| Grafana 无法访问 | 容器没有启动 | 检查 Compose 状态 |
| Prometheus 无数据 | Target 不可达 | 检查 Targets |
| 数据源连接失败 | 地址配置错误 | 使用容器服务名 |
| Loki 无日志 | Alloy 未采集 | 检查 Alloy 日志 |
| Tempo 没有 Trace | 应用没有埋点 | 检查 OTLP 配置 |
| Dashboard 没有数据 | PromQL 错误 | 检查指标名称 |
| 查询速度慢 | 标签基数过高 | 优化标签设计 |
| 告警没有通知 | 联系点配置错误 | 检查 Contact Point |
| 数据重启后丢失 | 没有持久化 | 配置 Volume |
几个常用排查命令:
docker compose ps
docker compose logs --tail=200 grafana
docker compose logs --tail=200 prometheus
docker compose logs --tail=200 alloy
docker compose logs --tail=200 loki
检查 Prometheus 目标状态:
http://localhost:9090/targets
检查 Loki:
http://localhost:3100/ready
检查 Tempo:
http://localhost:3200/ready
第十二部分:完整实战项目与学习验收
最后,我们把前面学习的内容组合成一个真正的企业级项目。
12.1 项目名称
Enterprise Observability Platform(企业级可观测性平台)

项目业务背景:
假设我们有一个企业 AI Platform,包含:
-
React 管理控制台。
-
Spring Boot 业务后端。
-
FastAPI Agent 服务。
-
MySQL 数据库。
-
Redis 缓存。
-
Milvus 向量数据库。
-
多种大模型 API。
-
Docker 部署环境。
需要通过 Grafana 建立统一监控平台。
12.2 最终 Dashboard 菜单设计
企业可观测性平台
│
├── 01. 运维总览
│ ├── 系统健康总览
│ ├── 服务可用性
│ └── 实时告警
│
├── 02. 基础设施监控
│ ├── 服务器监控
│ ├── CPU / 内存
│ ├── 磁盘 / 网络
│ └── Docker 容器
│
├── 03. 应用性能监控
│ ├── Spring Boot
│ ├── FastAPI
│ ├── API 性能
│ └── JVM 监控
│
├── 04. 数据库监控
│ ├── MySQL
│ ├── Redis
│ └── Milvus
│
├── 05. 日志中心
│ ├── 应用日志
│ ├── 系统日志
│ ├── 错误日志
│ └── 异常分析
│
├── 06. 链路追踪
│ ├── 服务调用关系
│ ├── 请求链路
│ └── 性能瓶颈
│
├── 07. AI Agent 监控
│ ├── Agent 执行情况
│ ├── LLM 调用统计
│ ├── Token 消耗
│ ├── RAG 检索性能
│ └── Tool 调用统计
│
└── 08. 告警管理
├── 告警规则
├── 告警记录
├── 通知渠道
└── 告警策略
12.3 实战任务清单
使用 Docker Compose 启动 Grafana、Prometheus、Loki、Tempo
完成 Prometheus 数据源配置
采集 Node Exporter 指标
采集 Docker 容器指标
创建服务器监控 Dashboard
使用 Alloy 采集 Docker 日志
完成 LogQL 日志查询
Spring Boot 接入 Actuator + Micrometer
FastAPI 接入 OpenTelemetry
在 Tempo 中查询 Trace
创建 CPU、内存、服务异常告警
构建 AI Agent 监控 Dashboard
完成日志、指标、Trace 关联分析
重置进度
12.4 最终验收标准
完成后,应该能够做到:
-
能够监控服务器和 Docker 容器。
-
能够查看 Java、Python 应用的性能指标。
-
能够集中检索应用日志。
-
能够追踪一次 Agent 的完整调用链。
-
能够查看 LLM 调用耗时和 Token 使用情况。
-
能够在系统出现异常时收到告警。
-
能够通过 Trace ID 将指标、日志和调用链关联起来。
这才算真正完成了一套企业级可观测性工程实践。
第十三部分:官方学习资源与延伸阅读
以下是建议长期收藏的官方资料:
| 学习主题 | 官方资料 |
|---|---|
| Grafana | Grafana Documentation |
| Prometheus | Prometheus Documentation |
| PromQL | PromQL 查询指南 |
| Loki | Loki Documentation |
| LogQL | LogQL 查询指南 |
| Tempo | Tempo Documentation |
| Alloy | Alloy Documentation |
| OpenTelemetry | OpenTelemetry Documentation |
| Docker 部署 | Grafana Docker 安装 |
官方 Docker Compose 和 Tempo 示例也值得参考:
十四、学习过程中需要特别注意的几个问题
- 本教程是单机实验环境,不是开箱即用的生产部署包。
Windows Docker Desktop 下,Node Exporter 和 cAdvisor 的宿主机指标采集存在平台差异。如果希望完整监控 Windows 宿主机,建议增加 Windows Exporter。
- 生产环境不要使用 latest 标签。
实验时可以使用 latest 快速启动,但正式部署应该锁定经过验证的版本,并使用版本升级和回滚机制。
- 不要把所有数据都放进 Grafana。
Grafana 主要负责查询、分析和展示,实际数据由 Prometheus、Loki、Tempo 等后端负责存储。
- AI Agent 的 Token 和成本需要业务埋点。
不要误以为安装 Grafana 就能自动获得 LLM Token 使用量。应由 Langfuse、模型调用 SDK 或业务服务主动提供相关数据。
- 监控系统自身也需要监控。
例如 Prometheus 抓取失败、Loki 磁盘空间不足、Tempo 写入异常,都应该有相应的健康检查和告警。
十五、总结:Grafana 在 AI Agent 工程体系中的位置

从传统 IT 运维到云原生,再到 AI Agent,企业的可观测性建设正在变得越来越重要。
我认为需要掌握的核心不是 Grafana 的 Dashboard 操作,而是下面这套工程思维:
| 层次 | 需要掌握的能力 |
|---|---|
| 数据采集 | Exporter、OpenTelemetry、Alloy |
| 指标体系 | Prometheus、PromQL |
| 日志体系 | Loki、LogQL |
| 链路追踪 | Tempo、Trace、Span |
| 可视化 | Grafana Dashboard |
| 告警体系 | Alerting、Notification Policy |
| AI 可观测性 | Langfuse、LangSmith |
| 企业工程化 | 高可用、权限、安全、存储、部署 |
最终形成的能力:
不仅能知道服务器是否正常运行,还能知道某个业务接口为什么变慢、哪个微服务出现异常、一次 Agent 执行消耗了多少时间、哪个模型调用产生了成本,以及整个 AI 工作流在哪个环节出了问题。
这才是企业级 AI Agent 开发工程师需要具备的可观测性工程能力。