# 监控与日志管理:构建可观测性体系的完整实践指南
## 引言
在现代分布式系统中,监控与日志管理不再是可选项,而是必需品。当你的应用运行在多个服务器、容器或云实例上时,如何快速定位问题、理解系统行为、预测潜在风险?答案就是建立完善的可观测性体系。
本文将带你从基础概念到生产实践,全面掌握监控与日志管理的核心技能。
## 一、监控的三大支柱
### 1. 指标(Metrics)
指标是系统的量化数据,通常以时间序列形式存储。常见的指标包括:
- **CPU 使用率**:反映计算资源消耗
- **内存占用**:监控内存泄漏风险
- **请求延迟**:衡量系统响应速度
- **错误率**:评估系统稳定性
### 2. 日志(Logs)
日志记录系统发生的具体事件,是排查问题的第一手资料。好的日志应该:
- 结构化(JSON 格式)
- 包含上下文信息(请求 ID、用户 ID)
- 分级明确(DEBUG、INFO、WARN、ERROR)
### 3. 追踪(Traces)
分布式追踪帮助理解请求在系统中的完整流转路径,对于微服务架构尤为重要。
## 二、实用监控工具链
### Prometheus + Grafana 组合
Prometheus 是开源监控的事实标准,Grafana 提供强大的可视化能力。
**Prometheus 配置示例:**
```yaml
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
- job_name: 'application'
static_configs:
- targets: ['localhost:8080']
```
**关键监控指标:**
```promql
# CPU 使用率
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 内存使用率
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
# 磁盘使用率
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100
```
### 日志收集:ELK Stack
Elasticsearch + Logstash + Kibana 是经典的日志解决方案。
**Filebeat 配置示例:**
```yaml
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/application/*.log
fields:
environment: production
service: web-api
output.elasticsearch:
hosts: ["localhost:9200"]
index: "logs-%{+YYYY.MM.dd}"
```
## 三、生产环境的监控策略
### 1. 分层监控
```
┌─────────────────┐
│ 业务监控层 │ ← 订单量、转化率、用户活跃度
├─────────────────┤
│ 应用监控层 │ ← QPS、延迟、错误率、GC 次数
├─────────────────┤
│ 系统监控层 │ ← CPU、内存、磁盘、网络
├─────────────────┤
│ 基础设施层 │ ← 宿主机、容器、云服务状态
└─────────────────┘
```
### 2. 告警规则设计
**避免告警疲劳的原则:**
- 设置合理的阈值(不要过于敏感)
- 使用多条件组合(持续 N 分钟超过阈值)
- 分级告警(Warning → Critical → Page)
**Prometheus 告警规则示例:**
```yaml
# alerting-rules.yml
groups:
- name: application-alerts
rules:
- alert: HighErrorRate
expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "错误率超过 5%"
description: "服务 {{ $labels.job }} 的错误率持续 5 分钟超过 5%"
- alert: HighLatency
expr: histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 1
for: 10m
labels:
severity: warning
annotations:
summary: "P95 延迟超过 1 秒"
```
## 四、日志最佳实践
### 1. 结构化日志
```python
# Python 示例
import logging
import json
class JSONFormatter(logging.Formatter):
def format(self, record):
log_data = {
'timestamp': self.formatTime(record),
'level': record.levelname,
'logger': record.name,
'message': record.getMessage(),
'module': record.module,
'function': record.funcName,
'line': record.lineno,
}
# 添加额外字段
if hasattr(record, 'request_id'):
log_data['request_id'] = record.request_id
if hasattr(record, 'user_id'):
log_data['user_id'] = record.user_id
return json.dumps(log_data, ensure_ascii=False)
logger = logging.getLogger('app')
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)
# 使用示例
logger.info('用户登录成功', extra={'request_id': 'abc123', 'user_id': 456})
```
### 2. 日志采样
在高流量场景下,全量日志可能带来存储和性能问题:
```python
import random
def should_sample(sample_rate=0.1):
"""10% 采样率"""
return random.random() < sample_rate
if should_sample():
logger.debug("详细调试信息")
```
### 3. 敏感信息脱敏
```python
import re
def mask_sensitive_data(log_message):
# 脱敏邮箱
log_message = re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
'[EMAIL_MASKED]', log_message)
# 脱敏手机号
log_message = re.sub(r'\b1[3-9]\d{9}\b', '[PHONE_MASKED]', log_message)
# 脱敏身份证号
log_message = re.sub(r'\b\d{17}[\dXx]\b', '[ID_MASKED]', log_message)
return log_message
```
## 五、实战:搭建完整的监控告警系统
### Docker Compose 部署
```yaml
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
volumes:
- grafana-data:/var/lib/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
alertmanager:
image: prom/alertmanager:latest
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
ports:
- "9093:9093"
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
grafana-data:
```
### 告警通知集成
```yaml
# alertmanager.yml
global:
smtp_smarthost: 'smtp.example.com:587'
smtp_from: 'alerts@example.com'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'default'
routes:
- match:
severity: critical
receiver: 'pagerduty'
receivers:
- name: 'default'
email_configs:
- to: 'team@example.com'
- name: 'pagerduty'
pagerduty_configs:
- service_key: 'your-pagerduty-key'
```
## 六、监控指标的健康检查清单
定期 review 以下指标,确保系统健康:
- [ ] CPU 使用率 < 80%(持续 5 分钟)
- [ ] 内存使用率 < 85%
- [ ] 磁盘使用率 < 90%
- [ ] 应用错误率 < 1%
- [ ] P95 延迟 < 500ms
- [ ] 日志增长速率正常
- [ ] 告警规则有效且无误报
- [ ] 备份和恢复流程已测试
## 结语
监控与日志管理是一个持续优化的过程。随着系统规模的增长和业务的变化,你需要不断调整监控策略、优化告警规则、完善日志规范。
记住:好的监控不是告诉你系统"坏了",而是在问题发生前就给你预警;好的日志不是事后的"验尸报告",而是帮助你快速理解系统行为的"黑匣子"。
从今天开始,建立你的可观测性体系,让系统运行在阳光之下。
---
**延伸阅读:**
- Prometheus 官方文档:https://prometheus.io/docs/
- Grafana 仪表盘模板:https://grafana.com/grafana/dashboards/
- ELK Stack 实战指南:https://www.elastic.co/guide/
---
*本文首发于李炫炫的技术博客,欢迎转载,请注明出处。*
文章评论