logger 提供了应用程序可以直接使用的接口handler将(logger创建的)日志记录发送到合适的目的输出filter提供了细度设备来决定输出哪条日志记录formatter决定日志记录的最终输出格式

logging模块介绍

logger 提供了应用程序可以直接使用的接口
handler将(logger创建的)日志记录发送到合适的目的输出
filter提供了细度设备来决定输出哪条日志记录
formatter决定日志记录的最终输出格式

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

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

logging模块与log4j的机制是一样的,只是具体的实现细节不同。模块提供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的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。

与log4j类似,logger,handler和日志消息的调用可以有具体的日志级别(Level),只有在日志消息的级别大于logger和handler的级别。

logging.StreamHandler: 日志输出到流,可以是sys.stderr、sys.stdout或者文件
logging.FileHandler: 日志输出到文件

日志回滚方式,实际使用时用RotatingFileHandler和TimedRotatingFileHandler
logging.handlers.BaseRotatingHandler
logging.handlers.RotatingFileHandler
logging.handlers.TimedRotatingFileHandler

logging.handlers.SocketHandler: 远程输出日志到TCP/IP sockets
logging.handlers.DatagramHandler:  远程输出日志到UDP sockets
logging.handlers.SMTPHandler:  远程输出日志到邮件地址
logging.handlers.SysLogHandler: 日志输出到syslog
logging.handlers.NTEventLogHandler: 远程输出日志到Windows NT/2000/XP的事件日志
logging.handlers.MemoryHandler: 日志输出到内存中的制定buffer
logging.handlers.HTTPHandler: 通过"GET"或"POST"远程输出到HTTP服务器

import logging
import sys # 获取logger实例,如果参数为空则返回root logger
logger = logging.getLogger("AppName") # 指定logger输出格式
formatter = logging.Formatter(‘%(asctime)s %(levelname)-8s: %(message)s‘) # 文件日志
file_handler = logging.FileHandler("test.log")
file_handler.setFormatter(formatter) # 可以通过setFormatter指定输出格式 # 控制台日志
console_handler = logging.StreamHandler(sys.stdout)
console_handler.formatter = formatter # 也可以直接给formatter赋值 # 为logger添加的日志处理器,可以自定义日志处理器让其输出到其他地方
logger.addHandler(file_handler)
logger.addHandler(console_handler) # 指定日志的最低输出级别,默认为WARN级别
logger.setLevel(logging.INFO) # 输出不同级别的log
logger.debug(‘this is debug info‘)
logger.info(‘this is information‘)
logger.warn(‘this is warning message‘)
logger.error(‘this is error message‘)
logger.fatal(‘this is fatal message, it is same as logger.critical‘)
logger.critical(‘this is critical message‘) # 2016-10-08 21:59:19,493 INFO : this is information
# 2016-10-08 21:59:19,493 WARNING : this is warning message
# 2016-10-08 21:59:19,493 ERROR : this is error message
# 2016-10-08 21:59:19,493 CRITICAL: this is fatal message, it is same as logger.critical
# 2016-10-08 21:59:19,493 CRITICAL: this is critical message # 移除一些日志处理器
logger.removeHandler(file_handler) python:logging模块

10 DECEMBER 2015 概述

python的logging模块(logging是线程安全的)给应用程序提供了标准的日志信息输出接口。logging不仅支持把日志输出到文件,还支持把日志输出到TCP/UDP服务器,EMAIL服务器,HTTP服务器,UNIX的syslog系统等。在logging中主要有四个概念:logger、handler、filter和formatter,下面会分别介绍。 logger

Logger对象扮演了三重角色: 它给应用程序暴漏了几个方法,以便应用程序能在运行时记录日志。 Logger对象根据日志的级别或根据Filter对象,来决定记录哪些日志。 Logger对象负责把日志信息传递给相关的handler。

在Logger对象中,最常使用的方法分为两类:configuration,message sending。  configuration方法包括:

setLevel(level)

setLevel(level)方法用来设置logger的日志级别,如果日志的级别低于setLevel(level)方法设置的值,那么logger不会处理它。logging模块内建的日志级别有: CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0  (数值越大级别越高) addFilter(filter) removeFilter(filter) addHandler(handler) removeHandler(handler)

