python标准日志模块logging的使用方法


Posted in Python onNovember 01, 2013

最近写一个爬虫系统,需要用到python的日志记录模块,于是便学习了一下。
python的标准库里的日志系统从Python2.3开始支持。只要import 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')

结合上面的例子,我们说下几个最常使用的API:

logging.getLogger([name])

返回一个logger实例,如果没有指定name,返回root logger。只要name相同,返回的logger实例都是同一个而且只有一个,即name和logger实例是一一对应的。这意味着,无需把logger实例在各个模块中传递。只要知道name,就能得到同一个logger实例。

Logger.setLevel(lvl)

设置logger的level, level有以下几个级别:

级别高低顺序: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)
通过handler对象可以把日志内容写到不同的地方。比如简单的StreamHandler就是把日志写到类似文件的地方。python提供了十几种实用handler,比较常用有:
StreamHandler: 输出到控制台
 FileHandler:   输出到文件
BaseRotatingHandler 可以按时间写入到不同的日志中。比如将日志按天写入不同的日期结尾的文件文件。
SocketHandler 用TCP网络连接写LOG
DatagramHandler 用UDP网络连接写LOG
SMTPHandler 把LOG写成EMAIL邮寄出去

logging.basicConfig([**kwargs])* 这个函数用来配置root logger, 为root logger创建一个StreamHandler,设置默认的格式。* 这些函数: logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical() 如果调用的时候发现root logger没有任何handler,会自动调用basicConfig添加一个handler* 如果root logger已有handler,这个函数不做任何事情使用basicConfig来配置root logger的输出格式和level:
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')

ogger对象直接提供日志接口。formatter描述日志的格式。handler把日志写到不同的地方,你可以把日志保存成本地文件,也可以每个小时写一个日志文件,还可以把日志通过socket传到别的机器上。
从最简单的formatter对象来看。formatter指定的是每一条日志记录的抬头信息,也就是你可以指定日志记录的时间格式、进程号、文件名、函数名等信息。可以用这个方法来创建一个formatter对象:
logging.Formatter.__init__( fmt=None, datefmt=None)

fmt参数指定进程号、文件名、函数名等信息是否出现以及格式, datefmt为日期时间格式,默认的日期格式精确到微秒,例如‘2003-07-08 16:49:45,896'。fmt中可以指定多个字段,每个字段的格式为“%(<dictionary key>)s”, 例如你想打印时间、日志级别、日志信息可以用下面的format:
'%(asctime)s - %(levelname)s - %(message)s'

python标准日志模块logging的使用方法在记录爬虫系统日志的时候需要定义记录日志的级别,级别越高表示打出来的日志越详细。我们可以用一个字典来设置不同级别对应的不同日志信息:
#用字典保存日志级别
format_dict = {
   1 : logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'),
   2 : logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'),
   3 : logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'),
   4 : logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'),
   5 : logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
}

将本文开始的代码封装在一个类中
#开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件   
class Logger():
    def __init__(self, logname, loglevel, logger):
        '''
           指定保存日志的文件路径,日志级别,以及调用文件
           将日志存入到指定的文件中
        '''        # 创建一个logger
        self.logger = logging.getLogger(logger)
        self.logger.setLevel(logging.DEBUG)
        # 创建一个handler,用于写入日志文件
        fh = logging.FileHandler(logname)
        fh.setLevel(logging.DEBUG)
        # 再创建一个handler,用于输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        # 定义handler的输出格式
        #formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        formatter = format_dict[int(loglevel)]
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)
        # 给logger添加handler
        self.logger.addHandler(fh)
        self.logger.addHandler(ch)
    
    def getlog(self):
        return self.logger

再通过以下方式调用,便是一个简单的日志系统了
logger = Logger(logname='log.txt', loglevel=1, logger="fox").getlog()
Python 相关文章推荐
玩转python爬虫之URLError异常处理
Feb 17 Python
对Python中数组的几种使用方法总结
Jun 28 Python
[原创]Python入门教程4. 元组基本操作
Oct 31 Python
在python3中pyqt5和mayavi不兼容问题的解决方法
Jan 08 Python
Python3日期与时间戳转换的几种方法详解
Jun 04 Python
Python学习笔记基本数据结构之序列类型list tuple range用法分析
Jun 08 Python
mac系统下Redis安装和使用步骤详解
Jul 09 Python
Django REST framework 如何实现内置访问频率控制
Jul 23 Python
python正则表达式 匹配反斜杠的操作方法
Aug 07 Python
python 中的9个实用技巧,助你提高开发效率
Aug 30 Python
Python中random模块常用方法的使用教程
Oct 04 Python
Python GUI库Tkiner使用方法代码示例
Nov 27 Python
python类定义的讲解
Nov 01 #Python
用实例说明python的*args和**kwargs用法
Nov 01 #Python
python操作MongoDB基础知识
Nov 01 #Python
python操作MySQL数据库具体方法
Oct 28 #Python
Python sys.path详细介绍
Oct 17 #Python
python开发的小球完全弹性碰撞游戏代码
Oct 15 #Python
python中 ? : 三元表达式的使用介绍
Oct 09 #Python
You might like
php中的filesystem文件系统函数介绍及使用示例
2014/02/13 PHP
ThinkPHP自动转义存储富文本编辑器内容导致读取出错的解决方法
2014/08/08 PHP
php结合js实现点击超链接执行删除确认操作
2014/10/31 PHP
简单了解将WordPress中的工具栏移到底部的小技巧
2015/12/31 PHP
Laravel如何实现自动加载类
2019/10/14 PHP
PHP全局使用Laravel辅助函数dd
2019/12/26 PHP
PHP数组Key强制类型转换实现原理解析
2020/09/01 PHP
关于取不到由location.href提交而来的上级页面地址的解决办法
2009/07/30 Javascript
JQuery处理json与ajax返回JSON实例代码
2014/01/03 Javascript
js中settimeout方法加参数
2014/02/28 Javascript
改变隐藏的input中value值的方法
2014/03/19 Javascript
jQuery Easyui学习教程之实现datagrid在没有数据时显示相关提示内容
2016/07/09 Javascript
Bootstrap的class样式小结
2016/12/01 Javascript
vue之数据交互实例代码
2017/06/20 Javascript
js实现Tab选项卡切换效果
2020/07/17 Javascript
JS二分查找算法详解
2017/11/01 Javascript
解决Vue使用swiper动态加载数据,动态轮播数据显示白屏的问题
2018/09/27 Javascript
小程序实现页面顶部选项卡效果
2018/11/06 Javascript
JS内置对象和Math对象知识点详解
2020/04/03 Javascript
JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
2020/04/13 Javascript
js实现滑动滑块验证登录
2020/07/24 Javascript
angular *Ngif else用法详解
2020/12/15 Javascript
记录Django开发心得
2014/07/16 Python
Python求均值,方差,标准差的实例
2019/06/29 Python
Python pip安装第三方库实现过程解析
2020/07/09 Python
Pycharm Git 设置方法
2020/09/15 Python
python 代码运行时间获取方式详解
2020/09/18 Python
css3之UI元素状态伪类选择器实例演示
2017/08/11 HTML / CSS
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
世界上最大的字体市场:MyFonts
2020/01/10 全球购物
请用用Java代码写一个堆栈
2012/01/26 面试题
先进典型发言材料
2014/12/30 职场文书
法制工作总结2015
2015/07/23 职场文书
2016入党积极分子心得体会
2016/01/06 职场文书
浅谈Golang 嵌套 interface 的赋值问题
2021/04/29 Golang
Redis的字符串是如何实现的
2021/10/24 Redis