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
|