name: 可观测性模式 description: 用于实施可观测性策略、关联信号或设计监控系统时使用。涵盖三大支柱(日志、指标、跟踪)及其集成。 allowed-tools: Read, Glob, Grep
可观测性模式
实施全面可观测性包括日志、指标、跟踪及其相关性的模式。
何时使用此技能
- 设计可观测性策略
- 实施三大支柱
- 跨系统关联信号
- 选择可观测性工具
- 构建监控仪表板
什么是可观测性?
可观测性 = 从外部输出理解内部状态的能力
不仅是监控(已知未知)
而是理解(未知未知)
传统监控:"CPU 使用率 > 80%?"
可观测性:"为什么用户遇到延迟?"
三大支柱
概述
┌─────────────────────────────────────────────────────────┐
│ 可观测性 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 日志 │ │ 指标 │ │ 跟踪 │ │
│ │ │ │ │ │ │ │
│ │ 事件 │ │ 计数器 │ │ 请求 │ │
│ │ 详情 │ │ 仪表 │ │ 跨度 │ │
│ │ 上下文 │ │ 趋势 │ │ 流程 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ └───────────────┼───────────────┘ │
│ │ │
│ ┌────────┴────────┐ │
│ │ 关联性 │ │
│ │ (trace_id) │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
每个支柱回答不同问题:
- 日志:发生了什么?(事件)
- 指标:有多少/多频繁?(聚合)
- 跟踪:在哪里?(请求流程)
日志
目的:具有上下文的离散事件
结构:
{
"timestamp": "2024-01-15T10:30:00.123Z",
"level": "ERROR",
"service": "order-service",
"message": "支付失败",
"trace_id": "abc123",
"span_id": "def456",
"user_id": "12345",
"order_id": "ORD-789",
"error": {
"code": "CARD_DECLINED",
"message": "资金不足"
}
}
最佳用于:
- 调试特定问题
- 审计跟踪
- 错误详情
- 业务事件
挑战:
- 高容量 → 存储成本高
- 非结构化 → 难以查询
- 无聚合 → 不适合趋势分析
指标
目的:随时间变化的数值测量
类型:
┌─────────────────────────────────────────────────────────┐
│ 计数器:累积,只增加 │
│ - http_requests_total │
│ - errors_total │
│ - bytes_transferred │
├─────────────────────────────────────────────────────────┤
│ 仪表:点时间值,可上升下降 │
│ - current_connections │
│ - queue_depth │
│ - temperature │
├─────────────────────────────────────────────────────────┤
│ 直方图:值分布 │
│ - request_duration_seconds │
│ - response_size_bytes │
│ 提供:计数、总和、桶 │
├─────────────────────────────────────────────────────────┤
│ 摘要:类似直方图,计算分位数 │
│ - request_latency_seconds (p50, p90, p99) │
└─────────────────────────────────────────────────────────┘
最佳用于:
- 趋势和模式
- 阈值告警
- 仪表板
- 容量规划
挑战:
- 无事件详情
- 基数限制
- 非请求级别
跟踪
目的:跨服务请求流程
结构:
跟踪(端到端请求)
├── 跨度(API 网关)- 200ms
│ ├── 跨度(认证)- 20ms
│ └── 跨度(订单服务)- 150ms
│ ├── 跨度(数据库)- 50ms
│ └── 跨度(支付服务)- 80ms
│ └── 跨度(外部 API)- 60ms
最佳用于:
- 理解请求流程
- 发现瓶颈
- 调试分布式问题
- 服务依赖
挑战:
- 存储密集
- 需要采样
- 实施复杂
信号关联
为什么关联?
无关联:
- 指标:"错误率很高"
- 日志:"来自某处的错误日志"
- 跟踪:"一些跟踪显示错误"
→ 难以连接点
有关联:
- 指标:"错误率在10:30激增"
└── 点击查看:示例跟踪
└── 点击查看:相关日志
→ 几秒钟内获得全貌
关联方法
1. 跟踪 ID 注入:
所有信号包括 trace_id
日志:{"trace_id": "abc123", "message": "..."}
指标:http_requests{trace_id="abc123"}
跟踪:TraceID = abc123
2. 示例:
指标指向样本跟踪
request_latency = 2.5s
└── 示例:trace_id=abc123
→ "显示一个慢请求"
3. 时间关联:
按时间戳对齐信号
指标激增在10:30
→ 查询10:30附近的日志
→ 查询10:30附近的跟踪
统一查询示例
调查流程:
1. 仪表板显示延迟激增
http_request_duration_p99 = 3s
2. 点击激增 → 示例跟踪
trace_id: abc123
3. 查看跟踪 → 慢数据库跨度
db.query: SELECT * FROM orders... (2.5s)
4. 使用 trace_id 查询日志
{"trace_id":"abc123","query":"SELECT...","rows":50000}
5. 根因识别
缺少索引导致全表扫描
OpenTelemetry 统一方法
OpenTelemetry 为所有信号提供统一 API:
应用程序代码
│
▼
┌─────────────────────────────────────────────────────┐
│ OpenTelemetry SDK │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 跟踪器 │ │ 仪表 │ │ 日志器 │ │
│ │ 提供者 │ │ 提供者 │ │ 提供者 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └────────────┼────────────┘ │
│ │ │
│ ┌───────┴───────┐ │
│ │ 导出器 │ │
│ └───────────────┘ │
└─────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Tempo │ │Prometheus│ │ Loki │
│(跟踪) │ │(指标) │ │ (日志) │
└─────────┘ └─────────┘ └─────────┘
日志模式
结构化日志
非结构化(差):
"用户12345登录失败:密码无效"
结构化(好):
{
"event": "login_failed",
"user_id": "12345",
"reason": "invalid_password",
"timestamp": "2024-01-15T10:30:00Z",
"trace_id": "abc123"
}
好处:
- 可查询:user_id:12345 AND event:login_failed
- 可解析:自动化分析
- 可关联:trace_id 链接到跟踪
日志级别
级别 | 何时使用
----------|------------------------------------------
TRACE | 非常详细,仅开发
DEBUG | 开发,详细
INFO | 正常操作,审计事件
WARN | 降级,可恢复问题
ERROR | 失败需要关注
FATAL | 应用程序无法继续
生产通常:INFO 及以上
调试模式:DEBUG 及以上
日志聚合架构
┌─────────────────────────────────────────────────────────┐
│ 应用程序 Pods │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ 应用 │ │ 应用 │ │ 应用 │ → stdout/stderr │
│ └──────┘ └──────┘ └──────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 日志收集器(Fluentd/Vector/Fluent Bit) │
│ - 解析日志 │
│ - 添加元数据(pod, namespace 等) │
│ - 转换/过滤 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 存储(Elasticsearch/Loki/CloudWatch) │
│ - 索引用于搜索 │
│ - 保留策略 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 查询接口(Kibana/Grafana) │
│ - 搜索和过滤 │
│ - 仪表板 │
└─────────────────────────────────────────────────────────┘
指标模式
命名约定
格式:[namespace]_[subsystem]_[name]_[unit]
示例:
http_requests_total
http_request_duration_seconds
http_response_size_bytes
process_cpu_seconds_total
db_connections_current
指南:
- 使用 snake_case
- 包括单位后缀(_seconds, _bytes, _total)
- 使用基本单位(秒而不是毫秒)
- 跨服务一致
标签/维度
带标签的指标:
http_requests_total{
method="GET",
path="/api/users",
status="200"
}
基数警告:
http_requests_total{user_id="..."} // 差:高基数
保持标签低基数:
- status:~5 个值(200, 4xx, 5xx...)
- method:~10 个值
- service:~100 个值
- user_id:数百万 → 太多
RED 方法
用于基于请求的服务:
R - 速率:每秒请求数
http_requests_total
E - 错误:每秒失败请求数
http_requests_total{status=~"5.."}
D - 持续时间:延迟分布
http_request_duration_seconds
USE 方法
用于资源(CPU, 内存, 磁盘):
U - 利用率:资源使用百分比
cpu_usage_percent
S - 饱和度:排队工作
thread_pool_queued_tasks
E - 错误:错误计数
disk_errors_total
仪表板和告警
仪表板设计
仪表板层次结构:
1. 概览(执行级别)
- 关键 SLOs
- 错误率
- 流量趋势
2. 服务仪表板
- RED 指标
- 依赖
- 资源使用
3. 调试仪表板
- 详细指标
- 组件分解
- 查询性能
告警设计
好告警:
- 可操作:有人可以做事
- 有意义:反映用户影响
- 紧急:现在需要关注
差告警:
- CPU > 80%(可能正常)
- 磁盘 > 90%(太晚?)
- 任何单个错误(噪音)
更好方法:基于 SLO 的告警
- "错误预算消耗太快"
- 直接与用户影响相关
工具选择
开源堆栈
指标:Prometheus + Grafana
日志:Loki + Grafana
跟踪:Jaeger/Tempo + Grafana
替代:
指标:VictoriaMetrics + Grafana
日志:Elasticsearch + Kibana
跟踪:Zipkin
云原生
AWS:
- CloudWatch(指标,日志)
- X-Ray(跟踪)
GCP:
- Cloud Monitoring(指标)
- Cloud Logging(日志)
- Cloud Trace(跟踪)
Azure:
- Azure Monitor(指标,日志)
- Application Insights(跟踪)
商业平台
全栈:
- Datadog
- New Relic
- Dynatrace
- Splunk
好处:统一,托管,功能
成本:价格,供应商锁定
最佳实践
1. 从一开始就结构化日志
不要事后修补
2. 一致跟踪上下文
到处传播 trace_id
3. 指标基数意识
监控并限制标签值
4. 默认关联
日志中的 trace_id,指标中的示例
5. 告警症状而非原因
"用户受影响" 而非 "CPU 高"
6. 定期可观测性审查
我们是否看到所需内容?
相关技能
distributed-tracing- 跟踪深入slo-sli-error-budget- 基于 SLO 的可观测性incident-response- 在事件中使用可观测性