message sending方法包括: debug(log_message, [*args[, **kwargs]])  使用DEBUG级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) info(log_message, [*args[, **kwargs]]) 使用INFO级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.info("Houston, we have a %s", "interesting problem", exc_info=1) warning(log_message, [*args[, **kwargs]]) 使用WARNING级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) error(log_message, [*args[, **kwargs]]) 使用Error级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.error("Houston, we have a %s", "major problem", exc_info=1) critical(log_message, [*args[, **kwargs]]) 使用CRITICAL级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.critical("Houston, we have a %s", "major disaster", exc_info=1) exception(message[, *args])  self.error(*((msg,) + args), **{‘exc_info‘: 1}) log(log_level, log_message, [*args[, **kwargs]]) 使用整型的级别level,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.log(level, "We have a %s", "mysterious problem", exc_info=1)

logging.getLogger([name])方法返回一个Logger实例的引用,如果提供了name参数,那么它就是这个Logger实例的名称,如果没提供name参数,那么这个Logger实例的名称是root。可以通过Logger实例的name属性,来查看Logger实例的名称。Logger实例的名称是使用句号(.)分隔的多级结构。在这种命名方式中,后面的logger是前面的logger的子(父子logger只是简单的通过命名来识别),比如:有一个名称为foo的logger,那么诸如foo.bar、foo.bar.baz和foo.bam这样的logger都是foo这个logger的子logger。子logger会自动继承父logger的定义和配置。  使用相同的名称多次调用logging.getLogger([name])方法,会返回同一个logger对象的引用。这个规则不仅仅在同一个module有效,而且对在同一个Python解释器进程的多个module也有效。因此应用程序可以在一个module中定义一个父logger,然后在其他module中继承这个logger,而不必把所有的logger都配置一遍。 handler

handler实例负责把日志事件分发到具体的目的地。logger对象可以使用addHandler()方法,添加零个或多个handler对象到它自身。一个常见的场景是:应用程序可能希望把所有的日志都记录到一个log文件,所有的ERROR及以上级别的日志都记录到stdout,所有的CRITICAL级别的日志都发送到一个email地址。这个场景需要三个独立的handler,每个handler负责把特定级别的日志发送到特定的地方。

下面是logging模块内置的handler: StreamHandler FileHandler RotatingFileHandler TimedRotatingFileHandler SocketHandler DatagramHandler SysLogHandler NTEventLogHandler SMTPHandler MemoryHandler HTTPHandler

内置的handler提供了下面的配置方法: setLevel(level)  handler对象的setLevel()方法,与logger对象的setLevel()方法一样,也是用于设置一个日志级别,如果日志的级别低于setLevel()方法设置的值,那么handler不会处理它。 setFormatter(formatter) addFilter(filter) removeFilter(filter)

应用程序代码不应该直接实例化和使用handler。logging.Handler是一个定义了所有的handler都应该实现的接口和建立了子类能够使用(或重写)的一些默认行为的基类。

自定义Handler  自定义的handler必须继承自logging.Handler,且实现下面的方法:

class Handler(Filterer):
def emit(self, record):
"""
Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so
raises a NotImplementedError.
"""
raise NotImplementedError, ‘emit must be implemented ‘ ‘by Handler subclasses‘ def flush(self):
"""
Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by
subclasses.
"""
pass def close(self):
"""
Tidy up any resources used by the handler. This version does removes the handler from an internal list
of handlers which is closed when shutdown() is called. Subclasses
should ensure that this gets called from overridden close()
methods.
"""
#get the module data lock, as we‘re updating a shared structure.
_acquireLock()
try: #unlikely to raise an exception, but you never know...
if self in _handlers:
del _handlers[self]
if self in _handlerList:
_handlerList.remove(self)
finally:
_releaseLock()

其中,emit(record)方法负责执行真正地记录日志所需的一切事情,在logging.Handler的子类中必须实现这个方法。close()方法负责清理handler所使用的资源(在Python解释器退出的时候,会调用所有的handler的flush()和close()方法),logging.Handler的子类应该确保在重写close()方法的时候,调用父类的该方法。

