Python中使用logging模块打印log日志详解


Posted in Python onApril 05, 2015

学一门新技术或者新语言,我们都要首先学会如何去适应这们新技术,其中在适应过程中,我们必须得学习如何调试程序并打出相应的log信息来,正所谓“只要log打的好,没有bug解不了”,在我们熟知的一些信息技术中,log4xxx系列以及开发Android app时的android.util.Log包等等都是为了开发者更好的得到log信息服务的。在Python这门语言中,我们同样可以根据自己的程序需要打出log。

log信息不同于使用打桩法打印一定的标记信息,log可以根据程序需要而分出不同的log级别,比如info、debug、warn等等级别的信息,只要实时控制log级别开关就可以为开发人员提供更好的log信息,与log4xx类似,logger,handler和日志消息的调用可以有具体的日志级别(Level),只有在日志消息的级别大于logger和handler的设定的级别,才会显示。下面我就来谈谈我在Python中使用的logging模块一些方法。

logging模块介绍

Python的logging模块提供了通用的日志系统,熟练使用logging模块可以方便开发者开发第三方模块或者是自己的Python应用。同样这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP、GET/POST,SMTP,Socket等,甚至可以自己实现具体的日志记录方式。下文我将主要介绍如何使用文件方式记录log。

logging模块包括logger,handler,filter,formatter这四个基本概念。

logger:提供日志接口,供应用代码使用。logger最长用的操作有两类:配置和发送日志消息。可以通过logging.getLogger(name)获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象。
handler:将日志记录(log record)发送到合适的目的地(destination),比如文件,socket等。一个logger对象可以通过addHandler方法添加0到多个handler,每个handler又可以定义不同日志级别,以实现日志分级过滤显示。
filter:提供一种优雅的方式决定一个日志记录是否发送到handler。
formatter:指定日志记录输出的具体格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。

基本使用方法

一些小型的程序我们不需要构造太复杂的log系统,可以直接使用logging模块的basicConfig函数即可,代码如下:

'''

Created on 2012-8-12

 

@author: walfred

@module: loggingmodule.BasicLogger

'''

import logging

 

log_file = "./basic_logger.log"

 

logging.basicConfig(filename = log_file, level = logging.DEBUG)

 

logging.debug("this is a debugmsg!")

logging.info("this is a infomsg!")

logging.warn("this is a warn msg!")

logging.error("this is a error msg!")

logging.critical("this is a critical msg!")

运行程序时我们就会在该文件的当前目录下发现basic_logger.log文件,查看basic_logger.log内容如下:

INFO:root:this is a info msg!

DEBUG:root:this is a debug msg!

WARNING:root:this is a warn msg!

ERROR:root:this is a error msg!

CRITICAL:root:this is a critical msg!

需要说明的是我将level设定为DEBUG级别,所以log日志中只显示了包含该级别及该级别以上的log信息。信息级别依次是:notset、debug、info、warn、error、critical。如果在多个模块中使用这个配置的话,只需在主模块中配置即可,其他模块会有相同的使用效果。

较高级版本

上述的基础使用比较简单,没有显示出logging模块的厉害,适合小程序用,现在我介绍一个较高级版本的代码,我们需要依次设置logger、handler、formatter等配置。

'''

Created on 2012-8-12

 

@author: walfred

@module: loggingmodule.NomalLogger

'''

import logging

 

log_file = "./nomal_logger.log"

log_level = logging.DEBUG

 

logger = logging.getLogger("loggingmodule.NomalLogger")

handler = logging.FileHandler(log_file)

formatter = logging.Formatter("[%(levelname)s][%(funcName)s][%(asctime)s]%(message)s")

 

handler.setFormatter(formatter)

logger.addHandler(handler)

logger.setLevel(log_level)

 

#test

logger.debug("this is a debug msg!")

logger.info("this is a info msg!")

logger.warn("this is a warn msg!")

logger.error("this is a error msg!")

logger.critical("this is a critical msg!")

这时我们查看当前目录的nomal_logger.log日志文件,如下:

[DEBUG][][2012-08-12 17:43:59,295]this is a debug msg!

[INFO][][2012-08-12 17:43:59,295]this is a info msg!

[WARNING][][2012-08-12 17:43:59,295]this is a warn msg!

[ERROR][][2012-08-12 17:43:59,295]this is a error msg!

[CRITICAL][][2012-08-12 17:43:59,295]this is a critical msg!

这个对照前面介绍的logging模块,不难理解,下面的最终版本将会更加完整。

完善版本

这个最终版本我用singleton设计模式来写一个Logger类,代码如下:

'''

Created on 2012-8-12

 

@author: walfred

@module: loggingmodule.FinalLogger

'''

 

import logging.handlers

 

class FinalLogger:

 

 logger = None

 

 levels = {"n" : logging.NOTSET,

  "d" : logging.DEBUG,

  "i" : logging.INFO,

  "w" : logging.WARN,

  "e" : logging.ERROR,

  "c" : logging.CRITICAL}

 

 log_level = "d"

 log_file = "final_logger.log"

 log_max_byte = 10 * 1024 * 1024;

 log_backup_count = 5

 

 @staticmethod

 def getLogger():

  if FinalLogger.logger is not None:

   return FinalLogger.logger

 

  FinalLogger.logger = logging.Logger("oggingmodule.FinalLogger")

  log_handler = logging.handlers.RotatingFileHandler(filename = FinalLogger.log_file,\

  maxBytes = FinalLogger.log_max_byte,\

  backupCount = FinalLogger.log_backup_count)

  log_fmt = logging.Formatter("[%(levelname)s][%(funcName)s][%(asctime)s]%(message)s")

  log_handler.setFormatter(log_fmt)

  FinalLogger.logger.addHandler(log_handler)

  FinalLogger.logger.setLevel(FinalLogger.levels.get(FinalLogger.log_level))

  return FinalLogger.logger

 

