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 相关文章推荐
使用IronPython把Python脚本集成到.NET程序中的教程
Mar 31 Python
python使用arp欺骗伪造网关的方法
Apr 24 Python
Python中Random和Math模块学习笔记
May 18 Python
在Python中使用defaultdict初始化字典以及应用方法
Oct 31 Python
使用 Python 快速实现 HTTP 和 FTP 服务器的方法
Jul 22 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
Mar 30 Python
Python bisect模块原理及常见实例
Jun 17 Python
python3将变量输入的简单实例
Aug 19 Python
python利用 keyboard 库记录键盘事件
Oct 16 Python
Python爬虫爬取微博热搜保存为 Markdown 文件的源码
Feb 22 Python
Python基础详解之邮件处理
Apr 28 Python
Python实现提取PDF简历信息并存入Excel
Apr 02 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
解析PayPal支付接口的PHP开发方式
2010/11/28 PHP
php调用Google translate_tts api实现代码
2013/08/07 PHP
Mac环境下php操作mysql数据库的方法分享
2015/05/11 PHP
用js实现手把手教你月入万刀(转贴)
2007/11/07 Javascript
复制本贴标题和地址的js代码
2008/07/01 Javascript
JavaScript打字小游戏代码
2011/12/26 Javascript
jQuery中校验时间格式的正则表达式小结
2013/09/22 Javascript
JavaScript使用indexOf获得子字符串在字符串中位置的方法
2015/04/06 Javascript
通过设置CSS中的position属性来固定层的位置
2015/12/14 Javascript
javascript实现dom元素可拖动
2016/03/21 Javascript
Bootstrap Chart组件使用教程
2016/04/28 Javascript
全面解析Bootstrap中form、navbar的使用方法
2016/05/30 Javascript
浅析javascript中的Event事件
2016/12/09 Javascript
BootStrap Datetimepicker 汉化的实现代码
2017/02/10 Javascript
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
2017/11/10 jQuery
vue interceptor 使用教程实例详解
2018/09/13 Javascript
微信小程序利用Canvas绘制图片和竖排文字详解
2019/06/25 Javascript
layui异步加载table表中某一列数据的例子
2019/09/16 Javascript
微信小程序实现左侧滑动导航栏
2020/04/08 Javascript
小程序自动化测试的示例代码
2020/08/11 Javascript
零基础写python爬虫之HTTP异常处理
2014/11/05 Python
Python字符串拼接的几种方法整理
2017/08/02 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
将Django项目部署到CentOs服务器中
2018/10/18 Python
python Matplotlib数据可视化(1):简单入门
2020/09/30 Python
凯伦·米莲女装网上商店:Karen Millen
2017/11/07 全球购物
电子狗项圈:eDog Australia
2019/12/04 全球购物
乌克兰设计师和品牌的服装:Love&Live
2020/04/14 全球购物
为什么使用接口?
2014/08/13 面试题
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
列车乘务员工作不细心检讨书
2014/10/07 职场文书
仓库统计员岗位职责
2015/04/14 职场文书
入党积极分子培养联系人意见
2015/08/12 职场文书
员工聘用合同范本
2015/09/21 职场文书
html+css实现环绕倒影加载特效
2021/07/07 HTML / CSS