health.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. """
  2. 系统健康检查模块
  3. 提供系统各组件健康状态检查和系统信息获取功能
  4. """
  5. import logging
  6. import platform
  7. import psutil
  8. import os
  9. import socket
  10. from datetime import datetime
  11. from flask import current_app, jsonify
  12. from app.services.db_healthcheck import check_database_connection
  13. from app.services.neo4j_driver import Neo4jDriver
  14. logger = logging.getLogger(__name__)
  15. def check_neo4j_connection():
  16. """
  17. 检查Neo4j数据库连接状态
  18. Returns:
  19. bool: 连接成功返回True,失败返回False
  20. """
  21. try:
  22. with Neo4jDriver().get_session() as session:
  23. # 执行简单查询确认连接
  24. session.run("RETURN 1")
  25. return True
  26. except Exception as e:
  27. logger.error(f"Neo4j数据库连接失败: {str(e)}")
  28. return False
  29. def check_system_health():
  30. """检查系统各个组件的健康状态"""
  31. health_status = {
  32. 'database': check_database_connection(),
  33. 'neo4j': Neo4jDriver().verify_connectivity(),
  34. 'environment': current_app.config['FLASK_ENV'],
  35. 'platform': current_app.config['PLATFORM']
  36. }
  37. # 检查所有组件是否都正常
  38. all_healthy = all([health_status['database'], health_status['neo4j']])
  39. return {
  40. 'status': 'healthy' if all_healthy else 'unhealthy',
  41. 'components': health_status
  42. }
  43. def get_system_info():
  44. """
  45. 获取系统运行环境信息
  46. 包括操作系统、Python版本、CPU使用率、内存使用情况等
  47. Returns:
  48. dict: 包含系统信息的字典
  49. """
  50. try:
  51. # 获取基本系统信息
  52. sys_info = {
  53. "os": {
  54. "name": platform.system(),
  55. "version": platform.version(),
  56. "platform": platform.platform(),
  57. },
  58. "python": {
  59. "version": platform.python_version(),
  60. "implementation": platform.python_implementation(),
  61. },
  62. "network": {
  63. "hostname": socket.gethostname(),
  64. "ip": socket.gethostbyname(socket.gethostname()),
  65. },
  66. "resources": {
  67. "cpu": {
  68. "cores": psutil.cpu_count(logical=False),
  69. "logical_cores": psutil.cpu_count(logical=True),
  70. "usage_percent": psutil.cpu_percent(interval=0.1),
  71. },
  72. "memory": {
  73. "total": _format_bytes(psutil.virtual_memory().total),
  74. "available": _format_bytes(psutil.virtual_memory().available),
  75. "used": _format_bytes(psutil.virtual_memory().used),
  76. "percent": psutil.virtual_memory().percent,
  77. },
  78. "disk": {
  79. "total": _format_bytes(psutil.disk_usage("/").total),
  80. "used": _format_bytes(psutil.disk_usage("/").used),
  81. "free": _format_bytes(psutil.disk_usage("/").free),
  82. "percent": psutil.disk_usage("/").percent,
  83. },
  84. },
  85. "application": {
  86. "environment": current_app.config['FLASK_ENV'],
  87. "debug_mode": current_app.config['DEBUG'],
  88. "port": current_app.config['PORT'],
  89. "platform": current_app.config['PLATFORM'],
  90. "bucket_name": current_app.config['BUCKET_NAME'],
  91. "prefix": current_app.config['PREFIX'],
  92. # 不返回敏感信息如密码、密钥等
  93. }
  94. }
  95. return sys_info
  96. except Exception as e:
  97. logger.error(f"获取系统信息失败: {str(e)}")
  98. return {"error": str(e)}
  99. def _format_bytes(bytes_value):
  100. """
  101. 将字节数格式化为易读形式
  102. Args:
  103. bytes_value: 字节数
  104. Returns:
  105. str: 格式化后的字符串,如"1.23 GB"
  106. """
  107. for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
  108. if bytes_value < 1024 or unit == 'TB':
  109. return f"{bytes_value:.2f} {unit}"
  110. bytes_value /= 1024