logger_config.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # logger_config.py
  2. import logging
  3. import os
  4. from logging import handlers
  5. from datetime import datetime
  6. import sys
  7. class ColorFormatter(logging.Formatter):
  8. """自定义彩色日志格式化器(仅控制台输出带颜色,文件日志无颜色)"""
  9. # 终端颜色编码
  10. COLORS = {
  11. 'DEBUG': '\033[36m', # 青色
  12. 'INFO': '\033[32m', # 绿色
  13. 'WARNING': '\033[33m', # 黄色
  14. 'ERROR': '\033[31m', # 红色
  15. 'CRITICAL': '\033[41m', # 红底白字
  16. 'RESET': '\033[0m' # 重置颜色
  17. }
  18. # 日志级别对应图标
  19. ICONS = {
  20. 'DEBUG': '🐞',
  21. 'INFO': '✅',
  22. 'WARNING': '⚠️',
  23. 'ERROR': '❌',
  24. 'CRITICAL': '💥'
  25. }
  26. def format(self, record):
  27. # 为控制台添加颜色和图标,文件日志保持纯文本
  28. if hasattr(sys.stderr, 'isatty') and sys.stderr.isatty():
  29. # 彩色格式:[时间] [图标 级别] [模块:行号] 信息
  30. color = self.COLORS.get(record.levelname, self.COLORS['RESET'])
  31. icon = self.ICONS.get(record.levelname, '')
  32. record.levelname = f"{color}{icon} {record.levelname}{self.COLORS['RESET']}"
  33. record.msg = f"{color}{record.msg}{self.COLORS['RESET']}"
  34. # 调用父类格式化方法
  35. return super().format(record)
  36. def setup_logger(level=logging.DEBUG):
  37. """
  38. 配置日志器:
  39. 1. 自动创建logs文件夹
  40. 2. 日志文件带时间戳,按大小分割(10MB/个,保留5个备份)
  41. 3. 控制台输出带颜色/图标,文件日志纯文本(更规范)
  42. 4. 支持自定义日志级别(默认DEBUG,可传INFO/WARNING等)
  43. 5. 日志格式包含:时间、级别、进程ID、模块、行号、信息
  44. """
  45. # 1. 自动创建logs文件夹(不存在则创建)
  46. log_dir = "logs"
  47. os.makedirs(log_dir, exist_ok=True) # exist_ok=True:文件夹已存在时不报错
  48. # 2. 生成时间戳(格式:年月日_时分秒,如20260112_164530)
  49. timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") # 生成时间戳
  50. # 3. 定义带时间戳的日志文件路径
  51. log_file = os.path.join(log_dir, f"yjj_crawl_log_{timestamp}.txt")
  52. # 4. 创建日志器并设置级别
  53. logger = logging.getLogger("yjj_crawler")
  54. logger.setLevel(level)
  55. logger.propagate = False # 避免重复输出
  56. # 清空已有处理器(防止重复添加)
  57. if logger.handlers:
  58. logger.handlers.clear()
  59. # 5. 配置文件处理器(美化格式,保存到logs文件夹)
  60. file_handler = handlers.RotatingFileHandler(
  61. log_file,
  62. encoding="utf-8",
  63. maxBytes=10*1024*1024, # 单个日志文件最大10MB
  64. backupCount=5, # 最多保留5个备份日志文件
  65. mode="a" # 追加模式
  66. )
  67. # 文件日志美化格式:时间戳 | 级别 | 信息(带图标/模块标注)
  68. file_formatter = logging.Formatter(
  69. "[%(asctime)s] [%(levelname)-8s] [PID:%(process)d] [%(module)s:%(lineno)d] %(message)s",
  70. datefmt="%Y-%m-%d %H:%M:%S" # 精确到微秒
  71. )
  72. file_handler.setFormatter(file_formatter)
  73. logger.addHandler(file_handler)
  74. # 5. 配置控制台处理器(简洁格式,仅输出信息)
  75. console_handler = logging.StreamHandler()
  76. console_formatter = ColorFormatter(
  77. "[%(asctime)s] %(levelname)-8s %(message)s",
  78. datefmt="%H:%M:%S" # 控制台仅显示时分秒,更简洁
  79. )
  80. console_handler.setFormatter(console_formatter)
  81. # 6. 添加处理器到日志器
  82. console_handler.setFormatter(console_formatter)
  83. logger.addHandler(console_handler)
  84. return logger
  85. # 创建全局可调用的logger对象
  86. logger = setup_logger(level=logging.INFO)