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多进程同步简单实现代码
Apr 27 Python
python 网络编程常用代码段
Aug 28 Python
安装python3的时候就是输入python3死活没有反应的解决方法
Jan 24 Python
pandas数据预处理之dataframe的groupby操作方法
Apr 13 Python
利用Python如何批量修改数据库执行Sql文件
Jul 29 Python
python hook监听事件详解
Oct 25 Python
Django使用中间件解决前后端同源策略问题
Sep 02 Python
Python range、enumerate和zip函数用法详解
Sep 11 Python
Python字节单位转换实例
Dec 05 Python
Python中的None与 NULL(即空字符)的区别详解
Sep 24 Python
如何在pycharm中安装第三方包
Oct 27 Python
如何基于python实现单目三维重建详解
Jun 25 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
优化NFR之一 --MSSQL Hello Buffer Overflow
2006/10/09 PHP
解决GD中文乱码问题
2007/02/14 PHP
php中文字符串截取方法实例总结
2014/09/30 PHP
Thinkphp关闭缓存的方法
2015/06/26 PHP
PHP实现的数独求解问题示例
2017/04/18 PHP
php检测mysql表是否存在的方法小结
2017/07/20 PHP
Laravel 6.2 中添加了可调用容器对象的方法
2019/10/22 PHP
Mootools 1.2教程 输入过滤第二部分(字符串)
2009/09/15 Javascript
avascript中的自执行匿名函数应用示例
2014/09/15 Javascript
node.js中的fs.lchmodSync方法使用说明
2014/12/16 Javascript
解析JavaScript的ES6版本中的解构赋值
2015/07/28 Javascript
基于jQuery通过jQuery.form.js插件使用ajax提交form表单
2015/08/17 Javascript
jQuery插件学习教程之SlidesJs轮播+Validation验证
2016/07/12 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
2016/09/08 Javascript
JS非空验证及邮箱验证的实例
2017/08/11 Javascript
Vue从TodoList中学父子组件通信
2019/02/05 Javascript
Vue基本使用之对象提供的属性功能
2019/04/30 Javascript
微信小程序实现日期格式化和倒计时
2020/11/01 Javascript
JavaScript设计模型Iterator实例解析
2020/01/22 Javascript
JS PHP字符串截取函数实现原理解析
2020/08/29 Javascript
Python制作爬虫抓取美女图
2016/01/20 Python
Python3计算三角形的面积代码
2017/12/18 Python
Python3.5内置模块之time与datetime模块用法实例分析
2019/04/27 Python
详解Pandas之容易让人混淆的行选择和列选择
2019/07/10 Python
Python流程控制 if else实现解析
2019/09/02 Python
pycharm专业版远程登录服务器的详细教程
2020/09/15 Python
Python提取视频中图片的示例(按帧、按秒)
2020/10/22 Python
美国Curacao百货连锁店网站:iCuracao.com
2019/07/20 全球购物
初中学生期末评语
2014/04/24 职场文书
绿色环保口号
2014/06/12 职场文书
干部年终考核评语
2015/01/04 职场文书
2015年征兵工作总结
2015/07/23 职场文书
《桂花雨》教学反思
2016/02/19 职场文书
JavaScript继承的三种方法实例
2021/05/12 Javascript
Win10系统下配置Java环境变量
2021/06/13 Java/Android
向Spring IOC 容器动态注册bean实现方式
2022/07/15 Java/Android