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 相关文章推荐
简单介绍Python的Tornado框架中的协程异步实现原理
Apr 23 Python
在Python中使用next()方法操作文件的教程
May 24 Python
python 性能优化方法小结
Mar 31 Python
python 实现将文件或文件夹用相对路径打包为 tar.gz 文件的方法
Jun 10 Python
python的常见矩阵运算(小结)
Aug 07 Python
Python generator生成器和yield表达式详解
Aug 08 Python
python带参数打包exe及调用方式
Dec 21 Python
详解python itertools功能
Feb 07 Python
python读取excel进行遍历/xlrd模块操作
Jul 12 Python
浅谈python 类方法/静态方法
Sep 18 Python
python基于selenium爬取斗鱼弹幕
Feb 20 Python
python爬虫之利用selenium模块自动登录CSDN
Apr 22 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
php5新改动之短标记启用方法
2008/09/11 PHP
php实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
php使用pdo连接sqlite3的配置示例
2016/05/27 PHP
thinkphp下MySQL数据库读写分离代码剖析
2017/04/18 PHP
CSS常用网站布局实例
2008/04/03 Javascript
jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
2011/09/22 Javascript
jQuery常用知识点总结以及平时封装常用函数
2016/02/23 Javascript
JS实现获取剪贴板内容的方法
2016/06/21 Javascript
多种方式实现js图片预览
2016/12/12 Javascript
浅谈React + Webpack 构建打包优化
2018/01/23 Javascript
SVG实现时钟效果
2018/07/17 Javascript
webpack 静态资源集中输出的方法示例
2018/11/09 Javascript
vue使用pdfjs显示PDF可复制的实现方法
2018/12/14 Javascript
Vuex中实现数据状态查询与更改
2019/11/08 Javascript
python实现迭代法求方程组的根过程解析
2019/11/25 Javascript
微信小程序wxs实现吸顶效果
2020/01/08 Javascript
关于element-ui表单中限制输入纯数字的解决方式
2020/09/08 Javascript
[03:58]2014DOTA2国际邀请赛 龙宝赛后解密DK获胜之道
2014/07/14 DOTA
[00:12]2018DOTA2亚洲邀请赛SOLO赛 MidOne是否中单第一人?
2018/04/05 DOTA
[50:02]完美世界DOTA2联赛PWL S2 Magma vs FTD 第三场 11.29
2020/12/03 DOTA
人工智能最火编程语言 Python大战Java!
2017/11/13 Python
python实现校园网自动登录的示例讲解
2018/04/22 Python
Python中format()格式输出全解
2019/04/12 Python
python实现读取excel文件中所有sheet操作示例
2019/08/09 Python
python是否适合网页编程详解
2019/10/04 Python
在django admin详情表单显示中添加自定义控件的实现
2020/03/11 Python
Python startswith()和endswith() 方法原理解析
2020/04/28 Python
英国领先的酒类网上商城:TheDrinkShop
2017/03/16 全球购物
Java如何格式化日期
2012/08/07 面试题
2014年教学工作总结
2014/11/13 职场文书
公司优秀员工推荐信
2015/03/24 职场文书
建筑工程材料员岗位职责
2015/04/11 职场文书
先进教师个人主要事迹材料
2015/11/03 职场文书
实例讲解Python中sys.argv[]的用法
2021/06/03 Python
基于MySql验证的vsftpd虚拟用户
2021/11/07 MySQL
Mysql存储过程、触发器、事件调度器使用入门指南
2022/01/22 MySQL