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 相关文章推荐
一个检测OpenSSL心脏出血漏洞的Python脚本分享
Apr 10 Python
Python中实现参数类型检查的简单方法
Apr 21 Python
python通过openpyxl生成Excel文件的方法
May 12 Python
python 3.0 模拟用户登录功能并实现三次错误锁定
Nov 01 Python
Python中字典的浅拷贝与深拷贝用法实例分析
Jan 02 Python
Python3中的列表生成式、生成器与迭代器实例详解
Jun 11 Python
Python3.6简单的操作Mysql数据库的三个实例
Oct 17 Python
Python中new方法的详解
Jan 15 Python
Python绘制堆叠柱状图的实例
Jul 09 Python
使用Pytorch来拟合函数方式
Jan 14 Python
计算Python Numpy向量之间的欧氏距离实例
May 22 Python
Django REST Swagger实现指定api参数
Jul 07 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学习之 数组声明
2011/06/09 PHP
快速解决PHP调用Word组件DCOM权限的问题
2017/12/27 PHP
在PHP中实现使用Guzzle执行POST和GET请求
2019/10/15 PHP
JQuery困惑—包装集 DOM节点
2009/10/16 Javascript
document.documentElement和document.body区别介绍
2013/09/16 Javascript
jQuery窗口、文档、网页各种高度的精确理解
2014/07/02 Javascript
不到30行JS代码实现Excel表格的方法
2014/11/15 Javascript
根据user-agent判断蜘蛛代码黑帽跳转代码(js版与php版本)
2015/09/14 Javascript
功能强大的jquery.validate表单验证插件
2016/11/07 Javascript
jQuery实现二维码扫描功能
2017/01/09 Javascript
最全的JavaScript开发工具列表 总有一款适合你
2017/06/29 Javascript
Vue的Class与Style绑定的方法
2017/09/01 Javascript
bootstrap Table服务端处理分页(后台是.net)
2017/10/19 Javascript
javascript用rem来做响应式开发
2018/01/13 Javascript
jQuery中的for循环var与let的区别
2018/04/21 jQuery
NodeJS搭建HTTP服务器的实现步骤
2018/10/12 NodeJs
微信小程序实现图片选择并预览功能
2019/07/25 Javascript
layui 点击重置按钮, select 并没有被重置的解决方法
2019/09/03 Javascript
在vue和element-ui的table中实现分页复选功能
2019/12/04 Javascript
[52:41]OG vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/20 DOTA
详解Python中的type()方法的使用
2015/05/21 Python
python3实现raspberry pi(树莓派)4驱小车控制程序
2020/02/12 Python
anaconda3安装及jupyter环境配置全教程
2020/08/24 Python
python matplotlib库的基本使用
2020/09/23 Python
加拿大在线旅游公司:Flighthub
2019/03/11 全球购物
教师廉洁自律承诺书
2014/05/26 职场文书
五一口号
2014/06/19 职场文书
医院深入开展党的群众路线教育实践活动实施方案
2014/08/27 职场文书
无违反计划生育证明格式
2015/06/24 职场文书
上班旷工检讨书
2015/08/15 职场文书
村官2015年度工作总结
2015/10/14 职场文书
Python中X[:,0]和X[:,1]的用法
2021/05/10 Python
python spilt()分隔字符串的实现示例
2021/05/21 Python
python基础入门之字典和集合
2021/06/13 Python
Redis 的查询很快的原因解析及Redis 如何保证查询的高效
2022/03/16 Redis
MySQL实现配置主从复制项目实践
2022/03/31 MySQL