用 Python 的 logging 模块记录日志时,可能会遇到重复记录日志的问题,第一条记录写一次,第二条记录写两次,第三条记录写三次。
原因:没有移除 Handler
解决:在日志记录完之后 removeHandler
例子1:
def log(msg):
#创建logger,如果参数为空则返回root logger
logger = logging.getLogger("nick")
logger.setLevel(logging.DEBUG) #设置logger日志等级
#创建handler
fh = logging.FileHandler("test.log",encoding="utf-8")
ch = logging.StreamHandler()
#设置输出日志格式
formatter = logging.Formatter(
fmt="%(asctime)s %(name)s %(filename)s %(message)s",
datefmt="%Y/%m/%d %X"
)
#为handler指定输出格式
fh.setFormatter(formatter)
ch.setFormatter(formatter)
#为logger添加的日志处理器
logger.addHandler(fh)
logger.addHandler(ch)
# 输出不同级别的log
logger.info(msg)
log("泰拳警告")
log("提示")
log("错误")
# 输出结果
"""
2018/05/10 20:06:18 nick test.py 泰拳警告
2018/05/10 20:06:18 nick test.py 提示
2018/05/10 20:06:18 nick test.py 提示
2018/05/10 20:06:18 nick test.py 错误
2018/05/10 20:06:18 nick test.py 错误
2018/05/10 20:06:18 nick test.py 错误
"""
分析:可以看出输出结果有重复打印
原因:第二次调用 log 的时候,根据 getLogger(name) 里的 name 获取同一个 logger,而这个 logger 里已经有了第一次你添加的 handler,第二次调用又添加了一个 handler,所以,这个 logger 里有了两个同样的 handler,以此类推,调用几次就会有几个handler。
解决方案1:添加 removeHandler 语句
import logging
def log(msg):
#创建logger,如果参数为空则返回root logger
logger = logging.getLogger("nick")
logger.setLevel(logging.DEBUG) #设置logger日志等级
#创建handler
fh = logging.FileHandler("test.log",encoding="utf-8")
ch = logging.StreamHandler()
#设置输出日志格式
formatter = logging.Formatter(
fmt="%(asctime)s %(name)s %(filename)s %(message)s",
datefmt="%Y/%m/%d %X"
)
#为handler指定输出格式
fh.setFormatter(formatter)
ch.setFormatter(formatter)
#为logger添加的日志处理器
logger.addHandler(fh)
logger.addHandler(ch)
# 输出不同级别的log
logger.info(msg)
#解决方案1,添加removeHandler语句,每次用完之后移除Handler
logger.removeHandler(fh)
logger.removeHandler(ch)
log("泰拳警告")
log("提示")
log("错误")
解决方案2:在log方法里做判断,如果这个logger已有handler,则不再添加handler。
import logging
def log(msg):
#创建logger,如果参数为空则返回root logger
logger = logging.getLogger("nick")
logger.setLevel(logging.DEBUG) #设置logger日志等级
#解决方案2:这里进行判断,如果logger.handlers列表为空,则添加,否则,直接去写日志
if not logger.handlers:
#创建handler
fh = logging.FileHandler("test.log",encoding="utf-8")
ch = logging.StreamHandler()
#设置输出日志格式
formatter = logging.Formatter(
fmt="%(asctime)s %(name)s %(filename)s %(message)s",
datefmt="%Y/%m/%d %X"
)
#为handler指定输出格式
fh.setFormatter(formatter)
ch.setFormatter(formatter)
#为logger添加的日志处理器
logger.addHandler(fh)
logger.addHandler(ch)
# 输出不同级别的log
logger.info(msg)
log("泰拳警告")
log("提示")
log("错误")
参考文档: