basicConfig无法同时输出多等级日志到不同位置,因其仅创建一个根logger和一个handler,所有日志共用同一路径;需手动为同一logger添加多个handler并分别设置level,由各handler按自身level过滤日志。

为什么basicConfig不能同时输出多等级日志到不同位置
因为basicConfig只创建一个根logger和一个handler,所有日志都走同一条路径,无法按level分流。想让DEBUG写文件、ERROR发邮件或打印到控制台,必须手动构造logger+多个handler。
如何给同一个logger绑定多个handler并设置各自level
关键不是改logger的level,而是每个handler自己决定“接不接收”某条日志——靠setLevel()控制。logger把日志发给所有handler,每个handler再按自己的level过滤。
- logger.level设为最低级(如
DEBUG),保证不丢日志 - 文件handler调用
setLevel(logging.DEBUG),接收全部 - 控制台handler调用
setLevel(logging.WARNING),只显示WARNING及以上 - handler的level必须≤logger.level,否则全被logger拦住
import logging
<p>logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG) # logger放行所有</p><p>file_handler = logging.FileHandler("debug.log")
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))</p><p>console_handler = logging.StreamHandler()
console_handler.setLevel(logging.WARNING) # 注意这里
console_handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))</p><p>logger.addHandler(file_handler)
logger.addHandler(console_handler)</p><p>logger.debug("这条只写进文件")
logger.warning("这条既写文件又打屏")为什么加了propagate=False后控制台没日志了
默认情况下,logger会把日志向上冒泡到root logger,而root logger自带一个StreamHandler,导致日志重复输出。设propagate=False是为避免重复,但如果你没手动加其他handler,就真没输出了。
- 仅当logger有至少一个handler时,才可安全设
propagate=False - root logger的handler默认level是
WARNING,所以DEBUG日志本来就不会打屏 - 自定义logger不设
propagate=False,又没删root handler,就可能双份输出
用Filter实现更细粒度的日志分流
handler的level只能按等级粗筛,若要“把数据库相关DEBUG日志单独写进db.log”,就得用Filter子类重写filter()方法。
立即学习“Python免费学习笔记(深入)”;
- filter返回
True才让日志通过该handler - 可检查
record.name、record.msg甚至record.exc_info - 注意:filter加在handler上,不是logger上
class DBFilter(logging.Filter):
def filter(self, record):
return "DB" in record.name or "database" in record.msg.lower()
<p>db_handler = logging.FileHandler("db.log")
db_handler.addFilter(DBFilter()) # 关键这行
db_handler.setLevel(logging.DEBUG)配置多级输出真正麻烦的不是写代码,是理清logger→handler→filter→propagate四层关系里谁管什么。漏掉任意一层的level设置,日志就静默消失,而且很难一眼看出是哪一层拦住了。


















