Python中logging实例讲解


Posted in Python onJanuary 17, 2019

logging 的基本用法网上很多,这里就不介绍了。在引入正文之前,先来看一个需求:

假设需要将某功能封装成类库供他人使用,如何处理类库中的日志?

数年前在一个 C# 开发的项目中,我用了这样的方法:定义一个 logging 基类,所有需要用到日志的类都继承这个基类,这个基类中定义一个 LogHandler 事件,该事件用于实现具体的记录日志动作,同时可以通过将类 A 的 LogHandler 委托挂到类 B 的 LogHandler 上,实现将两个类的日志信息添加到一起。

自从看了 python 中 logging 的实现方式,我发现我的做法真是弱爆了。

我在之前的博客 Python:logging.NullHandler 的使用 中介绍了 peewee 框架中的日志输出,简单来说就是 peewee 中定义了一个名为peewee 的 Logger 并添加了一个 NullHandler,调用者只需要为其添加具体的 Handler 就可以输出日志了,非常方便。

Python中logging实例讲解

假设我们在主程序中也有一个 Logger,调用 peewee 后,我想将两个日志输出到同一个日志文件中去。显然将两个日志的 FileHandler 指向同一个日志文件是不可取的,存在并发抢占文件的风险。当然我们也可以将主程序中的 Logger 名字定为 peewee,但这不仅太 low 了,而且如果再调用一个库,其中也封装好了一个 Logger,就不好处理了。

树桩结构的 Logger

Logger 对象被设计为一个树形结构,它有一个 parent 属性。logging 中定义了一个名为 root 的 Logger 作为所有 Logger 的根节点,root 的 parent 属性为 None。root 是全局的。

当调用

logging.getLogger(name=None)

得到一个 Logger 对象的时候,如果 name 为 None,则返回根节点 root。如果 name 中含有 .,比如 name = 'a.b',这时如果已经存在了名为 a 的 Logger,则 a.b 为 a 的子节点,如果不存在名为 a 的 Logger,则 a.b 为 root 的子节点。

child logger 在完成对日志消息的处理后,默认会将日志消息传递给与它的 parent logger。因此,我们不必为一个应用程序中使用的所有 Logger 定义和配置 handlers,只需要为一个顶层的 Logger 配置 handlers,然后按照需要创建 child loggers 就可足够了。我们可以通过设置 Logger 的 propagate 属性设置为 False 来关闭这种传递机制。

什么意思呢,我们来看代码:

import logging
logA = logging.getLogger('a')
logA.setLevel(logging.DEBUG)
logA.addHandler(logging.StreamHandler())
logB = logging.getLogger('a.b')
logB.addHandler(logging.StreamHandler())

输出结果:

Logger A
Logger B
Logger B

之所以 Logger B 被输出了 2 次,是因为 logB 是 logA 的子节点,并且 logB 中也定义了 Handler,所以 logB 的 Handler 输出了一次,logA 的 Handler 也输出了一次,就 2 次了。如果想只输出一次,可以删掉 logB 中的 Handler。当然,这也是有用处的,尤其是当你手头没有日志管理工具的时候。例如,主程序中需要输出所有的日志,以便了解程序整体的运行顺序,而某模块的日志,你想单独输出一份,以便清晰了解模块中的报错或者是执行顺序。

之前 peewee 的例子也就很容易解决了,只需要将 peewee 日志的 parent 属性设置为主程序的日志就可以了。

结语

其实这是一个比较容易说明的问题,完全没必要写这么多。我并不想跟大家分享 python 中的 logging 是怎么用的,而是想和大家分享 logging 如此实现的一种思想,因为我遇到过这个问题,也设计了解决方案,然后被完爆了。

