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搭建Django应用程序步骤及版本冲突问题解决
Nov 19 Python
利用soaplib搭建webservice详细步骤和实例代码
Nov 20 Python
Python创建对称矩阵的方法示例【基于numpy模块】
Oct 12 Python
Python 中Django验证码功能的实现代码
Jun 20 Python
Python 获取指定文件夹下的目录和文件的实现
Aug 30 Python
kafka-python 获取topic lag值方式
Dec 23 Python
pytorch模型存储的2种实现方法
Feb 14 Python
python中的 zip函数详解及用法举例
Feb 16 Python
python能自学吗
Jun 18 Python
如何使用 Python 读取文件和照片的创建日期
Sep 05 Python
在python中对于bool布尔值的取反操作
Dec 11 Python
Pytorch实现图像识别之数字识别(附详细注释)
May 11 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 var_dump()函数的详解
2013/06/05 PHP
php获取目标函数执行时间示例
2014/03/04 PHP
PHP容器类的两种实现方式示例
2019/07/24 PHP
JavaScript 参考教程
2006/12/29 Javascript
js判断输入是否为正整数、浮点数等数字的函数代码
2010/11/17 Javascript
jquery的ajax请求全面了解
2013/03/20 Javascript
jQuery javaScript捕获回车事件(示例代码)
2013/11/07 Javascript
动态加载jQuery的方法
2015/06/16 Javascript
Javascript实现鼠标右键特色菜单
2015/08/04 Javascript
JS利用cookie记忆当前位置的防刷新导航效果
2015/10/15 Javascript
使用postMesssage()实现iframe跨域页面间的信息传递
2016/03/29 Javascript
Bootstrap学习笔记之css样式设计(1)
2016/06/07 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
2017/03/14 Javascript
Vue的百度地图插件尝试使用
2017/09/06 Javascript
JS实现获取毫秒值及转换成年月日时分秒的方法
2018/08/15 Javascript
Vue中的$set的使用实例代码
2018/10/08 Javascript
Django+vue跨域问题解决的详细步骤
2019/01/20 Javascript
DatePickerDialog 自定义样式及使用全解
2019/07/09 Javascript
vue-video-player实现实时视频播放方式(监控设备-rtmp流)
2020/08/10 Javascript
python socket 超时设置 errno 10054
2014/07/01 Python
python计算对角线有理函数插值的方法
2015/05/07 Python
浅谈Python中chr、unichr、ord字符函数之间的对比
2016/06/16 Python
windows下python连接oracle数据库
2017/06/07 Python
python之django母板页面的使用
2018/07/03 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
2019/05/05 Python
浅谈python 调用open()打开文件时路径出错的原因
2020/06/05 Python
Python 测试框架unittest和pytest的优劣
2020/09/26 Python
如何避免常见的6种HTML5错误用法
2017/11/06 HTML / CSS
自动化工程专业个人应聘自荐信
2013/09/26 职场文书
母亲节感恩活动记录
2014/03/16 职场文书
个人批评与自我批评材料
2014/10/17 职场文书
违反交通安全法检讨书
2014/10/24 职场文书
公司保密管理制度
2015/08/04 职场文书
2016年小学圣诞节活动总结
2016/03/31 职场文书
MySQL创建索引需要了解的
2021/04/08 MySQL
JVM入门之类加载与字节码技术(类加载与类的加载器)
2021/06/15 Java/Android