handler.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. 日志模块 - 按天生成独立日志文件
  5. """
  6. import logging
  7. import os
  8. from datetime import datetime
  9. from typing import Optional
  10. BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  11. LOG_DIR = os.path.join(BASE_DIR, "logs")
  12. def get_logger(name: str = "sync") -> logging.Logger:
  13. """
  14. 获取日志记录器
  15. 每次调用都检查日期,确保正确切换
  16. Args:
  17. name: 日志记录器名称
  18. Returns:
  19. 日志记录器实例
  20. """
  21. today: str = datetime.now().strftime("%Y-%m-%d")
  22. # 不再缓存 logger,每次都重新创建,避免日期切换问题
  23. logger: logging.Logger = logging.getLogger(name)
  24. logger.setLevel(logging.INFO)
  25. logger.propagate = False
  26. # 清除所有 handlers
  27. logger.handlers.clear()
  28. os.makedirs(LOG_DIR, exist_ok=True)
  29. # 按天生成日志文件:sync-2026-03-05.log
  30. log_file: str = os.path.join(LOG_DIR, f"{name}-{today}.log")
  31. # 文件处理器
  32. try:
  33. file_handler: logging.FileHandler = logging.FileHandler(
  34. log_file, encoding="utf-8"
  35. )
  36. except OSError as e:
  37. raise RuntimeError(f"无法创建日志文件 {log_file}: {e}") from e
  38. file_handler.setLevel(logging.INFO)
  39. # 控制台处理器
  40. console_handler: logging.StreamHandler = logging.StreamHandler()
  41. console_handler.setLevel(logging.INFO)
  42. # 格式化器
  43. formatter: logging.Formatter = logging.Formatter(
  44. "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
  45. datefmt="%Y-%m-%d %H:%M:%S"
  46. )
  47. file_handler.setFormatter(formatter)
  48. console_handler.setFormatter(formatter)
  49. logger.addHandler(file_handler)
  50. logger.addHandler(console_handler)
  51. return logger
  52. def clean_old_logs(days: int = 30) -> int:
  53. """
  54. 清理超过指定天数的旧日志文件
  55. Args:
  56. days: 保留天数
  57. Returns:
  58. 删除的文件数量
  59. """
  60. deleted_count: int = 0
  61. try:
  62. if not os.path.exists(LOG_DIR):
  63. return 0
  64. now: datetime = datetime.now()
  65. for filename in os.listdir(LOG_DIR):
  66. if not filename.endswith(".log"):
  67. continue
  68. filepath: str = os.path.join(LOG_DIR, filename)
  69. try:
  70. file_mtime: datetime = datetime.fromtimestamp(
  71. os.path.getmtime(filepath)
  72. )
  73. file_age: int = (now - file_mtime).days
  74. if file_age > days:
  75. os.remove(filepath)
  76. deleted_count += 1
  77. print(f"已删除旧日志: {filename}")
  78. except OSError as e:
  79. print(f"删除日志文件失败 {filename}: {e}")
  80. except Exception as e:
  81. print(f"清理日志失败: {e}")
  82. return deleted_count