Python 相关文章推荐
python根据给定文件返回文件名和扩展名的方法
Mar 27 Python
python字符串编码识别模块chardet简单应用
Jun 15 Python
Python 迭代器与生成器实例详解
May 18 Python
Python实现删除时保留特定文件夹和文件的示例
Apr 27 Python
django请求返回不同的类型图片json,xml,html的实例
May 22 Python
Python的iOS自动化打包实例代码
Nov 22 Python
Python设计模式之外观模式实例详解
Jan 17 Python
Pytorch使用MNIST数据集实现CGAN和生成指定的数字方式
Jan 10 Python
Python常用扩展插件使用教程解析
Nov 02 Python
scrapy在python爬虫中搭建出错的解决方法
Nov 22 Python
python反爬虫方法的优缺点分析
Nov 25 Python
python如何利用cv2模块读取显示保存图片
Jun 04 Python
python矩阵/字典实现最短路径算法
Jan 17 #Python
python实现Dijkstra静态寻路算法
Jan 17 #Python
解决在Python编辑器pycharm中程序run正常debug错误的问题
Jan 17 #Python
python实现dijkstra最短路由算法
Jan 17 #Python
Pycharm 设置默认头的图文教程
Jan 17 #Python
python实现狄克斯特拉算法
Jan 17 #Python
在PyCharm下使用 ipython 交互式编程的方法
Jan 17 #Python
You might like
php全局变量和类配合使用深刻理解
2013/06/05 PHP
浅析PHP程序防止ddos,dns,集群服务器攻击的解决办法
2013/06/18 PHP
PHP中预定义的6种接口介绍
2015/05/12 PHP
PHP7正式版测试,性能惊艳!
2015/12/08 PHP
Laravel构建即时应用的一种实现方法详解
2017/08/31 PHP
PHP面向对象程序设计之多态性的应用示例
2018/12/19 PHP
jquery的ajax跨域请求原理和示例
2014/05/08 Javascript
js判断浏览器是否支持html5
2014/08/17 Javascript
js插件设置innerHTML时在IE8下提示“未知运行时错误”解决方法
2015/04/25 Javascript
JS实现无限级网页折叠菜单(类似树形菜单)效果代码
2015/09/17 Javascript
js当前页面登录注册框,固定div,底层阴影的实例代码
2016/10/04 Javascript
概述javascript在Google IE中的调试技巧
2016/11/24 Javascript
AngularJS基于ui-route实现深层路由的方法【路由嵌套】
2016/12/14 Javascript
JavaScript 事件对内存和性能的影响
2017/01/22 Javascript
vue货币过滤器的实现方法
2017/04/01 Javascript
vue-router 中router-view不能渲染的解决方法
2017/05/23 Javascript
JavaScript之Map和Set_动力节点Java学院整理
2017/06/29 Javascript
纯JS实现出生日期[年月日]下拉菜单效果
2018/06/01 Javascript
Vue(定时器)解决mounted不能获取到data中的数据问题
2020/07/30 Javascript
Python函数可变参数定义及其参数传递方式实例详解
2015/05/25 Python
剖析Django中模版标签的解析与参数传递
2015/07/21 Python
解决python中使用plot画图,图不显示的问题
2018/07/04 Python
python 2.7.13 安装配置方法图文教程
2018/09/18 Python
Python函数返回不定数量的值方法
2019/01/22 Python
PyCharm-错误-找不到指定文件python.exe的解决方法
2019/07/01 Python
pytorch三层全连接层实现手写字母识别方式
2020/01/14 Python
使用Python对Dicom文件进行读取与写入的实现
2020/04/20 Python
python tqdm库的使用
2020/11/30 Python
CSS3系列教程:背景图片(背景大小和多背景图) 应用说明
2012/12/19 HTML / CSS
html5 button autofocus 属性介绍及应用
2013/01/04 HTML / CSS
Big Green Smile法国:领先的英国有机和天然产品在线商店
2021/01/02 全球购物
小区门卫管理制度
2014/01/29 职场文书
市场部岗位职责
2015/02/12 职场文书
500字作文之周记
2019/12/13 职场文书
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
2021/06/11 Python
JS开发前端团队展示控制器来为成员引流
2022/08/14 Javascript