Selva-git-22/Advanced-Observability-and-Incident-Response-platform
GitHub: Selva-git-22/Advanced-Observability-and-Incident-Response-platform
该平台将 Prometheus 指标、OpenSearch 日志和 Jaeger 分布式追踪统一集成,帮助运维团队快速定位跨服务故障并支持自动修复。
Stars: 0 | Forks: 0
# 可观测性与事件响应平台






我们总是被打个措手不及。服务会降级,用户会抱怨,而我们在每次事件发生的前 40 分钟里,只能试图弄清楚问题到底出在*哪里*——在单个 EC2 实例上跟踪日志,猜测哪个服务出了问题,手动在三个不同的工具间关联时间戳。
所以我构建了这个平台。目标不是使用每一个花哨的工具,而是将 metrics、logs 和 traces 集中到一个地方,让你在凌晨 2 点系统出问题时能够真正快速地在它们之间切换。
## 问题所在
AWS 上的三个微服务(Node.js API、Python backend、Go worker)。没有集中式日志记录。只有在 CPU 达到 100% 时才触发的告警——而此时损害已经造成。没有分布式追踪,因此当请求失败时,我们根本不知道它是死在 API、backend,还是两者之间的某个地方。
对于任何非简单的事件,平均解决时间都徘徊在 **45–60 分钟**左右。这段时间大部分都花在了排查上,而不是修复上。
## 架构
| 组件 | 角色 |
|---|---|
| **Prometheus** | 抓取并存储时间序列 metrics |
| **Grafana** | 用于查看 metrics、logs 和 traces 的统一仪表盘 |
| **Fluent Bit** | 从所有服务收集并发送 logs |
| **OpenSearch** | 集中式日志存储和搜索 |
| **Jaeger** | 通过 OpenTelemetry 实现跨服务分布式追踪 |
| **Alertmanager** | 将告警路由到 Slack 和 AWS SNS |
| **AWS Lambda** | 针对已知故障模式的自动修复 |
部署在 **AWS EC2 (t3.xlarge)** 上,Prometheus metrics 在本地保留 30 天,并通过 Thanos 发送到 S3 进行长期存储。
## 快速开始
### 前置条件
- Docker `>= 24.x` 和 Docker Compose `>= 2.x`
- 已配置 AWS CLI (`aws configure`)
- 最少 4 vCPU / 16 GB RAM
### 克隆仓库
```
git clone https://github.com/your-username/observability-platform.git
cd observability-platform
```
### 启动核心栈
```
docker compose up -d
```
### 添加日志和追踪
```
docker compose up -d opensearch opensearch-dashboards fluent-bit jaeger
```
### 验证一切是否运行正常
```
docker compose ps
```
## 服务 URL
| 服务 | URL | 凭据 |
|---|---|---|
| Grafana | `http://localhost:3000` | `admin / admin123` |
| Prometheus | `http://localhost:9090` | — |
| Alertmanager | `http://localhost:9093` | — |
| Jaeger UI | `http://localhost:16686` | — |
| OpenSearch Dashboards | `http://localhost:5601` | — |
| OpenSearch API | `http://localhost:9200` | — |
| Node Exporter | `http://localhost:9100/metrics` | — |
## 📊 Metrics — Prometheus + Grafana
Prometheus 每 `15s` 抓取一次应用的 `/metrics` endpoint。Node Exporter 负责处理主机级别的 metrics —— CPU、内存、磁盘、网络。
**CPU 使用率 %**
```
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
```
**p95 响应延迟**
```
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
```
**错误率 %**
```
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m])) * 100
```
**SLO 消耗率** - 高于 `1` 的值意味着错误预算将在月底前耗尽
```
(1 - job:http_success_rate:ratio_rate1h) / (1 - 0.999)
```
**可导入 Grafana 的社区仪表盘:**
| 仪表盘 | ID |
|---|---|
| Node Exporter Full | `1860` |
| Prometheus 2.0 Overview | `3662` |
## 🪵 Logging - Fluent Bit + OpenSearch
Fluent Bit 会追踪 Docker 容器日志和应用日志文件,使用 `hostname` 和 `environment` 元数据丰富它们,并发送到 OpenSearch。日志被索引到每日索引 (`app-logs-YYYY.MM.DD`) 中,并通过 ISM 生命周期策略在 **30 天**后自动删除。
`fluent-bit/fluent-bit.conf` 中的核心输出块:
```
[OUTPUT]
Name opensearch
Match *
Host opensearch
Port 9200
Logstash_Format On
Logstash_Prefix app-logs
Retry_Limit False
```
## 分布式追踪 - Jaeger + OpenTelemetry
只需埋点一次,即可获取所有操作的 traces —— HTTP、Express、数据库调用、gRPC。
**Node.js**
```
npm install @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-http
```
**Python**
```
pip install opentelemetry-sdk opentelemetry-instrumentation
```
### 带来最大改变的部分
将 trace ID 注入到每一行日志中。当你在 OpenSearch 中发现错误时,点击 `trace_id` 就会直接跳转到 Jaeger,查看跨所有服务的完整请求旅程。在此之前,跨服务故障意味着手动关联时间戳和猜测。有了它之后,通常只需 **不到 2 分钟**。
```
class TraceIdFilter(logging.Filter):
def filter(self, record):
span = trace.get_current_span()
ctx = span.get_span_context()
record.trace_id = format(ctx.trace_id, '032x') if ctx.is_valid else 'no-trace'
record.span_id = format(ctx.span_id, '016x') if ctx.is_valid else 'no-span'
return True
```
## 告警 - Alertmanager
我们旧告警系统的问题不在于工具本身——告警触发得太晚,而且会发送给所有人,所以它们实际上被忽略了。我们围绕三个原则重建了它:
- **针对症状告警,而不是原因。** 高错误率很重要。高 CPU 可能并不重要。
- **路由给正确的人。** DB 告警 → DBA 渠道。基础设施 → 运维。不要发给所有人。
- **在告警中提供上下文。** 摘要、受影响的服务、runbook 链接——值班工程师不应该到处去翻找信息。
`alertmanager/alertmanager.yml` 中的路由配置:
```
route:
routes:
- match:
severity: critical
receiver: slack-critical # Immediate Slack + PagerDuty
- match:
service: database
receiver: dba-team # DBA channel only
- match_re:
alertname: ^(NodeDown|DiskFull|HighCPU)$
receiver: ops-team
```
### SLO 消耗率告警
不是在突破错误预算后才告警,而是当我们的消耗速度足以在 **5 天**内耗尽预算时,消耗率告警就会触发。这就是主动与被动的区别。
```
- alert: SLOBudgetBurnRateHigh
expr: |
(1 - job:http_success_rate:ratio_rate1h) > (1 - 0.999) * 14.4
for: 2m
labels:
severity: critical
```
## 自动修复 — AWS Lambda
两个 Lambda 函数会自动处理最常见的故障模式:
- **`auto_remediate_ecs.py`** - 在触发 `ServiceDown` 告警时强制进行新的 ECS 部署。无论结果如何都会通知 Slack;如果修复本身失败,则升级交由人工处理。
- **`auto_scale_ec2.py`** - 在 CPU 过高告警时向 ASG 添加两个实例,并在问题解决时自动缩容。
这些涵盖了大约 **30% 的事件**。并非所有问题都能自动修复,但那些能够自动修复的问题不应该需要叫醒某个人。
### 部署
```
cd lambda
zip auto_remediate_ecs.zip auto_remediate_ecs.py
```
```
aws lambda create-function \
--function-name auto-remediate-ecs \
--runtime python3.11 \
--role arn:aws:iam::${ACCOUNT_ID}:role/lambda-remediation-role \
--handler auto_remediate_ecs.lambda_handler \
--zip-file fileb://auto_remediate_ecs.zip \
--timeout 60
```
```
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:${ACCOUNT_ID}:ops-alerts \
--protocol lambda \
--notification-endpoint ${LAMBDA_ARN}
```
## 实用命令
无需重启即可重载 Prometheus 配置:
```
curl -X POST http://localhost:9090/-/reload
```
端到端测试完整的告警流水线:
```
curl -X POST http://localhost:9093/api/v1/alerts \
-H "Content-Type: application/json" \
-d '[{
"labels": { "alertname": "TestAlert", "severity": "warning" },
"annotations": { "summary": "Pipeline check — ignore this" }
}]'
```
检查所有抓取目标是否健康:
```
curl -s http://localhost:9090/api/v1/targets | python3 -m json.tool
```
追踪任意服务的实时日志:
```
docker compose logs -f prometheus
docker compose logs -f fluent-bit
docker compose logs -f jaeger
```
## 仓库结构
```
observability-platform/
├── docker-compose.yml
├── prometheus/
│ ├── prometheus.yml
│ └── rules/
│ ├── alerts.yml # Infrastructure + app + SLO alerts
│ └── slo.yml # Error budget recording rules
├── grafana/
│ └── provisioning/
│ ├── datasources/ # Prometheus, OpenSearch, Jaeger auto-wired
│ └── dashboards/
├── alertmanager/
│ └── alertmanager.yml # Routing + Slack + SNS config
├── fluent-bit/
│ ├── fluent-bit.conf
│ └── parsers.conf
├── lambda/
│ ├── auto_remediate_ecs.py
│ └── auto_scale_ec2.py
├── thanos/
│ └── objstore.yml # S3 long-term metrics storage
└── runbooks/
└── high-error-rate.md
```
## 正式上线前
- 更改 Grafana 管理员密码 (`GF_SECURITY_ADMIN_PASSWORD`)
- 启用 OpenSearch TLS —— `plugins.security.disabled=true` 仅适用于本地开发
- 将你的 Slack webhook URL 添加到 `alertmanager/alertmanager.yml`
- 在生产环境中将 Jaeger `badger` 存储替换为 OpenSearch (`SPAN_STORAGE_TYPE=elasticsearch`)
- 将 Lambda IAM 角色收紧为最小权限
- 更新 `prometheus/rules/slo.yml` 中的 SLO 目标,以匹配实际的承诺
## 技术栈版本
| 工具 | 版本 |
|---|---|
| Prometheus | `2.47.0` |
| Grafana | `10.2.0` |
| Alertmanager | `0.26.0` |
| OpenSearch | `2.11.0` |
| Fluent Bit | `2.2.0` |
| Jaeger | `1.51` |
| Node Exporter | `1.7.0` |
## 📄 许可证
MIT
标签:API集成, Grafana, 可观测性, 用户代理, 自定义请求头, 请求拦截, 运维监控, 链路追踪