122、logging 模块系统化:Logger、Handler、Formatter 的层级架构与最佳实践一个让我熬夜到凌晨三点的Bug去年接手一个金融风控项目,生产环境突然出现日志丢失——某些关键告警信息在ERROR级别下竟然没有写入文件。排查了整整六个小时,从代码逻辑到服务器权限,最后发现是logging配置里Logger的层级传播机制出了问题。那个深夜,我盯着屏幕上的日志输出,突然意识到:大多数人(包括当时的我)对logging的理解,停留在"会用就行"的层面。Logger:日志世界的命名空间树Logger不是孤立的个体,它们构成一棵树。根Logger叫"root",所有自定义Logger都是它的子孙。当你写logger = logging.getLogger('my_module')时,实际上是在root下挂了一个名为’my_module’的节点。这里踩过坑:很多人以为getLogger(‘A.B’)和getLogger(‘A’)是两个独立的Logger,其实’A.B’是’A’的子节点。日志事件会沿着这棵树向上传播,直到root。这意味着如果你在子Logger上设置了级别,父Logger的Handler可能会重复处理——这就是我那个金融项目日志丢失的根源。