概要
在python编程中,记录日志是十分有必要的,相比于print打印相关的内容logging有下面几个好处:
- 记录更加丰富的信息。可以记录时间、文件、行号等等
- 可以记录到本地。日志信息可以输出到日志文件中,方便后续管理记录
但是日志的使用一直没有搞清楚,写这篇博客进行梳理记录一下。
不同python文件的logger可以共享吗?
通常一个python项目是由很多的python文件组成的,那我的logger应该如何配置呢?
答案是新建一个logging_config.py 文件进行logger的管理与配置。下面是一个我自己常用的日志配置文件。
logger是一个全局的概念,只要我们配置好对应名称的logger之后,只需要在各个文件中通过logger=logging.getLogger([logger_name])
即可获取相应配置好的logger。
logging_config.py
import logging
import os
def get_logger(name=None, log_file=None):
"""
获取一个日志记录器实例,并配置日志输出到控制台和/或文件。
参数:
name -- 日志记录器的名称 (默认为空,即根记录器)
log_file -- 日志文件的名称 (如果不指定,则不输出到文件)
"""
# 创建日志记录器
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG) # 设置日志等级为 DEBUG,捕获所有级别的日志
# 设置日志格式
formatter = logging.Formatter('%(asctime)s-%(levelname)8s-%(filename)s[:%(lineno)d]-%(message)s')
# 创建一个控制台处理器 (console handler)
if not any(isinstance(h, logging.StreamHandler) for h in logger.handlers):
# 检查是否已经有控制台处理器,避免重复添加
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG) # 控制台处理器的日志等级为 DEBUG
ch.setFormatter(formatter) # 设置控制台处理器的日志格式
logger.addHandler(ch) # 将控制台处理器添加到日志记录器
# 如果指定了日志文件,创建一个文件处理器 (file handler)
if log_file:
if not isinstance(log_file, str) or not log_file.strip():
# 检查 log_file 是否为有效的非空字符串
raise ValueError("log_file must be a non-empty string")
log_dir = os.path.dirname(log_file)
if log_dir and not os.path.exists(log_dir):
# 确保日志文件所在的目录存在,如果不存在则创建
os.makedirs(log_dir, exist_ok=True)
if not any(isinstance(h, logging.FileHandler) for h in logger.handlers):
# 检查是否已经有文件处理器,避免重复添加
fh = logging.FileHandler(log_file)
fh.setLevel(logging.DEBUG) # 文件处理器的日志等级为 DEBUG
fh.setFormatter(formatter) # 设置文件处理器的日志格式
logger.addHandler(fh) # 将文件处理器添加到日志记录器
return logger # 返回配置好的日志记录器实例
if __name__ == '__main__':
# 在主模块中获取日志记录器实例
logger = get_logger('my_logger', './log/log_file.log')
# 记录不同级别的日志信息
logger.info('This is an info message.')
logger.debug('This is a debug message.')
try:
# 模拟一个除零错误
a = 10 / 0
except Exception as e:
# 记录错误信息,并包含异常堆栈信息
logger.error(e, exc_info=True)