167 lines
4.7 KiB
Python
167 lines
4.7 KiB
Python
"""
|
||
系统监控和健康检查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
|