模块启用日志报错:No handlers could be found for logger
这个问题我之前也碰到过!错误提示的核心原因很简单:你虽然在模块里创建了模块级的logger,但没有为它配置任何日志处理器(handler)——logging模块默认不会自动给logger添加处理器,所以当你调用logger.info()时,日志消息找不到输出的地方,就会抛出这个警告。
下面给你两种解决方案,优先推荐第一种:
方案1:在应用入口统一配置日志(推荐)
在Python应用里,最佳实践是在主程序(入口文件)中统一配置logging,模块只负责使用logger即可。这样所有模块的logger都会继承主配置的处理器,避免重复配置,也方便统一管理日志格式、级别和输出目标。
比如你的主程序main.py可以这么写:
import logging from foo import Foo # 先配置日志,这一步一定要在导入模块或者使用logger之前执行 logging.basicConfig( level=logging.INFO, # 设置日志级别,低于这个级别的消息会被忽略 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', # 日志格式 handlers=[ logging.StreamHandler(), # 输出到控制台 # 也可以添加FileHandler把日志写到文件里 # logging.FileHandler('app.log') ] ) if __name__ == "__main__": foo = Foo() # 这里实例化Foo时,模块里的logger就能正常输出日志了
这样你的foo模块不需要做任何修改,保持原来的代码就行——因为模块级的logger会自动继承根logger的配置,日志就能正常输出到你指定的地方了。
方案2:在模块内临时配置(仅用于测试)
如果你只是临时测试模块功能,不想改动主程序,可以在模块里给logger手动添加处理器,但这种方式不推荐在正式应用里用(容易出现重复日志输出)。修改后的foo模块代码如下:
import logging logger = logging.getLogger(__name__) # 检查logger是否已有处理器,避免重复添加 if not logger.handlers: # 创建一个控制台处理器 handler = logging.StreamHandler() # 设置日志格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) # 添加处理器到logger logger.addHandler(handler) # 设置日志级别 logger.setLevel(logging.INFO) class Foo(): def __init__(self): logger.info("hello world")
补充说明
你用logging.getLogger(__name__)的做法非常正确!这种方式会让logger的名字和模块的层级一致(比如如果foo在某个包下,logger名字会是package.foo),这样在日志里能清晰区分不同模块的输出,方便排查问题。
内容的提问来源于stack exchange,提问作者Steve Lorimer