下面分析logging.StreamHandler的源代码:

class StreamHandler(Handler):
def __init__(self, strm=None):
Handler.__init__(self)
if strm is None:
strm = sys.stderr
self.stream = strm def flush(self):
if self.stream and hasattr(self.stream, "flush"):
self.stream.flush() def emit(self, record):
try:
msg = self.format(record)
stream = self.stream
fs = "%s\n"
if not hasattr(types, "UnicodeType"): #if no unicode support...
stream.write(fs % msg)
else:
try:
if (isinstance(msg, unicode) and
getattr(stream, ‘encoding‘, None)):
fs = fs.decode(stream.encoding)
try:
stream.write(fs % msg)
except UnicodeEncodeError:
#Printing to terminals sometimes fails. For example,
#with an encoding of ‘cp1251‘, the above write will
#work if written to a stream opened or wrapped by
#the codecs module, but fail when writing to a
#terminal even when the codepage is set to cp1251.
#An extra encoding step seems to be needed.
stream.write((fs % msg).encode(stream.encoding))
else:
stream.write(fs % msg)
except UnicodeError:
stream.write(fs % msg.encode("UTF-8"))
self.flush()
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)

在构造函数中,如果提供了strm参数,那么它就是要输出到的流,如果没提供,那么就会将日志输出到标准错误输出流sys.stderr。 
flush()方法的作用是:刷新self.stream内部的I/O缓冲区。每次emit日志之后都会调用这个方法,将日志从I/O缓冲区sync到

以上是python中的logger模块详细讲解的全部内容,在云栖社区的博客、问答、云栖号、人物、课程等栏目也有python中的logger模块详细讲解的相关内容,欢迎继续使用右上角搜索按钮进行搜索date
, 第三方
, 关键字
, uri
, 地址
, 日志记录
, 资源
, __init__
TDE
,以便于您获取更多的相关知识。

logger

Logger对象扮演了三重角色:

它给应用程序暴漏了几个方法,以便应用程序能在运行时记录日志。
    Logger对象根据日志的级别或根据Filter对象,来决定记录哪些日志。
    Logger对象负责把日志信息传递给相关的handler。

在Logger对象中,最常使用的方法分为两类:configuration,message sending。  configuration方法包括:

setLevel(level)

setLevel(level)方法用来设置logger的日志级别,如果日志的级别低于setLevel(level)方法设置的值,那么logger不会处理它。logging模块内建的日志级别有:
            CRITICAL = 50
            FATAL = CRITICAL
            ERROR = 40
            WARNING = 30
            WARN = WARNING
            INFO = 20
            DEBUG = 10
            NOTSET = 0  (数值越大级别越高)
    addFilter(filter)
    removeFilter(filter)
    addHandler(handler)
    removeHandler(handler)

message sending方法包括:

debug(log_message, [*args[, **kwargs]])
        使用DEBUG级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
    info(log_message, [*args[, **kwargs]])
        使用INFO级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
    warning(log_message, [*args[, **kwargs]])
        使用WARNING级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
    error(log_message, [*args[, **kwargs]])
        使用Error级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.error("Houston, we have a %s", "major problem", exc_info=1)
    critical(log_message, [*args[, **kwargs]])
        使用CRITICAL级别,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
    exception(message[, *args])
        self.error(*((msg,) + args), **{'exc_info': 1})
    log(log_level, log_message, [*args[, **kwargs]])
        使用整型的级别level,记录log_message % args。为了记录异常信息,需要将关键字参数exc_info设置为一个true值。  比如:logger.log(level, "We have a %s", "mysterious problem", exc_info=1)

logging.getLogger([name])方法返回一个Logger实例的引用,如果提供了name参数,那么它就是这个Logger实例的名称,如果没提供name参数,那么这个Logger实例的名称是root。可以通过Logger实例的name属性,来查看Logger实例的名称。Logger实例的名称是使用句号(.)分隔的多级结构。在这种命名方式中,后面的logger是前面的logger的子(父子logger只是简单的通过命名来识别),比如:有一个名称为foo的logger,那么诸如foo.bar、foo.bar.baz和foo.bam这样的logger都是foo这个logger的子logger。子logger会自动继承父logger的定义和配置。  使用相同的名称多次调用logging.getLogger([name])方法,会返回同一个logger对象的引用。这个规则不仅仅在同一个module有效,而且对在同一个Python解释器进程的多个module也有效。因此应用程序可以在一个module中定义一个父logger,然后在其他module中继承这个logger,而不必把所有的logger都配置一遍。
---------------------

