优点
-
独立性:
-
每个脚本的日志独立存储,避免日志混杂,便于排查问题。
-
-
灵活性:
-
支持动态获取脚本名称,无需手动指定日志记录器名称。
-
-
可扩展性:
-
可以轻松扩展日志格式、级别、存储路径等功能。
-
-
易用性:
-
只需导入
logger
即可使用,无需额外配置。
-
代码
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import logging
import traceback
from logging.handlers import TimedRotatingFileHandler
import pathlib
from logging import Logger
def get_logger(name, level=logging.INFO):
"""
构建一个 logger
:param name: logger 唯一标识
:param level: 日志等级
:return:
"""
# 创建一个 logger 对象
_logger = Logger.manager.getLogger(name)
_logger.setLevel(level)
# 创建一个 handler 输出到控制台
console_handler = logging.StreamHandler()
formatter = logging.Formatter(
"%(asctime)s - %(levelname)s - %(pathname)s:%(lineno)d - %(message)s",
)
console_handler.setFormatter(formatter)
_logger.addHandler(console_handler)
# 与logger.py相对路径相关
path = pathlib.Path(__file__).parent.joinpath(f"./logs/{name}.log")
path.parent.mkdir(parents=True, exist_ok=True)
# 按天分割日志,最多7天
file_handler = TimedRotatingFileHandler(
str(path), when="midnight", interval=1, backupCount=7, encoding="utf8"
)
file_handler.setFormatter(formatter)
_logger.addHandler(file_handler)
_logger.info(f"日志文件路径:{path}")
return _logger
def _get_server_name():
"""
:return:
"""
_server_name = "default"
_stack = traceback.extract_stack()
r = None
for item in _stack[::-1]:
if item.name == "_get_server_name":
# 与logger.py相对路径相关
r = pathlib.Path(item.filename).parent.as_posix().replace("\\", "/")
filename = item.filename.replace("\\", "/")
if r and r in filename:
_server_name = pathlib.Path(filename).name.replace(".py", "")
return _server_name
logger = get_logger(_get_server_name())
# 使用示例
if __name__ == "__main__":
logger.info("测试日志")