详解Python中的日志模块logging


Posted in Python onJune 19, 2015

许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪。在.NET平台中,有非常著名的第三方开源日志组件log4net,c++中,有人们熟悉的log4cpp,而在python中,我们不需要第三方的日志组件,因为它已经为我们提供了简单易用、且功能强大的日志模块:logging。logging模块支持将日志信息保存到不同的目标域中,如:保存到日志文件中;以邮件的形式发送日志信息;以http get或post的方式提交日志到web服务器;以windows事件的形式记录等等。这些日志保存方式可以组合使用,每种方式可以设置自己的日志级别以及日志格式。日志模块的内容比较多,今天先学习logging模块的基本使用,下次具体学习日志的处理。

先看一个比较简单的例子,让我们对logging模块有个感性的认识:
 

import logging
logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG)
logging.debug('this is a message')

运行上面例子的代码,将会在程序的根目录下创建一个log.txt文件,打开该文件,里面有一条日志记录:”DEBUG:root:this is a message”。
4个主要的组件

  1. logger: 日志类,应用程序往往通过调用它提供的api来记录日志;
  2. handler: 对日志信息处理,可以将日志发送(保存)到不同的目标域中;
  3. filter: 对日志信息进行过滤;
  4. formatter:日志的格式化;

日志级别

在记录日志时, 日志消息都会关联一个级别(“级别”本质上是一个非负整数)。系统默认提供了6个级别,它们分别是:

详解Python中的日志模块logging

可以给日志对象(Logger Instance)设置日志级别,低于该级别的日志消息将会被忽略,也可以给Hanlder设置日志级别,对于低于该级别的日志消息, Handler也会忽略。

logging模块中的常用函数:
logging.basicConfig([**kwargs]):

为日志模块配置基本信息。kwargs 支持如下几个关键字参数:

  • filename :日志文件的保存路径。如果配置了些参数,将自动创建一个FileHandler作为Handler;
  • filemode :日志文件的打开模式。 默认值为'a',表示日志消息以追加的形式添加到日志文件中。如果设为'w', 那么每次程序启动的时候都会创建一个新的日志文件;
  • format :设置日志输出格式;
  • datefmt :定义日期格式;
  • level :设置日志的级别.对低于该级别的日志消息将被忽略;
  • stream :设置特定的流用于初始化StreamHandler;

下面是一个简单的例子:
 

#coding=gbk
import logging
logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), /
  level = logging.WARN, filemode = 'w', format = '%(asctime)s - %(levelname)s: %(message)s')
logging.debug('debug') 
#被忽略
logging.info('info')  
#被忽略
logging.warning('warn')
logging.error('error')
#----- 结果
#2009-07-13 21:42:15,592 - WARNING: warn
#2009-07-13 21:42:15,640 - ERROR: error
logging.getLogger([name])

创建Logger对象。日志记录的工作主要由Logger对象来完成。在调用getLogger时要提供Logger的名称(注:多次使用相同名称来调用getLogger,返回的是同一个对象的引用。),Logger实例之间有层次关系,这些关系通过Logger名称来体现,如:

p = logging.getLogger(“root”)

c1 = logging.getLogger(“root.c1″)

c2 = logging.getLogger(“root.c2″)

例子中,p是父logger, c1,c2分别是p的子logger。c1, c2将继承p的设置。如果省略了name参数, getLogger将返回日志对象层次关系中的根Logger。
logging.setLoggerClass(klass)
logging.getLoggerClass()

获取/设置日志类型。用户可以自定义日志类来代替系统提供的logging.Logger类。
logging.getLevelName(lvl)

获取日志级别对应的名称。例如:
 

print logging.getLevelName(logging.NOTSET)
print logging.getLevelName(10) 
#logging.DEBUG
print logging.getLevelName(logging.DEBUG)
print logging.getLevelName(30) 
#logging.WARN
print logging.getLevelName(logging.ERROR)
print logging.getLevelName(50) 
#logging.CRITICAL
logging.shutdown()

当不再使用日志系统的时候,调用该方法,它会将日志flush到对应的目标域上。一般在系统退出的时候调用。

Logger对象 通过调用logging.getLogger(name)来创建,它有如下常用的方法和属性:
Logger.setLevel(lvl):

设置日志的级别。对于低于该级别的日志消息将被忽略。下面一个例子演示setLevel方法:
 

#coding=gbk
import logging
logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG)
log = logging.getLogger('root.test')
log.setLevel(logging.WARN) #日志记录级别为WARNNING
log.info('info')  #不会被记录
log.debug('debug') #不会被记录
log.warning('warnning')
log.error('error')
Logger.debug(msg [ ,*args [, **kwargs]])

记录DEBUG级别的日志信息。参数msg是信息的格式,args与kwargs分别是格式参数。

import logging
logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG)
log = logging.getLogger('root')
log.debug('%s, %s, %s', *('error', 'debug', 'info'))
log.debug('%(module)s, %(info)s', {'module': 'log', 'info': 'error'})
Logger.info(msg[ , *args[ , **kwargs] ] )
Logger.warnning(msg[ , *args[ , **kwargs] ] )
Logger.error(msg[ , *args[ , **kwargs] ] )
Logger.critical(msg[ , *args[ , **kwargs] ] )

