log.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import logging
  2. import os
  3. import queue
  4. import threading
  5. import time
  6. from logging.handlers import RotatingFileHandler
  7. from colorama import init
  8. class LogColors:
  9. colors = [
  10. "\033[0m", # RESET
  11. "\033[36m", # CYAN
  12. "\033[92m", # LIGHT_GREEN
  13. "\033[94m", # LIGHT_BLUE
  14. "\033[95m", # LIGHT_MAGENTA
  15. "\033[96m", # LIGHT_CYAN
  16. "\033[90m", # DARK_GRAY
  17. "\033[93m", # LIGHT_YELLOW
  18. "\033[32m", # GREEN
  19. "\033[33m", # YELLOW
  20. "\033[34m", # BLUE
  21. "\033[35m", # MAGENTA
  22. "\033[91m", # LIGHT_RED
  23. "\033[37m", # WHITE
  24. "\033[31m", # RED
  25. ]
  26. @classmethod
  27. def get_color(cls, index):
  28. return cls.colors[index]
  29. class Logger:
  30. def __init__(self, log_file=r'Log\app.log', file_log_level=logging.DEBUG, console_log_level=logging.DEBUG):
  31. init(autoreset=True) # 初始化colorama并自动重置颜色
  32. # 创建日志文件目录(如果不存在)
  33. log_dir = os.path.dirname(log_file)
  34. if not os.path.exists(log_dir):
  35. os.makedirs(log_dir)
  36. # 如果日志文件不存在,创建一个新的
  37. if not os.path.exists(log_file):
  38. with open(log_file, 'a'):
  39. pass
  40. # 创建Logger对象
  41. self.logger = logging.getLogger('Logger')
  42. self.logger.setLevel(logging.DEBUG)
  43. # 创建文件处理器,并设置日志级别和格式
  44. max_bytes = 5 * 1024 * 1024 # 最大文件大小 5MB
  45. backup_count = 5 # 保留的日志文件数量
  46. file_handler = RotatingFileHandler(log_file, maxBytes=max_bytes, backupCount=backup_count)
  47. file_handler.setLevel(file_log_level)
  48. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  49. file_handler.setFormatter(formatter)
  50. self.logger.addHandler(file_handler)
  51. # 创建控制台处理器,并设置日志级别和格式
  52. console_handler = logging.StreamHandler()
  53. console_handler.setLevel(console_log_level)
  54. console_handler.setFormatter(formatter)
  55. self.logger.addHandler(console_handler)
  56. self.log_queue = queue.Queue()
  57. self.thread = threading.Thread(target=self._log_worker)
  58. self.thread.start()
  59. def get_logger(self):
  60. return self.logger
  61. def _log_worker(self):
  62. while True:
  63. try:
  64. log_action = self.log_queue.get()
  65. if log_action is None:
  66. break
  67. log_action() # 执行存储的 lambda 函数
  68. except Exception as e:
  69. self.logger.error(f"Error in log worker: {e}")
  70. time.sleep(0.01)
  71. def debug(self, message):
  72. self.log_queue.put(lambda: self.logger.debug(f"{LogColors.get_color(8)}{message}{LogColors.get_color(0)}")) # LIGHT_MAGENTA
  73. def info(self, message, color_index=13):
  74. self.log_queue.put(lambda: self.logger.info(f"{LogColors.get_color(color_index)}{message}{LogColors.get_color(0)}"))
  75. def warning(self, message):
  76. self.log_queue.put(lambda: self.logger.warning(f"{LogColors.get_color(9)}{message}{LogColors.get_color(0)}")) # YELLOW
  77. def error(self, message):
  78. self.log_queue.put(lambda: self.logger.error(f"{LogColors.get_color(14)}{message}{LogColors.get_color(0)}")) # RED
  79. def exception(self, message):
  80. self.log_queue.put(lambda: self.logger.exception(f"{LogColors.get_color(14)}{message}{LogColors.get_color(0)}")) # RED
  81. def critical(self, message):
  82. self.log_queue.put(lambda: self.logger.critical(f"{LogColors.get_color(12)}{message}{LogColors.get_color(0)}")) # MAGENTA
  83. # 使用示例
  84. logger = Logger(log_file=r'Log\app.log', file_log_level=logging.DEBUG, console_log_level=logging.DEBUG)