#!/usr/bin/python # -*- coding: UTF-8 -*- # # # author: Scott Chen # date: 2020-01-03 import os import time import logging from logging.handlers import RotatingFileHandler class LogWare(object): # ---------- 创建日志对象的单例模式 ---------- __instance = None def __new__(cls, *args, **kwargs): if not cls.__instance: cls.__instance = super().__new__(cls) return cls.__instance # ---------- 日志类构造方法 ---------- def __init__(self, level='DEBUG'): if '_logger' not in self.__dict__: # -------------------- 日志配置 -------------------- # 日志路径 self.__log_path = 'd:/data/logs/' # 项目名作为日志目录 self.__project_name = 'idcard_reader_web' # 日志文件名 self.__log_file_prefix = 'idcard_reader_web_log' # 日志级别,DEBUG,INFO,WARNING,ERROR,CRITICAL self.__log_level = level # -------------------- 日志路径文件创建 -------------------- self.__log_size = 3 * 1024 * 1024 self.__backup_count = 100 self.__formatter = logging.Formatter('1[%(asctime)s][%(threadName)s][%(levelname)s][%(filename)s][%(lineno)d] %(message)s', '%Y-%m-%d %H:%M:%S') self.__timestamp = time.strftime("%Y-%m-%d", time.localtime()) # 日志除文件名之外的路径 self.__log_path_dict = { 'debug': os.path.join(self.__log_path, self.__project_name, 'debug'), 'info': os.path.join(self.__log_path, self.__project_name, 'info'), 'warning': os.path.join(self.__log_path, self.__project_name, 'warning'), 'error': os.path.join(self.__log_path, self.__project_name, 'error'), 'critical': os.path.join(self.__log_path, self.__project_name, 'critical'), } # 日志全路径 self.__log_full_path_dict = {} for (k, v) in self.__log_path_dict.items(): self.__log_full_path_dict[k] = os.path.join(v, self.__log_file_prefix + '_' + self.__timestamp + '_' + k + '.log') # 创建日志目录 for (k, v) in self.__log_path_dict.items(): if os.path.exists(v) and os.path.isdir(v): pass else: os.makedirs(v) # 日志对象 # self.__logger = logging # -------------------- 构造日志对象 -------------------- # 控制台 console_handler = logging.StreamHandler() console_handler.setFormatter(self.__formatter) # 此处通过文件大小截断日志文件,如果想要通过时间截断,可以使用 TimedRotatingFileHandler 这个类 debug_handler = logging.handlers.RotatingFileHandler( filename=self.__log_full_path_dict['debug'], mode='w', maxBytes=self.__log_size, encoding='utf-8', backupCount=self.__backup_count ) debug_handler.setFormatter(self.__formatter) info_handler = logging.handlers.RotatingFileHandler( filename=self.__log_full_path_dict['info'], mode='w', maxBytes=self.__log_size, encoding='utf-8', backupCount=self.__backup_count ) info_handler.setFormatter(self.__formatter) warning_handler = logging.handlers.RotatingFileHandler( filename=self.__log_full_path_dict['warning'], mode='w', maxBytes=self.__log_size, encoding='utf-8', backupCount=self.__backup_count ) warning_handler.setFormatter(self.__formatter) error_handler = logging.handlers.RotatingFileHandler( filename=self.__log_full_path_dict['error'], mode='w', maxBytes=self.__log_size, encoding='utf-8', backupCount=self.__backup_count ) error_handler.setFormatter(self.__formatter) critical_handler = logging.handlers.RotatingFileHandler( filename=self.__log_full_path_dict['critical'], mode='w', maxBytes=self.__log_size, encoding='utf-8', backupCount=self.__backup_count ) critical_handler.setFormatter(self.__formatter) # 日志文件输出 logger = logging.getLogger() logger.addHandler(console_handler) logger.addHandler(debug_handler) logger.setLevel(self.__log_level) self._logger = logger # 返回日志对象 def return_logger(self): return self._logger def get_logger(): return LogWare().return_logger() # ########## 单元测试 ########## if __name__ == '__main__': # 外部使用时,引入 # from log_ware import get_logger # 生成日志对象 logger = get_logger() i = 0 while True: logger.debug("level debug %s %s %d", 'aaaa', 'bbb', 10) logger.info("level info") logger.warning('level warning') logger.error("level error") logger.critical('level critical') i += 1 if i == 1: break