if __name__ == "__main__":

 logger = FinalLogger.getLogger()

 logger.debug("this is a debug msg!")

 logger.info("this is a info msg!")

 logger.warn("this is a warn msg!")

 logger.error("this is a error msg!")

 logger.critical("this is a critical msg!")

当前目录下的 final_logger.log内容如下:

[DEBUG][][2012-08-12 18:12:23,029]this is a debug msg!

[INFO][][2012-08-12 18:12:23,029]this is a info msg!

[WARNING][][2012-08-12 18:12:23,029]this is a warn msg!

[ERROR][][2012-08-12 18:12:23,029]this is a error msg!

[CRITICAL][][2012-08-12 18:12:23,029]this is a critical msg!

这个final版本,也是我一直用的,读者朋友也可以再加上其他的一些Handler,比如StreamHandler等等来获取更多的log信息,当然也可以将你的log信息通过配置文件来完成。
Python 相关文章推荐
Python语法快速入门指南
Oct 12 Python
Python编程求解二叉树中和为某一值的路径代码示例
Jan 04 Python
将TensorFlow的模型网络导出为单个文件的方法
Apr 23 Python
Selenium控制浏览器常见操作示例
Aug 13 Python
Python闭包思想与用法浅析
Dec 27 Python
python实现把二维列表变为一维列表的方法分析
Oct 08 Python
基于Tensorflow批量数据的输入实现方式
Feb 05 Python
python图形开发GUI库wxpython使用方法详解
Feb 14 Python
Python基础之列表常见操作经典实例详解
Feb 26 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
Mar 04 Python
Python loguru日志库之高效输出控制台日志和日志记录
Mar 07 Python
python 求两个向量的顺时针夹角操作
Mar 04 Python
Python中的两个内置模块介绍
Apr 05 #Python
Python中不同进制互相转换(二进制、八进制、十进制和十六进制)
Apr 05 #Python
Python中使用第三方库xlrd来写入Excel文件示例
Apr 05 #Python
Python中使用第三方库xlrd来读取Excel示例
Apr 05 #Python
Python中使用第三方库xlutils来追加写入Excel文件示例
Apr 05 #Python
Python下使用Psyco模块优化运行速度
Apr 05 #Python
Python中使用tarfile压缩、解压tar归档文件示例
Apr 05 #Python
You might like
手把手教你使用DedeCms的采集的图文教程
2007/03/11 PHP
php _autoload自动加载类与机制分析
2012/02/10 PHP
php中将指针移动到数据集初始位置的实现代码[mysql_data_seek]
2012/11/01 PHP
关于Zend Studio 配色方案插件的介绍
2013/06/24 PHP
php实现通过ftp上传文件
2015/06/19 PHP
用javascript获取地址栏参数
2006/12/22 Javascript
dojo 之基础篇(三)之向服务器发送数据
2007/03/24 Javascript
createElement与createDocumentFragment的点点区别小结
2011/12/19 Javascript
JavaScript 反科里化 this [译]
2012/09/20 Javascript
JSON 数字排序多字段排序介绍
2013/09/18 Javascript
为开发者准备的10款最好的jQuery日历插件
2014/02/04 Javascript
jquery的ajax简单结构示例代码
2014/02/17 Javascript
JavaScript_ECMA5数组新特性详解
2016/06/12 Javascript
如何使用Vuex+Vue.js构建单页应用
2016/10/27 Javascript
微信小程序网络请求wx.request详解及实例
2017/05/18 Javascript
vue实现app页面切换动画效果实例
2017/05/23 Javascript
js点击时关闭该范围下拉菜单之外的菜单方法
2018/01/11 Javascript
vue iview组件表格 render函数的使用方法详解
2018/03/15 Javascript
JQuery元素快速查找与操作
2018/04/22 jQuery
[27:02]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第三场
2014/05/24 DOTA
[02:28]DOTA2亚洲邀请赛附加赛 RECAP赛事回顾
2015/01/29 DOTA
[06:14]《辉夜杯》外卡赛附加赛 4支战队巡礼
2015/10/23 DOTA
python获取远程图片大小和尺寸的方法
2015/03/26 Python
Python中的rjust()方法使用详解
2015/05/19 Python
基于windows下pip安装python模块时报错总结
2018/06/12 Python
Python中的支持向量机SVM的使用(附实例代码)
2019/06/26 Python
Python Gitlab Api 使用方法
2019/08/28 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
python保留小数位的三种实现方法
2020/01/07 Python
美国知名的百货清仓店:Neiman Marcus Last Call
2016/08/03 全球购物
大学生简历的个人自我评价
2013/12/04 职场文书
有限责任公司股东合作协议书范本
2014/10/30 职场文书
消防宣传语大全
2015/07/13 职场文书
申请吧主发表的感言
2015/08/03 职场文书
大学生团支书竞选稿
2015/11/21 职场文书
原生JS实现飞机大战小游戏
2021/06/09 Javascript