import logging import os import os.path import datetime import inspect class ServiceLoggerHandler(logging.Handler): def __init__(self, file_fmt=None): self.file_fmt = file_fmt if file_fmt is None: self.file_fmt = os.path.join('logs', '%Y-%m-%d.log') logging.Handler.__init__(self) def emit(self, record): msg = self.format(record) fpath = datetime.datetime.now().strftime(self.file_fmt) fdir = os.path.dirname(fpath) try: if not os.path.exists(fdir): os.makedirs(fdir) except Exception as e: print(e) try: f = open(fpath, 'a') f.write(msg) f.write("\n") f.flush() f.close() except Exception as e: print(e) class Logger: def __init__(self, service_name, log_level=logging.DEBUG, log_dir=None, print_terminal=True): self.service_name = service_name self.log_level = log_level self.log_dir = log_dir self.print_terminal = print_terminal logging.addLevelName(10, 'DEBG') logging.addLevelName(20, 'INFO') logging.addLevelName(30, 'WARN') logging.addLevelName(40, 'EROR') logging.addLevelName(50, 'CRIT') self.logger = logging.getLogger(self.service_name) self.logger.setLevel(self.log_level) # 创建一个handler,用于写入日志文件 file_fmt = os.path.join(self.log_dir, self.service_name, self.service_name + "-%Y-%m-%d.log") fh = ServiceLoggerHandler(file_fmt) fh.setLevel(self.log_level) # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() ch.setLevel(self.log_level) # 定义handler的输出格式 formatter = logging.Formatter( '[%(asctime)s] [%(levelname).4s] (%(name)s, %(call_fname)s:%(call_line)d) %(message)s') fh.setFormatter(formatter) if print_terminal: ch.setFormatter(formatter) # 给logger添加handler self.logger.addHandler(fh) if print_terminal: self.logger.addHandler(ch) def Debug(self, msg): previous_frame = inspect.currentframe().f_back pathname, line_number, func_name, lines, index = inspect.getframeinfo(previous_frame) filename = os.path.basename(pathname) self.logger.debug(msg, extra={'call_fname': filename, 'call_line': line_number}) def Info(self, msg): previous_frame = inspect.currentframe().f_back pathname, line_number, func_name, lines, index = inspect.getframeinfo(previous_frame) filename = os.path.basename(pathname) self.logger.info(msg, extra={'call_fname': filename, 'call_line': line_number}) def Warn(self, msg): previous_frame = inspect.currentframe().f_back pathname, line_number, func_name, lines, index = inspect.getframeinfo(previous_frame) filename = os.path.basename(pathname) self.logger.warning(msg, extra={'call_fname': filename, 'call_line': line_number}) def Error(self, msg): previous_frame = inspect.currentframe().f_back pathname, line_number, func_name, lines, index = inspect.getframeinfo(previous_frame) filename = os.path.basename(pathname) self.logger.error(msg, extra={'call_fname': filename, 'call_line': line_number}) def Critical(self, msg): previous_frame = inspect.currentframe().f_back pathname, line_number, func_name, lines, index = inspect.getframeinfo(previous_frame) filename = os.path.basename(pathname) self.logger.critical(msg, extra={'call_fname': filename, 'call_line': line_number})