health.py 3.9 KB

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