记录相应级别的日志信息。参数的含义与Logger.debug一样。
Logger.log(lvl, msg[ , *args[ , **kwargs] ] )

记录日志,参数lvl用户设置日志信息的级别。参数msg, *args, **kwargs的含义与Logger.debug一样。
Logger.exception(msg[, *args])

以ERROR级别记录日志消息,异常跟踪信息将被自动添加到日志消息里。Logger.exception通过用在异常处理块中,如:
 

import logging
logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG)
log = logging.getLogger('root')
try:
  raise Exception, 'this is a exception'
except:
  log.exception('exception') 
#异常信息被自动添加到日志消息中
Logger.addFilter(filt)
Logger.removeFilter(filt)

添加/移除日志消息过滤器。在讲述Filter时具体介绍。
Logger.addHandler(hdlr)
Logger.removeHandler(hdlr)

添加/移除日志消息处理器。在讲述Handler时具体介绍。
Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info[, func, extra])

创建LogRecord对象。日志消息被实例为一个LogRecord对象,并在日志类内处理。

Python 相关文章推荐
python基础教程之类class定义使用方法
Feb 20 Python
Python中optparse模块使用浅析
Jan 01 Python
Django中几种重定向方法
Apr 28 Python
开源Web应用框架Django图文教程
Mar 09 Python
Python做简单的字符串匹配详解
Mar 21 Python
Python基于list的append和pop方法实现堆栈与队列功能示例
Jul 24 Python
Tensorflow 利用tf.contrib.learn建立输入函数的方法
Feb 08 Python
Windows下安装Django框架的方法简明教程
Mar 28 Python
python re库的正则表达式入门学习教程
Mar 08 Python
python中tkinter窗口位置\坐标\大小等实现示例
Jul 09 Python
详解Python 循环嵌套
Jul 09 Python
Python大批量搜索引擎图像爬虫工具详解
Nov 16 Python
使用httplib模块来制作Python下HTTP客户端的方法
Jun 19 #Python
举例详解Python中threading模块的几个常用方法
Jun 18 #Python
Python的time模块中的常用方法整理
Jun 18 #Python
Python抽象类的新写法
Jun 18 #Python
Python实现的彩票机选器实例
Jun 17 #Python
Python基于Tkinter实现的记事本实例
Jun 17 #Python
Python基于Tkinter的HelloWorld入门实例
Jun 17 #Python
You might like
漫荒推荐:画风超赞的国风漫画推荐 超长假期不无聊
2020/03/08 国漫
php中的三元运算符使用说明
2011/07/03 PHP
php好代码风格的阶段性总结
2016/06/25 PHP
PHP数组相加操作及与array_merge的区别浅析
2016/11/26 PHP
yii2.0整合阿里云oss的示例代码
2017/09/19 PHP
比较详细的javascript对象的property和prototype是什么一种关系
2007/08/06 Javascript
Javascript 面向对象(三)接口代码
2012/05/23 Javascript
关于全局变量和局部变量的那些事
2013/01/11 Javascript
javascript实现文字图片上下滚动的具体实例
2013/06/28 Javascript
HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
2015/11/25 Javascript
基于AngularJS+HTML+Groovy实现登录功能
2016/02/17 Javascript
DataTables+BootStrap组合使用Ajax来获取数据并且动态加载dom的方法(排序,过滤,分页等)
2016/11/09 Javascript
原生js编写焦点图效果
2016/12/08 Javascript
关于Javascript中document.cookie的使用
2017/03/08 Javascript
vue中mint-ui环境搭建详细介绍
2017/04/06 Javascript
详解基于iview-ui的导航栏路径(面包屑)配置
2019/02/22 Javascript
Angular8基础应用之表单及其验证
2019/08/11 Javascript
JavaScript使用表单元素验证表单的示例代码
2019/08/20 Javascript
vue图片加载失败时用默认图片替换的方法
2019/08/29 Javascript
Echarts实现单条折线可拖拽效果
2019/12/19 Javascript
js实现简单的倒计时
2021/01/28 Javascript
JavaScript实现点击出现子菜单效果
2021/02/08 Javascript
[03:02]辉夜杯主赛事第二日 每日之星
2015/12/27 DOTA
python基础教程之对象和类的实际运用
2014/08/29 Python
仅用50行Python代码实现一个简单的代理服务器
2015/04/08 Python
深入解析Python中的线程同步方法
2016/06/14 Python
Python中文分词工具之结巴分词用法实例总结【经典案例】
2017/04/15 Python
python命令行参数用法实例分析
2019/06/25 Python
用Python配平化学方程式的方法
2019/07/20 Python
解决python pandas读取excel中多个不同sheet表格存在的问题
2020/07/14 Python
追悼会上的答谢词
2014/01/10 职场文书
工程采购员岗位职责
2014/03/09 职场文书
2016年幼儿园教师师德承诺书
2016/03/25 职场文书
大学学生会主席竞选稿怎么写?
2019/08/19 职场文书
励志语录:你若不勇敢,谁替你坚强
2019/11/08 职场文书
pytorch 实现多个Dataloader同时训练
2021/05/29 Python