90 lines
3.4 KiB
Python
90 lines
3.4 KiB
Python
# ============================================================
|
|||
|
|
# 日志工具类 — 对标准库 logging 进行简单封装
|
||
|
|
# 提供控制台输出、文件输出、统一 message() 记录三个能力
|
||
|
|
# 避免在各处重复写 logger.handlers / FileHandler / Formatter 等样板代码
|
||
|
|
# ============================================================
|
||
|
|
|
||
|
|
import logging
|
||
|
|
|
||
|
|
|
||
|
|
class Log:
|
||
|
|
"""
|
||
|
|
简易日志封装类。
|
||
|
|
|
||
|
|
用法示例:
|
||
|
|
log = Log('myapp', 'INFO')
|
||
|
|
log.logFile('app.log') # 输出到文件
|
||
|
|
log.logConsol() # 同时输出到控制台
|
||
|
|
log.message('info', '启动成功')
|
||
|
|
|
||
|
|
设计要点:
|
||
|
|
- 同一日志器重复 addHandler 会导致同一条日志输出多次,
|
||
|
|
所以 logFile / logConsol 里做了 handler 去重判断。
|
||
|
|
"""
|
||
|
|
|
||
|
|
def __init__(self, name, lv):
|
||
|
|
"""
|
||
|
|
构造日志器实例。
|
||
|
|
|
||
|
|
参数:
|
||
|
|
name: 日志器名称,同名日志器是全局单例(logging.getLogger 内部维护)
|
||
|
|
lv: 初始日志级别字符串,不区分大小写
|
||
|
|
可选值: 'DEBUG' / 'INFO' / 'WARNING' / 'ERROR' / 'CRITICAL'
|
||
|
|
"""
|
||
|
|
# ① 创建命名日志器
|
||
|
|
self.logName = logging.getLogger(name)
|
||
|
|
|
||
|
|
# ② 设置日志级别(字符串转 logging.XXX 枚举)
|
||
|
|
self.logName.setLevel(eval(f'logging.{lv.upper()}'))
|
||
|
|
|
||
|
|
# ④ 定义统一的日志输出格式:时间 - 名称 - 级别 - 消息
|
||
|
|
self.formatter = logging.Formatter(
|
||
|
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
|
|
datefmt='%Y-%m-%d %H:%M:%S'
|
||
|
|
)
|
||
|
|
|
||
|
|
# 保存现有 handler 列表,方便后续去重
|
||
|
|
self.handlers = self.logName.handlers
|
||
|
|
|
||
|
|
def logConsol(self):
|
||
|
|
"""将日志输出到控制台(stdout)。"""
|
||
|
|
con_hand = logging.StreamHandler() # ③ 创建控制台处理器
|
||
|
|
con_hand.setFormatter(self.formatter) # 绑定格式
|
||
|
|
# 去重:避免重复添加同一个类型的 handler 导致日志重复打印
|
||
|
|
if 'StreamHandler' not in str(self.handlers):
|
||
|
|
self.logName.addHandler(con_hand) # ⑤ 注册到日志器
|
||
|
|
|
||
|
|
def logFile(self, fileName):
|
||
|
|
"""
|
||
|
|
将日志输出到指定文件(UTF-8 编码)。
|
||
|
|
|
||
|
|
参数:
|
||
|
|
fileName: 日志文件名,例如 'log.txt'
|
||
|
|
"""
|
||
|
|
file_hand = logging.FileHandler(fileName, encoding='utf-8') # ③ 创建文件处理器
|
||
|
|
file_hand.setFormatter(self.formatter)
|
||
|
|
# 去重:同一个文件 handler 只注册一次
|
||
|
|
if 'FileHandler' not in str(self.handlers):
|
||
|
|
self.logName.addHandler(file_hand) # ⑤ 注册到日志器
|
||
|
|
|
||
|
|
def message(self, lv, mes):
|
||
|
|
"""
|
||
|
|
按照指定级别输出一条日志。
|
||
|
|
|
||
|
|
参数:
|
||
|
|
lv: 日志级别字符串(不区分大小写),可选 debug / info / warning / error / critical
|
||
|
|
mes: 日志内容
|
||
|
|
"""
|
||
|
|
lv = lv.lower()
|
||
|
|
if lv == 'debug':
|
||
|
|
self.logName.debug(mes)
|
||
|
|
elif lv == 'info':
|
||
|
|
self.logName.info(mes)
|
||
|
|
elif lv == 'warning':
|
||
|
|
self.logName.warning(mes)
|
||
|
|
elif lv == 'error':
|
||
|
|
self.logName.error(mes)
|
||
|
|
elif lv == 'critical':
|
||
|
|
self.logName.critical(mes)
|
||
|
|
else:
|
||
|
|
print('请输入正确的日志级别!')
|