本文目录导读:

我来详细介绍Python项目监控告警的配置方法,包括多种方案和实践建议。
基础监控告警方案
使用Python内置日志 + 邮件告警
import logging
import smtplib
from email.mime.text import MIMEText
from datetime import datetime
class AlertLogger:
def __init__(self, email_config):
self.email_config = email_config
self.setup_logger()
def setup_logger(self):
self.logger = logging.getLogger('alert_logger')
self.logger.setLevel(logging.INFO)
# 文件日志
fh = logging.FileHandler('app_monitor.log')
fh.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
self.logger.addHandler(fh)
def send_alert_email(self, subject, message, level='ERROR'):
"""发送告警邮件"""
if level in ['ERROR', 'CRITICAL']:
try:
msg = MIMEText(message)
msg['Subject'] = f"[{level}] {subject}"
msg['From'] = self.email_config['from']
msg['To'] = self.email_config['to']
with smtplib.SMTP(self.email_config['smtp_server'],
self.email_config['smtp_port']) as server:
server.starttls()
server.login(self.email_config['username'],
self.email_config['password'])
server.send_message(msg)
except Exception as e:
self.logger.error(f"发送告警邮件失败: {e}")
def alert(self, message, level='ERROR'):
"""记录并发送告警"""
self.logger.log(getattr(logging, level), message)
self.send_alert_email(
subject="应用告警",
message=message,
level=level
)
# 使用示例
email_config = {
'smtp_server': 'smtp.gmail.com',
'smtp_port': 587,
'username': 'your-email@gmail.com',
'password': 'your-password',
'from': 'your-email@gmail.com',
'to': 'alert-recipient@example.com'
}
alert_logger = AlertLogger(email_config)
alert_logger.alert("数据库连接失败", 'CRITICAL')
使用专业的监控工具
Prometheus + Grafana方案
# app/metrics.py
from prometheus_client import Counter, Histogram, Gauge, generate_latest
from flask import Flask, Response
import time
app = Flask(__name__)
# 定义指标
REQUEST_COUNT = Counter('http_requests_total', 'Total HTTP requests',
['method', 'endpoint', 'status'])
REQUEST_DURATION = Histogram('http_request_duration_seconds',
'HTTP request duration in seconds',
['method', 'endpoint'])
ACTIVE_USERS = Gauge('active_users', 'Current number of active users')
@app.route('/metrics')
def metrics():
"""暴露Prometheus指标"""
return Response(generate_latest(), mimetype='text/plain')
@app.before_request
def before_request():
request.start_time = time.time()
@app.after_request
def after_request(response):
# 记录请求计数
REQUEST_COUNT.labels(
method=request.method,
endpoint=request.path,
status=response.status_code
).inc()
# 记录请求耗时
duration = time.time() - request.start_time
REQUEST_DURATION.labels(
method=request.method,
endpoint=request.path
).observe(duration)
return response
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
Prometheus告警规则配置 (alert.rules.yml):
groups:
- name: python_app_alerts
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate detected"
description: "Error rate is {{ $value }} requests/s for the last 5 minutes"
- alert: SlowResponseTime
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 2
for: 5m
labels:
severity: warning
annotations:
summary: "Slow response time detected"
description: "P95 response time is {{ $value }} seconds"
- alert: LowActiveUsers
expr: active_users < 10
for: 10m
labels:
severity: info
annotations:
summary: "Low active users"
description: "Active users dropped to {{ $value }}"
Grafana告警配置
{
"alert": {
"conditions": [
{
"evaluator": {
"params": [5],
"type": "gt"
},
"operator": {
"type": "and"
},
"query": {
"params": ["A", "5m", "now"]
},
"reducer": {
"params": [],
"type": "avg"
},
"type": "query"
}
],
"executionErrorState": "alerting",
"for": "5m",
"frequency": "1m",
"handler": 1,
"name": "API Response Time Alert",
"noDataState": "no_data",
"notifications": [
{
"uid": "email_channel"
}
]
}
}
使用Sentry进行错误监控
# 安装: pip install sentry-sdk
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
sentry_sdk.init(
dsn="https://your-dsn@sentry.io/project-id",
integrations=[
FlaskIntegration(),
SqlalchemyIntegration(),
],
# 设置发送告警的规则
traces_sample_rate=1.0,
# 环境配置
environment="production",
# 错误级别配置
before_send=lambda event, hint: event if event.get('level') in ['error', 'fatal'] else None,
# 用户信息
with_locals=True,
)
# 设置告警规则示例
def configure_sentry_alerts():
"""配置Sentry告警"""
alerts_config = {
'error_count': {
'threshold': 10,
'interval': '1h',
'channels': ['email', 'slack']
},
'error_rate': {
'threshold': 5.0, # 百分比
'interval': '5m',
'channels': ['pagerduty']
}
}
return alerts_config
# 在代码中使用
try:
risky_operation()
except Exception as e:
sentry_sdk.capture_exception(e)
raise
使用健康检查API
# app/health.py
from flask import Flask, jsonify
import psutil
import platform
from datetime import datetime
app = Flask(__name__)
@app.route('/health')
def health_check():
"""健康检查端点"""
health_status = {
'status': 'healthy',
'timestamp': datetime.now().isoformat(),
'services': {}
}
# 检查数据库连接
health_status['services']['database'] = check_database()
# 检查Redis连接
health_status['services']['redis'] = check_redis()
# 检查系统资源
health_status['system'] = {
'cpu_usage': psutil.cpu_percent(),
'memory_usage': psutil.virtual_memory().percent,
'disk_usage': psutil.disk_usage('/').percent
}
# 设置整体状态
if any(s['status'] == 'unhealthy' for s in health_status['services'].values()):
health_status['status'] = 'unhealthy'
return jsonify(health_status)
@app.route('/readiness')
def readiness():
"""就绪检查"""
return jsonify({
'status': 'ready',
'timestamp': datetime.now().isoformat()
})
@app.route('/liveness')
def liveness():
"""存活检查"""
return jsonify({
'status': 'alive',
'timestamp': datetime.now().isoformat()
})
def check_database():
"""检查数据库连接"""
try:
# 测试数据库连接
db.session.execute('SELECT 1')
return {'status': 'healthy', 'message': 'Database connected'}
except Exception as e:
return {'status': 'unhealthy', 'message': str(e)}
def check_redis():
"""检查Redis连接"""
try:
redis_client.ping()
return {'status': 'healthy', 'message': 'Redis connected'}
except Exception as e:
return {'status': 'unhealthy', 'message': str(e)}
综合告警配置系统
# alert_manager.py
import json
import requests
from typing import Dict, List, Optional
from datetime import datetime
class AlertManager:
def __init__(self, config_file='alert_config.json'):
self.config = self.load_config(config_file)
self.alert_history = []
def load_config(self, config_file):
"""加载告警配置"""
with open(config_file, 'r') as f:
return json.load(f)
def send_alert(self, alert_type, message, severity='high'):
"""发送告警"""
alert = {
'type': alert_type,
'message': message,
'severity': severity,
'timestamp': datetime.now().isoformat()
}
# 记录告警历史
self.alert_history.append(alert)
# 根据配置发送到不同渠道
channels = self.config.get('alert_channels', {})
if 'email' in channels:
self.send_email_alert(alert)
if 'slack' in channels:
self.send_slack_alert(alert)
if 'webhook' in channels:
self.send_webhook_alert(alert)
if 'pagerduty' in channels:
self.send_pagerduty_alert(alert)
def send_slack_alert(self, alert):
"""发送Slack告警"""
webhook_url = self.config['slack_webhook_url']
payload = {
'text': f"[{alert['severity'].upper()}] {alert['type']}: {alert['message']}",
'attachments': [
{
'color': 'danger' if alert['severity'] == 'high' else 'warning',
'fields': [
{'title': 'Type', 'value': alert['type'], 'short': True},
{'title': 'Time', 'value': alert['timestamp'], 'short': True}
]
}
]
}
requests.post(webhook_url, json=payload)
def send_webhook_alert(self, alert):
"""发送Webhook告警"""
webhooks = self.config.get('webhooks', [])
for webhook in webhooks:
try:
requests.post(
webhook['url'],
json=alert,
headers={'Authorization': f"Bearer {webhook['token']}"}
)
except Exception as e:
print(f"发送Webhook告警失败: {e}")
def check_alert_thresholds(self, metrics):
"""检查告警阈值"""
alerts = []
# 检查错误率
if metrics.get('error_rate', 0) > self.config['error_rate_threshold']:
alerts.append({
'type': 'error_rate',
'message': f"Error rate {metrics['error_rate']:.2f}% exceeds threshold",
'severity': 'high'
})
# 检查响应时间
if metrics.get('response_time', 0) > self.config['response_time_threshold']:
alerts.append({
'type': 'response_time',
'message': f"Response time {metrics['response_time']:.2f}s exceeds threshold",
'severity': 'medium'
})
# 检查CPU使用率
if metrics.get('cpu_usage', 0) > self.config['cpu_threshold']:
alerts.append({
'type': 'cpu_usage',
'message': f"CPU usage {metrics['cpu_usage']:.1f}% exceeds threshold",
'severity': 'high'
})
return alerts
# 配置文件示例 (alert_config.json)
config_example = {
"alert_channels": ["email", "slack", "webhook"],
"slack_webhook_url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"webhooks": [
{
"url": "https://api.example.com/alerts",
"token": "your-token-here"
}
],
"thresholds": {
"error_rate": 5.0,
"response_time": 3.0,
"cpu_threshold": 80.0,
"memory_threshold": 85.0
},
"notification_rules": {
"high": {
"channels": ["email", "slack", "pagerduty"],
"repeat_interval": 300
},
"medium": {
"channels": ["slack"],
"repeat_interval": 600
},
"low": {
"channels": ["email"],
"repeat_interval": 3600
}
}
}
最佳实践建议
告警配置清单
# Python项目告警配置清单 ## 基础告警 - [ ] 应用崩溃/退出告警 - [ ] 数据库连接失败告警 - [ ] 内存使用率过高告警 - [ ] CPU使用率过高告警 ## API监控 - [ ] 响应时间超阈值告警 - [ ] 错误率过高告警 - [ ] 请求量异常告警 - [ ] 5xx错误告警 ## 业务监控 - [ ] 关键业务流程失败告警 - [ ] 数据一致性检查告警 - [ ] 任务队列积压告警 ## 基础设施 - [ ] 磁盘空间不足告警 - [ ] 网络连接问题告警 - [ ] 证书过期告警 ## 告警配置 - [ ] 配置告警级别(P0-P4) - [ ] 配置告警渠道(邮件/短信/IM) - [ ] 配置静默时间 - [ ] 配置升级机制
Docker Compose监控栈
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus/alert.rules.yml:/etc/prometheus/alert.rules.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--alertmanager.url=http://alertmanager:9093'
ports:
- "9090:9090"
alertmanager:
image: prom/alertmanager
volumes:
- ./alertmanager/config.yml:/etc/alertmanager/config.yml
ports:
- "9093:9093"
environment:
- SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL}
grafana:
image: grafana/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
- GF_INSTALL_PLUGINS=grafana-piechart-panel
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
- ./grafana/datasources:/etc/grafana/provisioning/datasources
ports:
- "3000:3000"
depends_on:
- prometheus
sentry:
image: sentry
environment:
- SENTRY_SECRET_KEY=${SENTRY_SECRET_KEY}
- SENTRY_POSTGRES_HOST=postgres
- SENTRY_DB_USER=sentry
- SENTRY_DB_PASSWORD=${SENTRY_DB_PASSWORD}
- SENTRY_REDIS_HOST=redis
ports:
- "9000:9000"
depends_on:
- postgres
- redis
volumes:
prometheus_data:
grafana_data:
配置Python项目监控告警的关键步骤:
- 选择监控方案:根据项目规模选择合适方案
- 定义告警规则:明确哪些情况需要告警
- 配置通知渠道:选择适合团队的通信方式
- 设置分级告警:区分紧急程度
- 测试告警流程:确保告警能正常触发
- 持续优化:根据实际情况调整阈值和规则
建议从基础告警开始,逐步完善监控体系,避免告警疲劳。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播