一個完整的程序離不開日志,無論是開發階段,還是測試階段,亦或程序運行階段,都可以通過日志查看程序的運行情況,或是定位問題。
下面是對 python3 的日志庫 logging 進行了封裝,對於大部分的需求應該是能滿足的。
程序結構:
|--logger.py
|
|--singleton.py
|
|--runall.py
|
|--log
| |
| 2022-2-16.log
logger.py
import os import sys import time import logging from .singleton import Singleton @Singleton # 如需打印不同路徑的日志(運行日志、審計日志),則不能使用單例模式(注釋或刪除此行)。此外,還需設定參數name。 class Logger: def __init__(self, set_level="INFO", name=os.path.split(os.path.splitext(sys.argv[0])[0])[-1], log_name=time.strftime("%Y-%m-%d.log", time.localtime()), log_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "log"), use_console=True): """ :param set_level: 日志級別["NOTSET"|"DEBUG"|"INFO"|"WARNING"|"ERROR"|"CRITICAL"],默認為INFO :param name: 日志中打印的name,默認為運行程序的name :param log_name: 日志文件的名字,默認為當前時間(年-月-日.log) :param log_path: 日志文件夾的路徑,默認為logger.py同級目錄中的log文件夾 :param use_console: 是否在控制台打印,默認為True """ if not set_level: set_level = self._exec_type() # 設置set_level為None,自動獲取當前運行模式 self.__logger = logging.getLogger(name) self.setLevel( getattr(logging, set_level.upper()) if hasattr(logging, set_level.upper()) else logging.INFO) # 設置日志級別 if not os.path.exists(log_path): # 創建日志目錄 os.makedirs(log_path) formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s - %(message)s") handler_list = list() handler_list.append(logging.FileHandler(os.path.join(log_path, log_name), encoding="utf-8")) if use_console: handler_list.append(logging.StreamHandler()) for handler in handler_list: handler.setFormatter(formatter) self.addHandler(handler) def __getattr__(self, item): return getattr(self.logger, item) @property def logger(self): return self.__logger @logger.setter def logger(self, func): self.__logger = func def _exec_type(self): return "DEBUG" if os.environ.get("IPYTHONENABLE") else "INFO"
singleton.py
class Singleton: """ 單例裝飾器。 """ __cls = dict() def __init__(self, cls): self.__key = cls def __call__(self, *args, **kwargs): if self.__key not in self.cls: self[self.__key] = self.__key(*args, **kwargs) return self[self.__key] def __setitem__(self, key, value): self.cls[key] = value def __getitem__(self, item): return self.cls[item] @property def cls(self): return self.__cls @cls.setter def cls(self, cls): self.__cls = cls
runall.py
#coding=utf-8 from .logger import Logger log = Logger("debug") log .critical("這是一個 critical 級別的問題!") log .error("這是一個 error 級別的問題!") log .warning("這是一個 warning 級別的問題!") log .info("這是一個 info 級別的問題!") log .debug("這是一個 debug 級別的問題!")
來源:https://www.jb51.net/article/184274.htm