python中的logger模块的更多相关文章

  1. python中的logger模块详细讲解

    logger 提供了应用程序可以直接使用的接口handler将(logger创建的)日志记录发送到合适的目的输出filter提供了细度设备来决定输出哪条日志记录formatter决定日志记录的最终输出 ...

  2. Python中的logging模块

    http://python.jobbole.com/86887/ 最近修改了项目里的logging相关功能,用到了python标准库里的logging模块,在此做一些记录.主要是从官方文档和stack ...

  3. python中的shutil模块

    目录 python中的shutil模块 目录和文件操作 归档操作 python中的shutil模块 shutil模块对文件和文件集合提供了许多高级操作,特别是提供了支持文件复制和删除的函数. 目录和文 ...

  4. Python入门之Python中的logging模块

    基本用法 下面的代码展示了logging最基本的用法. import logging import sys # 获取logger实例,如果参数为空则返回root logger logger = log ...

  5. Python 中 logging 日志模块在多进程环境下的使用

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,Python 中 logging 日志模块在多进程环境下的使用 使用 Pytho ...

  6. Python中的logging模块就这么用

    Python中的logging模块就这么用 1.日志日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICALDEBUG:详细的信息,通常只出现在诊断问题 ...

  7. [ Python入门教程 ] Python中日志记录模块logging使用实例

    python中的logging模块用于记录日志.用户可以根据程序实现需要自定义日志输出位置.日志级别以及日志格式. 将日志内容输出到屏幕 一个最简单的logging模块使用样例,直接打印显示日志内容到 ...

  8. Python中的random模块,来自于Capricorn的实验室

    Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...

  9. Python中的random模块

    Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...

随机推荐

  1. mysql报错Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage

    mysql报错Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage 在执行cr ...

  2. 20190316 Python - Pandas

    1. python 安装3.7版本 2. 第三方包进行数据加工和呈现 需要注意的是,你安装过程中会有很多依赖包问题,如果网络异常,那么就使用https://pypi.org/   地址去找对应的包下载 ...

  3. api-gateway-engine知识点(1)

    1     密钥绑定时,通过Channel 实现监控 后台发送数据 :      redisTemplate.convertAndSend(RedisMessageChannel.API_GATEWA ...

  4. JS 8-2 再谈原型

    var bosn = new Student创建了Student的实例bosn.bosn的原型(__proto__)指向构造器Student的prototype属性. Student.prototyp ...

  5. iOS 第三方框架-SDWebImage

    iOS中著名的牛逼的网络图片处理框架.包含的功能:图片下载.图片缓存.下载进度监听.gif处理等等.用法极其简单,功能十分强大,大大提高了网络图片的处理效率.国内超过90%的iOS项目都有它的影子. ...

  6. mac控制台快捷键

    ctrl+a //移到行首ctrl+e //移到行尾 ctrl+y // 插入最近删除的单词或语句ctrl+k //删除光标处到行尾部分ctrl+u //删除光标处到行首部分ctrl+w //删除光标 ...

  7. (已解决) eclipse提示报错"serializing cdt project settings"解决方案

    最近在使用eclipse作为cocos2dx的交叉编译工具.但是某天突然相关工程打不开,打开eclipse直接提示 “serializing cdt project settings” has enc ...

  8. unity3d-游戏实战突出重围,整合游戏

    结构图: 两个场景,一个是开始界面.一个是游戏界面: 脚本说明:依次是:敌人脚本,主角游戏,主菜单,工具 Enemy using UnityEngine; using System.Collectio ...

  9. python爬虫-基础入门-爬取整个网站《3》

    python爬虫-基础入门-爬取整个网站<3> 描述: 前两章粗略的讲述了python2.python3爬取整个网站,这章节简单的记录一下python2.python3的区别 python ...

  10. JavaScript-模拟收银台小程序

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...