python日志logging模块使用方法分析


Posted in Python onMay 23, 2019

本文实例讲述了python日志logging模块使用方法。分享给大家供大家参考,具体如下:

一、从一个使用场景开始

开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件

import logging
# 创建一个logger
logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)
# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 给logger添加handler
logger.addHandler(fh)
logger.addHandler(ch)
# 记录一条日志
logger.info('foorbar')

运行后, 在控制台和日志文件都有一条日志:

2011-08-31 19:18:29,816 - mylogger - INFO - foorbar

二、logging模块的API

结合上面的例子,我们说下几个最常使用的API

logging.getLogger([name])返回一个logger实例,如果没有指定name,返回root logger。只要name相同,返回的logger实例都是同一个而且只有一个,即name和logger实例是一一对应的。这意味着,无需把logger实例在各个模块中传递。只要知道name,就能得到同一个logger实例

Logger.setLevel(lvl)设置logger的level, level有以下几个级别:

python日志logging模块使用方法分析

NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL

如果把looger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级别的日志都输出

logger.debug("foobar")  # 不输出
logger.info("foobar")    # 输出
logger.warning("foobar") # 输出
logger.error("foobar")   # 输出
logger.critical("foobar")  # 输出

Logger.addHandler(hdlr)logger可以雇佣handler来帮它处理日志, handler主要有以下几种:StreamHandler : 输出到控制台FileHandler :   输出到文件handler还可以设置自己的level以及输出格式。

logging.basicConfig([**kwargs])

这个函数用来配置root logger, 可以看它的源码,还是挺简单的。它首先检查root是否有handler,如果没有,那这个函数会创建一个StreamHandler,并设置默认的formatter。

然后将该handler添加到root。如果调用logging.basicConfig([**kwargs])的时候发现root logger已经有了handler,那该函数没有任何操作。

三、关于root logger以及logger的父子关系

前面多次提到root logger, 实际上logger实例之间还有父子关系, root logger就是处于最顶层的logger, 它是所有logger的祖先。如下图:

python日志logging模块使用方法分析

root logger是默认的logger,如果不创建logger实例, 直接调用logging.debug()、logging.info()logging.warning()、logging.error()、logging.critical()这些函数,那么使用的logger就是 root logger, 它可以自动创建,也是单实例的。

如何得到root logger通过logging.getLogger()或者logging.getLogger("")得到root logger实例。

默认的level:root logger默认的level是logging.WARNING

如何表示父子关系logger的name的命名方式可以表示logger之间的父子关系. 比如:parent_logger = logging.getLogger('foo')child_logger = logging.getLogger('foo.bar')

什么是effective levellogger有一个概念,叫effective level。 如果一个logger没有显示地设置level,那么它就用父亲的level。如果父亲也没有显示地设置level, 就用父亲的父亲的level,以此推....最后到达root logger,一定设置过level。默认为logging.WARNINGchild loggers得到消息后,既把消息分发给它的handler处理,也会传递给所有祖先logger处理,

来看一个例子

import logging
# 设置root logger
r = logging.getLogger()
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
r.addHandler(ch)
# 创建一个logger作为父亲
p = logging.getLogger('foo')
p.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(message)s')
ch.setFormatter(formatter)
p.addHandler(ch)
# 创建一个孩子logger
c = logging.getLogger('foo.bar')
c.debug('foo')

输出如下:

2011-08-31 21:04:29,893 - foo
2011-08-31 21:04:29,893 - DEBUG - foo

可见, 孩子logger没有任何handler,所以对消息不做处理。但是它把消息转发给了它的父亲以及root logger。最后输出两条日志。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python2.7删除文件夹和删除文件代码实例
Dec 18 Python
python数据预处理之将类别数据转换为数值的方法
Jul 05 Python
Windows系统下多版本pip的共存问题详解
Oct 10 Python
Python中pow()和math.pow()函数用法示例
Feb 11 Python
Python cookbook(数据结构与算法)让字典保持有序的方法
Feb 18 Python
Sanic框架流式传输操作示例
Jul 18 Python
解决pyinstaller打包pyqt5的问题
Jan 08 Python
pyqt5实现俄罗斯方块游戏
Jan 11 Python
django连接oracle时setting 配置方法
Aug 29 Python
python在一个范围内取随机数的简单实例
Aug 16 Python
Django中的DateTimeField和DateField实现
Feb 24 Python
Python之matplotlib绘制饼图
Apr 13 Python
Django框架模板语言实例小结【变量,标签,过滤器,继承,html转义】
May 23 #Python
Django框架模板文件使用及模板文件加载顺序分析
May 23 #Python
Django框架登录加上验证码校验实现验证功能示例
May 23 #Python
python图形工具turtle绘制国际象棋棋盘
May 23 #Python
python os模块简单应用示例
May 23 #Python
python使用turtle绘制国际象棋棋盘
May 23 #Python
Python实现的服务器示例小结【单进程、多进程、多线程、非阻塞式】
May 23 #Python
You might like
PHP开发环境配置(MySQL数据库安装图文教程)
2010/04/28 PHP
php中长文章分页显示实现代码
2012/09/29 PHP
关于document.cookie的使用javascript
2008/04/11 Javascript
javascript IE中的DOM ready应用技巧
2008/07/23 Javascript
学习JavaScript设计模式之单例模式
2016/01/19 Javascript
JavaScript函数内部属性和函数方法实例详解
2016/03/17 Javascript
基于BootStarp的Dailog
2016/04/28 Javascript
javascript实现根据汉字获取简拼
2016/09/25 Javascript
jQuery 检查某个元素在页面上是否存在实例代码
2016/10/27 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
axios 处理 302 状态码的解决方法
2018/04/10 Javascript
JS实现checkbox互斥(单选)功能示例
2019/05/04 Javascript
深入浅析vue中cross-env的使用
2019/09/12 Javascript
[04:49]期待西雅图之战 2016国际邀请赛中国区预选赛WINGS战队赛后采访
2016/06/29 DOTA
Python使用sorted排序的方法小结
2017/07/28 Python
python如何实现反向迭代
2018/03/20 Python
Python爬虫之网页图片抓取的方法
2018/07/16 Python
python如何保证输入键入数字的方法
2019/08/23 Python
python解析xml文件方式(解析、更新、写入)
2020/03/05 Python
使用Python项目生成所有依赖包的清单方式
2020/07/13 Python
通过实例解析python subprocess模块原理及用法
2020/10/10 Python
浅谈HTML5 defer和async的区别
2016/06/07 HTML / CSS
美国第一个网上卖鞋零售商:OnlineShoes.com
2017/09/24 全球购物
Hurley官方网站:扎根于海滩生活方式的全球青年文化品牌
2020/05/18 全球购物
地理科学专业毕业生求职信
2013/10/15 职场文书
大学生就业自我鉴定
2013/10/26 职场文书
高级人员简历的自我评价分享
2013/11/03 职场文书
个人租房协议书
2014/04/09 职场文书
优秀班主任经验交流材料
2014/06/02 职场文书
党支部书记四风问题整改措施
2014/09/24 职场文书
PHP使用非对称加密算法RSA
2021/04/21 PHP
六种css3实现的边框过渡效果
2021/04/22 HTML / CSS
HTML+css盒子模型案例(圆,半圆等)“border-radius” 简单易上手
2021/05/10 HTML / CSS
Python 解决空列表.append() 输出为None的问题
2021/05/23 Python
CSS作用域(样式分割)的使用汇总
2021/11/07 HTML / CSS
MySQL事务的ACID特性以及并发问题方案
2022/07/15 MySQL