关于 monitoring-setup-guide
monitoring-setup-guide 是帮助团队为服务制定生产监控方案的技能。它根据服务技术栈和用户旅程,组织指标、结构化日志、追踪、可执行告警阈值与仪表板。
主要功能
- 01四大黄金信号指标
- 02结构化日志规范
- 03分布式追踪清单
- 04基于阈值的告警规范
- 05业务指标与仪表板
- 06结合服务背景收集输入
适用场景
- 01规划新服务的监控方案
- 02审视现有服务的指标与告警
- 03围绕关键用户旅程设定运行阈值
- 04建立服务健康状况的统一参考
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mohitagw15856/ pm-claude-skills --skill monitoring-setup-guide安装后在 Claude Code 中输入/monitoring-setup-guide确认已加载。
详细介绍
监控配置指南技能
为服务编写完整的监控配置指南——明确要衡量什么、如何构建日志、如何配置具有可操作阈值的告警,以及如何构建能够回答实际运维问题的仪表板。良好的监控指南可以消除“我们不知道生产环境发生了什么”这一根因类别,并为值班工程师提供一份关于健康状态的唯一事实来源。
所需输入
如果尚未提供,请询问以下信息:
- 服务名称和描述——服务的功能及其在系统中的作用
- 技术栈——语言、框架和基础设施(例如,Kubernetes 上的 Go/gRPC、ECS 上的 Python/FastAPI)
- 当前监控工具——Datadog、Prometheus + Grafana、CloudWatch、New Relic、Honeycomb,或尚未使用任何工具
- 关键用户旅程——用户或使用方使用该服务时最重要的 2–4 项操作(这些决定了需要针对什么发出告警)
- 现有告警——粘贴现有告警配置,或描述当前的监控内容
输出格式
监控配置指南:[服务名称]
团队:[团队名称] | 技术负责人:[姓名] 技术栈:[语言/框架],运行于[基础设施] 监控平台:[Datadog / Prometheus+Grafana / CloudWatch / 等] 日期:[日期] | **审查周期:**每季度
1. 监控理念
良好的监控能回答三个问题:
- 服务目前是否健康?(告警)
- 过去是否健康,趋势是否正在恶化?(仪表板 + SLO 跟踪)
- 为什么发生了故障?(日志 + 跟踪)
本指南为[服务名称]明确这些问题的答案。每条告警都必须可操作——如果值班工程师无法针对告警采取具体行动,就不应该存在这条告警。
监控的关键用户旅程:
- 旅程 1:[例如,“用户提交付款——POST /charges,收到确认信息”]
- 旅程 2:[例如,“用户查看交易历史——GET /transactions”]
- 旅程 3:[例如,“订阅续订任务运行——后台工作进程处理计费事件”]
2. 四大黄金信号
针对[服务名称]应用四大黄金信号:
延迟
延迟衡量请求完成所需的时间。应分别跟踪成功请求和失败请求——如果只衡量总体延迟,快速错误会掩盖缓慢失败。
| 指标 | 描述 | 来源 | 维度 |
|---|---|---|---|
[service].request.duration_ms | 端到端请求延迟 | 应用插桩 | endpoint、method、status_code |
[service].db.query_duration_ms | 数据库查询延迟 | ORM / 查询插桩 | query_name、table |
[service].external.request_duration_ms | 对依赖项的出站调用延迟 | HTTP 客户端插桩 | target_service、endpoint |
[service].queue.processing_duration_ms | 处理单条消息所需的时间(如适用) | 消费者插桩 | queue_name、message_type |
延迟 SLO 目标:
| 端点 / 操作 | p50 目标 | p95 目标 | p99 目标 |
|---|---|---|---|
GET /api/v1/[resource] | < [50] ms | < [200] ms | < [500] ms |
POST /api/v1/[resource] | < [100] ms | < [400] ms | < [1000] ms |
GET /health | < [10] ms | < [20] ms | < [50] ms |
| [后台任务名称] | < [5] 秒 | < [15] 秒 | < [60] 秒 |
流量
流量用于衡量系统需求。可用它来检测意外的峰值、流量下降(这可能表示上游故障),并规划容量。
| 指标 | 描述 | 来源 |
|---|---|---|
[service].request.count | 每秒请求数 | 应用程序 / 负载均衡器 |
[service].request.count_by_endpoint | 按端点细分的每秒请求数(RPS) | 应用程序 |
[service].queue.messages_consumed_per_second | 消费者吞吐量 | 队列消费者 |
[service].queue.depth | 队列中等待处理的消息数 | 队列指标 |
流量基线(在生产环境观察 2 周以上后更新):
| 时间段 | 预期 RPS | 低流量下限 | 峰值上限 |
|---|---|---|---|
| 高峰时段(工作日办公时间) | [N] RPS | [N × 0.5] RPS | [N × 5] RPS |
| 非高峰时段(夜间 / 周末) | [N × 0.2] RPS | [N × 0.05] RPS | [N] RPS |
错误
错误用于衡量失败请求所占的比例。请区分客户端错误(4xx——调用方操作有误)和服务器错误(5xx——服务出现故障)。
| 指标 | 描述 | 是否告警? |
|---|---|---|
[service].request.error_rate | 5xx 错误数 / 总请求数 | 是——参见告警规则 |
[service].request.client_error_rate | 4xx 错误数 / 总请求数 | 阈值告警——突增可能表示 API 使用不当 |
[service].dependency.error_rate | 调用下游依赖时发生的错误 | 是——上游健康状况信号 |
[service].queue.dlq_depth | 死信队列中的消息数 | 是——表示处理失败 |
饱和度
饱和度用于衡量服务的“满载”程度——受限资源距离最大容量还有多远。
| 资源 | 指标 | 告警阈值 | 来源 |
|---|---|---|---|
| CPU | [service].cpu.utilisation_pct | 持续 5 分钟 >80% | 容器 / VM 指标 |
| 内存 | [service].memory.utilisation_pct | 持续 5 分钟 >85% | 容器 / VM 指标 |
| DB 连接 | [service].db.connection_pool.utilisation_pct | >75% | 应用程序 / DB 指标 |
| 线程池 / goroutine | [service].runtime.goroutine_count / thread_count | >N(建立基线) | 运行时指标 |
| 磁盘(如适用) | [service].disk.utilisation_pct | >75% | 基础设施 |
| 队列深度(如适用) | [service].queue.depth | >[backlog threshold] | 队列指标 |
3. 业务指标
除了黄金信号,还要跟踪衡量服务是否在创造业务价值的指标。这些指标对于 SLO 报告和产品仪表板很重要。
| 指标 | 描述 | 来源 | 是否告警? |
|---|---|---|---|
[service].[primary_action].success_rate | [例如:“支付成功率”] | 应用程序 | 是——与 1 小时平均值相比下降 >5% 时 |
[service].[primary_action].count | [例如:“每分钟处理的支付数”] | 应用程序 | 是——突降(流量异常) |
[service].[resource].created_per_hour | [例如:“新建账户数”] | 应用程序 / DB | 否——仅供参考 |
[service].cache.hit_rate | 由缓存提供服务的请求所占比例 | 缓存监测 | 是——低于 [60]% 时 |
[service].job.[name].success_rate | [后台作业成功率] | 作业框架 | 是——低于 [99]% 时 |
4. 日志策略
结构化日志模式
所有日志都必须采用结构化 JSON。生产环境中不得输出非结构化文本日志。每条日志都必须包含必填字段。
必填字段(每条日志):
{
"timestamp": "2024-01-15T10:23:45.123Z",
"level": "info",
"service": "[service-name]",
"version": "[git-sha-short]",
"trace_id": "[uuid-from-request-context]",
"span_id": "[span-uuid]",
"request_id": "[uuid-per-request]",
"message": "[human readable description]"
}
请求日志(每个 HTTP 请求都要输出):
{
"timestamp": "...",
"level": "info",
"service": "[service-name]",
"event": "http_request",
"method": "POST",
"path": "/api/v1/[resource]",
"status_code": 201,
"duration_ms": 45,
"user_id": "[uuid — DO NOT log PII directly]",
"request_id": "[uuid]",
"trace_id": "[uuid]"
}
错误日志(每个错误都要附带上下文输出):
{
"timestamp": "...",
"level": "error",
"service": "[service-name]",
"event": "error",
"error_code": "[application-error-code]",
"error_message": "[description — no sensitive data]",
"stack_trace": "[stack trace]",
"request_id": "[uuid]",
"trace_id": "[uuid]",
"context": {
"[key]": "[relevant context without PII]"
}
}
日志级别——何时使用
| 级别 | 使用场景 | 示例 |
|---|---|---|
error | 发生需要关注的故障——最终应触发值班告警 | 数据库查询失败、外部 API 返回 5xx、缺少必需的配置 |
warn | 发生意外情况,但服务仍在运行 | 失败后重试成功、预期命中时缓存未命中、即将达到速率限制 |
info | 重要的业务事件和请求生命周期 | 收到请求、已处理付款、用户已通过身份验证、任务已启动/完成 |
debug | 详细的诊断信息——默认在生产环境中关闭 | 查询参数、中间计算结果、缓存键查找 |
不要记录的内容
绝不要记录:
- 密码、令牌、API 密钥或机密信息(即使已哈希)
- 完整信用卡号或 PAN 数据
- 社会安全号码或政府颁发的身份证件号码
- 同一条日志中同时出现全名、出生日期和联系方式(个人身份信息聚合)
- 完整的请求/响应正文(改为按字段提取)
- 健康检查请求(噪声过多——从访问日志中排除
GET /health)
5. 分布式追踪设置
任何会调用其他服务的服务都必须实现分布式追踪。这有助于跨服务边界进行根因分析。
埋点检查清单
[ ] Tracing library installed:
- Go: go.opentelemetry.io/otel
- Python: opentelemetry-sdk, opentelemetry-instrumentation
- Node: @opentelemetry/sdk-node
- Java: opentelemetry-java-instrumentation
[ ] Tracer initialized at service startup with service name and version
[ ] Trace context propagated via W3C Trace Context headers:
traceparent: 00-[trace-id]-[span-id]-01
tracestate: [optional vendor-specific]
[ ] Automatic instrumentation enabled for:
[ ] Inbound HTTP/gRPC requests (creates root span)
[ ] Outbound HTTP/gRPC calls (creates child spans)
[ ] Database queries (creates child spans with sanitized query)
[ ] Cache operations (Redis, Memcached)
[ ] Message queue produce/consume
[ ] Custom spans added for:
[ ] Key business operations ([e.g. payment processing, user lookup])
[ ] Background jobs (each job execution = root span)
[ ] Third-party API calls with custom attributes
[ ] Span attributes to capture on all spans:
- user.id (if authenticated — no PII)
- deployment.environment (production/staging)
- service.version (git SHA)
- [service-specific key attributes]
[ ] Trace exporter configured to: [Datadog / Jaeger / Tempo / OTLP endpoint]
[ ] Sampling rate configured:
- Production: [1–10]% of requests (adjust based on volume and cost)
- Always sample: errors, slow requests (>p99 threshold), and 100% of [critical endpoint]
追踪埋点示例
# Python — OpenTelemetry example
from opentelemetry import trace
tracer = trace.get_tracer("[service-name]")
def process_payment(payment_data):
with tracer.start_as_current_span("process_payment") as span:
span.set_attribute("payment.amount_cents", payment_data["amount"])
span.set_attribute("payment.currency", payment_data["currency"])
# Never: span.set_attribute("payment.card_number", ...)
try:
result = _do_process(payment_data)
span.set_status(trace.StatusCode.OK)
return result
except PaymentError as e:
span.set_status(trace.StatusCode.ERROR, str(e))
span.record_exception(e)
raise
6. 告警规则规范
每条告警都必须包含:名称、条件、阈值、严重级别和明确的值班操作。没有明确操作的告警不应存在。
告警定义
| 告警名称 | 条件 | 阈值 | 严重级别 | 值班操作 |
|---|---|---|---|---|
[Service]HighErrorRate | 5xx 错误率,5 分钟滚动窗口 | 连续 2 个窗口 >1% | P1 | 检查近期部署;查看错误日志;参见运行手册 [link] |
[Service]CriticalErrorRate | 5xx 错误率,2 分钟滚动窗口 | >5% | P1 — 立即处理 | 同上——立即触发值班告警,不要等待 |
[Service]HighP99Latency | 关键端点的 p99 延迟 | 连续 3 分钟 >SLO 目标的 2 倍 | P2 | 检查数据库延迟、缓存命中率和上游依赖项 |
[Service]LatencySLOBreach | p99 延迟 | 连续 5 分钟 >SLO 目标 | P1 | SLO 消耗过快——触发值班告警;20 分钟内未解决则升级处理 |
[Service]HighCPU | CPU 使用率 | 持续 5 分钟 >80% | P2 | 检查流量是否激增;必要时扩容;检查是否有失控进程 |
[Service]HighMemory | 内存使用率 | 持续 5 分钟 >85% | P2 | 检查内存泄漏(尤其是在部署之后);若即将发生 OOM,则重启 Pod |
[Service]DBConnectionPoolHigh | 数据库连接池使用率 | >75% | P2 | 检查长时间运行的查询;考虑扩展服务或增大连接池 |
[Service]DLQDepthHigh | 死信队列深度 | >10 条消息 | P2 | 检查死信队列消息是否存在错误模式;修复缺陷,并在安全时重新投递 |
[Service]TrafficDropAnomaly | 与昨天同一时段相比的 RPS | 持续 5 分钟下降 >50% | P1 | 上游可能已宕机;检查调用方健康状况和负载均衡器 |
[Service]PrimaryActionSuccessRateDrop | [业务指标成功率] | 10 分钟内 <[95]% | P1 | [特定服务的操作,例如“检查支付服务提供商状态”] |
[Service]DownstreamDependencyErrors | 调用 [dependency] 的错误率 | 5 分钟内 >5% | P2 | 检查 [dependency] 状态页;如果有备用方案,则启用 |
告警配置示例
# Prometheus / Grafana alerting rules (adapt for your platform)
groups:
- name: [service-name]-alerts
rules:
- alert: [Service]HighErrorRate
expr: |
(
sum(rate([service]_http_requests_total{status=~"5.."}[5m]))
/
sum(rate([service]_http_requests_total[5m]))
) > 0.01
for: 2m
labels:
severity: critical
team: [team-name]
annotations:
summary: "High error rate on [Service Name]"
description: "Error rate is {{ $value | humanizePercentage }} (threshold: 1%)"
runbook_url: "[runbook link]"
- alert: [Service]HighP99Latency
expr: |
histogram_quantile(0.99,
sum(rate([service]_http_request_duration_seconds_bucket[5m])) by (le, endpoint)
) > [0.5]
for: 3m
labels:
severity: warning
team: [team-name]
annotations:
summary: "p99 latency elevated on [Service Name]"
description: "p99 latency on {{ $labels.endpoint }} is {{ $value | humanizeDuration }}"
runbook_url: "[runbook link]"
# Datadog monitor configuration (Python SDK or Terraform)
import datadog
datadog.initialize(api_key="[key]", app_key="[key]")
datadog.api.Monitor.create(
type="metric alert",
query=f"sum(last_5m):sum:{{service}}.http.errors{{service:[service-name]}} / sum:{{service}}.http.requests{{service:[service-name]}} > 0.01",
name="[Service] High Error Rate",
message="Error rate exceeded 1%. @pagerduty-[service-oncall]\n\nRunbook: [link]",
tags=["service:[service-name]", "team:[team-name]"],
options={
"thresholds": {"critical": 0.01, "warning": 0.005},
"notify_no_data": False,
"evaluation_delay": 60,
}
)
7. 仪表板布局规范
主要服务仪表板必须让人一眼看出“服务现在是否健康”。请使用以下布局:
┌─────────────────────────────────────────────────────────────────────┐
│ [SERVICE NAME] — Service Health Dashboard [Time range ▼] │
├───────────────┬───────────────┬───────────────┬─────────────────────┤
│ Error rate │ p99 Latency │ RPS (current)│ SLO budget remaining│
│ [BIG NUMBER] │ [BIG NUMBER] │ [BIG NUMBER] │ [BIG NUMBER / days] │
│ vs SLO: 0.1% │ vs SLO: 500ms│ vs avg: [N] │ [Error budget gauge]│
├───────────────┴───────────────┴───────────────┴─────────────────────┤
│ Error rate over time (24h) │
│ [Time series: 5xx rate line, SLO threshold line] │
├─────────────────────────────────┬───────────────────────────────────┤
│ Latency percentiles over time │ Request throughput over time │
│ [Lines: p50, p95, p99, p999] │ [Bars: RPS by endpoint] │
│ [SLO threshold horizontal line]│ │
├─────────────────────────────────┴───────────────────────────────────┤
│ Latency heatmap (all requests — shows distribution shape) │
├─────────────────────────────────┬───────────────────────────────────┤
│ CPU utilisation over time │ Memory utilisation over time │
│ [All instances/pods — lines] │ [All instances/pods — lines] │
│ [Alert threshold: 80%] │ [Alert threshold: 85%] │
├─────────────────────────────────┴───────────────────────────────────┤
│ DB: connection pool utilisation│ DB: query latency (p99 per query)│
├─────────────────────────────────┴───────────────────────────────────┤
│ [Business metric 1 over time] │ [Business metric 2 over time] │
│ e.g. Payment success rate │ e.g. Orders created/min │
└─────────────────────────────────┴───────────────────────────────────┘
第二个仪表板——依赖项健康状况:
┌─────────────────────────────────────────────────────────────────────┐
│ [SERVICE NAME] — Dependency Health │
├─────────────────────────────────────────────────────────────────────┤
│ For each dependency: error rate | latency | current status │
│ [Database] [N]% errors | [N]ms p99 | ● Healthy / ⚠ Degraded │
│ [Redis] [N]% errors | [N]ms p99 | ● Healthy │
│ [External API][N]% errors | [N]ms p99 | ● Healthy │
├─────────────────────────────────────────────────────────────────────┤
│ Outbound call latency over time (one line per dependency) │
├─────────────────────────────────────────────────────────────────────┤
│ Circuit breaker / fallback state (if implemented) │
└─────────────────────────────────────────────────────────────────────┘
8. 可观测性债务分析
如实评估当前缺少的内容,以及添加这些内容的优先级:
| 缺口 | 影响 | 优先级 | 工作量 | 负责人 | 目标日期 |
|---|---|---|---|---|---|
| [例如:没有分布式追踪——无法查看跨服务延迟] | 高——无法发现依赖项问题 | P1 | [2 天] | [姓名] | [日期] |
| [例如:没有业务指标告警——只有基础设施告警] | 高——业务故障悄无声息 | P1 | [1 天] | [姓名] | [日期] |
| [例如:日志是非结构化文本——无法搜索] | 中——事件调查速度慢 | P2 | [3 天] | [姓名] | [日期] |
| [例如:没有死信队列监控] | 中——消息处理失败未被察觉 | P2 | [4 小时] | [姓名] | [日期] |
| [例如:告警阈值未根据生产基线校准] | 中——告警疲劳或漏报 | P2 | [1 天] | [姓名] | [日期] |
| [例如:没有延迟热力图——平均值掩盖了异常值] | 低——更难发现尾部延迟问题 | P3 | [2 小时] | [姓名] | [日期] |
可观测性债务总计:[N] 项|预计工作量:[N 天]
质量检查
- 每条告警都有明确的值班处置措施——没有告警会只说“调查”,却不说明应先调查什么
- 告警阈值根据生产基线校准,而非使用模板中的默认值
- 已实现结构化日志——生产环境中没有非结构化文本日志行
- 明确排除日志中的个人身份信息(PII)——已有指定工程师确认
- 分布式追踪会在所有服务边界传递追踪 ID(通过测试请求验证)
- 主仪表板能在 10 秒内回答“服务是否健康?”——无需费力寻找合适的面板
- 除基础设施指标外,还跟踪业务指标——不只是四大黄金信号
- 可观测性债务事项都有负责人和日期——而不只是“有了更好”
反模式
- 不要创建没有明确值班处置措施的告警——只说“调查”的告警会让工程师逐渐忽视它
- 不要直接使用模板中的告警阈值,而不根据生产基线进行校准——未经校准的阈值会导致告警疲劳或漏掉事故
- 不要记录个人身份信息(PII)、令牌或密钥——如果日志规范没有明确列出绝不能记录的内容,就不完整
- 不要只衡量四大黄金信号,而不至少添加一条业务指标告警——基础设施健康状态可能显示正常,但业务关键路径却在悄无声息地故障
- 部署分布式追踪后,务必验证追踪 ID 能在所有服务边界传递——部分追踪比没有追踪更糟,因为它会生成不完整且具有误导性的追踪记录