Kamixitong/app/api/monitoring.py
2025-12-12 11:35:14 +08:00

167 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
系统监控和健康检查API
提供系统状态、性能指标和健康检查功能
"""
from flask import jsonify, current_app
from datetime import datetime, timedelta
import psutil
import time
from app import db
from app.models import License, Product, Order, Ticket, Device
from . import api_bp
@api_bp.route('/health', methods=['GET'])
def health_check():
"""
健康检查端点
返回系统的基本健康状态
"""
try:
# 检查数据库连接
db.session.execute('SELECT 1')
health_status = {
'status': 'healthy',
'timestamp': datetime.utcnow().isoformat(),
'version': current_app.config.get('API_VERSION', 'v1'),
'environment': 'production' if not current_app.debug else 'development'
}
return jsonify({
'success': True,
'data': health_status
}), 200
except Exception as e:
current_app.logger.error(f"健康检查失败: {str(e)}")
return jsonify({
'success': False,
'status': 'unhealthy',
'error': str(e),
'timestamp': datetime.utcnow().isoformat()
}), 503
@api_bp.route('/metrics', methods=['GET'])
def system_metrics():
"""
系统性能指标端点
返回系统的性能指标Prometheus格式
"""
try:
# CPU使用率
cpu_percent = psutil.cpu_percent(interval=1)
# 内存使用情况
memory = psutil.virtual_memory()
# 磁盘使用情况
disk = psutil.disk_usage('/')
# 数据库统计
stats = get_database_stats()
metrics = {
'system': {
'cpu_usage_percent': cpu_percent,
'memory': {
'total': memory.total,
'available': memory.available,
'used': memory.used,
'percent': memory.percent
},
'disk': {
'total': disk.total,
'used': disk.used,
'free': disk.free,
'percent': (disk.used / disk.total) * 100
}
},
'database': stats,
'timestamp': datetime.utcnow().isoformat()
}
return jsonify({
'success': True,
'data': metrics
}), 200
except Exception as e:
current_app.logger.error(f"获取系统指标失败: {str(e)}")
return jsonify({
'success': False,
'error': str(e),
'timestamp': datetime.utcnow().isoformat()
}), 500
def get_database_stats():
"""获取数据库统计信息"""
try:
# 卡密统计
total_licenses = License.query.count()
active_licenses = License.query.filter_by(status=1).count()
expired_licenses = License.query.filter_by(status=2).count()
# 产品统计
total_products = Product.query.filter_by(status=1).count()
# 订单统计
total_orders = Order.query.count()
paid_orders = Order.query.filter_by(status=1).count()
pending_orders = Order.query.filter_by(status=0).count()
# 工单统计
total_tickets = Ticket.query.count()
open_tickets = Ticket.query.filter_by(status__in=[0, 1]).count()
# 设备统计
total_devices = Device.query.filter_by(status=1).count()
# 最近24小时的订单
yesterday = datetime.utcnow() - timedelta(days=1)
recent_orders = Order.query.filter(Order.create_time >= yesterday).count()
return {
'licenses': {
'total': total_licenses,
'active': active_licenses,
'expired': expired_licenses,
'inactive': total_licenses - active_licenses - expired_licenses
},
'products': {
'total': total_products
},
'orders': {
'total': total_orders,
'paid': paid_orders,
'pending': pending_orders,
'recent_24h': recent_orders
},
'tickets': {
'total': total_tickets,
'open': open_tickets
},
'devices': {
'total': total_devices
}
}
except Exception as e:
current_app.logger.error(f"获取数据库统计失败: {str(e)}")
return {}
@api_bp.route('/ping', methods=['GET'])
def ping():
"""
简单的ping端点
用于快速检查服务是否可用
"""
return jsonify({
'success': True,
'message': 'pong',
'timestamp': datetime.utcnow().isoformat()
}), 200