python logging - 高级

参考:

Advanced logging tutorial:https://docs.python.org/2.7/howto/logging.html#advanced-logging-tutorial

15.7. logging - Logging facility for Python:https://docs.python.org/2.7/library/logging.html?highlight=logging#module-logging

15.8. logging.config - Logging configuration:https://docs.python.org/2.7/library/logging.config.html

15.9. logging.handlers - Logging handlers:https://docs.python.org/2.7/library/logging.handlers.html

####################################################################

对于python的logging模块不了解的可以先查看文章:

python logging - 初级:http://blog.csdn.net/u012005313/article/details/51581442

logging模块有4个最关键的组件:Logging,Handler,Filter和Formatter

官方给出解释如下:

  • Loggers expose the interface that application code directly uses.
  • Handlers send the log records (created by loggers) to the appropriate destination.
  • Filters provide a finer grained facility for determining which log records to output.
  • Formatters specify the layout of log records in the final output.

使用logging模块时,首先需要得到一个Logger类的实例,称为记录器(logger)。每个记录器都有一个名字,并且logging模块是通过名字来管理这些记录器的,两个记录器之间可以通过命名空间的层次结构来确定关系(Each instance has a name, and they are conceptually arranged in a namespace hierarchy using dots (periods) as separators)。比如,名字为‘one‘的记录器就是名字为‘one.two‘,‘one.three‘,‘one.four‘的记录器的父辈,也就是说,使用点号(‘.’)来确定父子的关系。记录器的名字命名没有任何要求,你可以选择你喜欢的,但最好名字能够表明该记录器在程序中的作用。

可以使用getLogger函数来获取记录器,常用的是命名为模块名或文件名:

logger = logging.getLogger(__name__)

所有记录器(logger)的父辈是root记录器,它的名字就是“root”。

默认情况下,信息会被输出到控制台,默认的输出格式是logging.BASIC_FORMAT:

severity:logger name:message

这些可以通过函数basicConfig进行修改:

basicConfig(**kwargs)

函数功能:为整个日志系统进行基础配置(Do basic configuration for the logging system)

如果root记录器已经有处理器(handler)配置(关于处理器将在下文讲解),那么函数basicConfig将不会起作用。

可以使用以下的关键字参数:

如果在多线程中使用baskcConfig函数,那么该函数必须在主线程中使用。

####################################################

其流程图如下:

###################################################################33

下面讲解Logger,Handler以及Formatter的使用

Logger

记录器有三部分的功能:

1.它提供了一些方法(debug(),info(),warning(),error(),critical()等),供开发者使用

2.记录器依据自身等级或过滤器(filter)来判断是否生成信息(message)

3.记录器将信息发送到所有绑定到自身的处理器(handler)

记录器上最常用的方法可以分为两个部分:配置和信息发送

以下是最常用的配置方法:

1.Logger.setLevel():指定记录器能够处理信息的最低等级(he lowest-severity)。logging模块中,debug是最低的等级,critical是最高的等级。比如,设置记录器等级为INFO,那么该记录器能够处理INFO,WARNING,ERROR,CRITICAL的信息,而会忽略DEBUG等级的信息。

2.Logger.addHandler()和Logger.removeHandler():绑定处理器(handler)到指定的记录器上,以及解除绑定

3.Logger.addFilter()和Logger.removeFilter():绑定过滤器(filter)到指定的过滤器上,以及解除绑定

当记录器配置解除后,以下方法可以处理日志信息:

Logger.debug(),Logger.info(),Logger.warning(),Logger.error()和Logger.critical()函数:用于处理信息,同时设定了该信息的等级(level or severity),以便于记录器判断是否处理该信息

getLogger函数返回一个记录器实例的引用,多次使用该函数去引用相同名字的记录器实例将返回同一个记录器。

每个记录器都必须设定一个等级(level or severity)。但如果没有显式设定,那么会根据它的父辈的等级来进行设定;如果父辈也没有显式设定,那么继续查找父辈的父辈,依次类推-查找所有的父辈直到找到一个显式设置的等级。root记录器是所有记录器的父辈,它的等级默认为WARNING。

logging模块使用层次命名空间来管理所有记录器,从而设置了一个很好的方法。子记录器将会把信息传送给绑定在父记录器上的处理器(handler),因此,不需要为所有记录器配置处理器,只需要在父记录器上绑定处理器,那么子记录器的消息就能够通过该处理器进行处理(可以通过设置记录器的propagate属性为False来关闭向上传播,默认为True)。

################################################

Handler

处理器负责将信息发送到指定的地点。记录器可以绑定0个或者多个处理器(通过addHandler方法)。比如,我们需要将程序中的所有日志信息都保存在文件中,将等级在error及以上的信息发送到控制台,将所有的critical等级的信息都发送到email,那么,我们仅需定义3个不同的处理器,在处理器上指定这3个目的地即可。

通常我们并不直接使用Handler实例,而是引用它的子类。Handler作为一个基类定义了一些基本的函数,子类扩展另外的功能。常用的Handler子类有StreamHandlerFileHandler,另外,我们还会提到RotatingFileHandler详细的Handler子类)。

我们对Handler的使用的方法不多。常用在配置阶段:

1.setLevel:指定处理器能够处理的最低等级

2.setFormatter:绑定一个Formatter到处理器

3.addFilter和removeFilter

下面介绍常用的Handler子类:

class logging.StreamHandler(stream=None)

输出日志信息到控制台

class logging.FileHandler(filename, mode='a', encoding=None, delay=False)

输出日志信息到文件。常用的文件打开方式为添加信息。

class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0)

输出日志信息到文件。需要设置文件所占的最大字节数(maxBytes)以及文件备份数(backupCount)。当前输入文件总是filename文件,比如,filename是‘he.log‘,那么当该文件所占字节达到最大时,将he.log文件保存为he.log.1文件,如果已存在he.log.1文件,那么将其保存为he.log.2文件,依次类推,直到达到文件备份数为止,比如,backupCount=5,那么如果已存在he.log.5文件,则将其删除。

如果所有记录器(logger)均没有绑定处理器(handler),那么root记录器会默认生成一个输出到控制台的handler。

#################################3

Formatter

Formatter对象配置最终的日志的结构,顺序以及内容。它有两个可选参数:

logging.Formatter.__init__(fmt=None, datefmt=None)

默认的fmt格式是使用原始信息。默认的时间格式为:

%Y-%m-%d %H:%M:%S

#################################3

在设置等级(level or severity)时可以使用数字。logging模块内置了一些常数,如下表所示:

#################################

下面介绍logging的一些用法:

1.在多个线程中使用logging模块

logging模块是线程安全的,所以可以在多个线程中共同使用同一个logging实例。但是logging模块并不是进程安全的,在多个进程中使用可能会出现问题。

2.在多个模块中使用logging

module_a.py:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import logging
import module_b

# 创建logger实例
logger = logging.getLogger('module_a')
logger.setLevel(logging.DEBUG)

# 创建流处理器
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)

# 创建Formatter
formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')

# Formatter绑定在Handler上
sh.setFormatter(formatter)
# Handler绑定在logger上
logger.addHandler(sh)

logger.debug("this is debug")
logger.info("this is info")
module_b.hello()
logger.warn("this is warn")
logger.error("this is error")
modu = module_b.Clas()
modu.hi()
logger.critical("this is critical")

module_b.py:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import logging

# create logger
logg = logging.getLogger('module_a.module_b')
logg.setLevel(logging.DEBUG)

class Clas:
	def __init__(self):
		logg.info("class: Clas")

	def hi(self):
		logg.debug("Clas -> hi")

def hello():
	logg.error("hello world")

结果:

如上图所示,子记录器(‘module_a.module_b‘)可以不用自己设置处理器,而调用父记录器绑定的处理器即可

修改如下可以使得结果更加直观易懂:

# 创建Formatter
formatter = logging.Formatter('%(asctime)s-%(name)20s-%(levelname)8s-%(message)s')

或者:

# 创建Formatter
formatter = logging.Formatter('%(asctime)s-%(name)-20s-%(levelname)-8s-%(message)s')

3.使用多个处理器和formatter

multiple_handlers_and_formatters.py:

绑定两个处理器,一个处理器将所有信息输出到控制台窗口,其信息格式为:

'%(asctime)s %(name)-6s: %(levelname)-8s: %(message)s'

另一个处理器将error等级及以上的信息输出到文件logging2.log,其信息格式为:

'%(levelname)-8s-%(message)s'
#!/usr/bin/env python
#-*- coding: utf-8 -*-

import logging

# create logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# set StreamHandler
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)

# set Formatter
formatter1 = logging.Formatter('%(asctime)s %(name)-6s: %(levelname)-8s: %(message)s')
sh.setFormatter(formatter1)

# set FileHandler
fh = logging.FileHandler("multi.log")
fh.setLevel(logging.ERROR)

# set Formatter
formatter2 = logging.Formatter('%(levelname)-8s-%(message)s')
fh.setFormatter(formatter2)

# add handlers to logger
logger.addHandler(sh)
logger.addHandler(fh)

# logging
logger.debug('debug message')
logger.info('info message')
logger.warn('warnning message')
logger.error('error message')
logger.critical('critical message')

结果:

控制台窗口:

multi.log:

ERROR   -error message
CRITICAL-critical message

还有一种更简便的方法,就是使用basicConfig函数:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)-6s: %(levelname)-8s: %(message)s')

# create logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# set FileHandler
fh = logging.FileHandler("multi.log")
fh.setLevel(logging.ERROR)

# set Formatter
formatter = logging.Formatter('%(levelname)-8s-%(message)s')
fh.setFormatter(formatter)

# add handlers to logger
logger.addHandler(fh)

# logging
logger.debug('debug message')
logger.info('info message')
logger.warn('warnning message')
logger.error('error message')
logger.critical('critical message')

能够达到同样的效果

4.使用FileRotationHandler处理器

代码如下:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import glob
import logging
import logging.handlers

LOG_FILENAME = 'rotation/logging_rotatingfile_example.out'

# set up a specific logger with our desired output level
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)

# add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, maxBytes=20, backupCount=5)

my_logger.addHandler(handler)

# log some messages
for i in range(20):
	my_logger.debug('i = %d'%i)

# see what files are created
logfiles = glob.glob('%s*'%LOG_FILENAME)

for filename in logfiles:
	print filename

在这里设置单个文件的最大容量为20字节,设置5个备份文件(所以共有6个文件)

rotation文件夹内:

时间: 2024-11-17 02:35:26

python logging - 高级的相关文章

python logging—模块

python logging模块 python logging提供了标准的日志接口,python logging日志分为5个等级: debug(), info(), warning(), error() and critical() 简单用法 import logging logging.warning("warning.........") logging.critical("server is down") print: WARNING:root:warning

Python字典高级使用方法汇总

Python字典高级使用方法汇总 字典(dictionary)是python中的一种非常灵活和强大的数据结构,可以完成很多操作.本文总结了一些除了基本的初始化.赋值.取值之外的常用的字典使用方法. 字典基础参考: [1]:http://www.w3cschool.cc/python/python-dictionary.html [2]:http://www.111cn.net/phper/python/56355.htm [3]:http://skyfen.iteye.com/blog/5675

进击的Python【第五章】:Python的高级应用(二)常用模块

Python的高级应用(二)常用模块学习 本章学习要点: Python模块的定义 time &datetime模块 random模块 os模块 sys模块 shutil模块 ConfigParser模块 shelve模块 xml处理 re正则表达式 一.Python模块的定义 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt这个函数,必须用语句"#include<math.h>"引入math.h这个头文件,否则是无法正常进行调用的.那么在Python中,如

进击的Python【第四章】:Python的高级应用(一)

Python的高级应用(一) 本章内容: 内置函数 生成器 迭代器 装饰器 JSON和PICKLE的简单用法 软件目录结构规范 一.内置函数 1.数学运算类 abs(x) 求绝对值1.参数可以是整型,也可以是复数2.若参数是复数,则返回复数的模 complex([real[, imag]]) 创建一个复数 divmod(a, b) 分别取商和余数注意:整型.浮点型都可以 float([x]) 将一个字符串或数转换为浮点数.如果无参数将返回0.0 int([x[, base]])  将一个字符转换

python logging system

官方教程:https://docs.python.org/2/library/logging.html 1.  用法1 import logging import logging.handlers LOG_FILE = 'tst.log' handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes = 1024*1024, backupCount = 5) # 实例化handler fmt = '%(asctime)s -

进击的Python【第七章】:Python的高级应用(四)面向对象编程进阶

Python的高级应用(三)面向对象编程进阶 本章学习要点: 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 一.面向对象高级语法部分 静态方法 要在类中使用静态方法,需在类成员函数前面加上@staticmethod标记符,以表示下面的成员函数是静态函数.使用静态方法的好处是,不需要定义实例即可使用这个方法.另外,多个实例共享此静态方法. 类方法 类方法与普通的成员函数和静态函数有不同之处,在接触的语言中好像也没见过这种语义,看它的定义: 

Python logging模块实例教程

position:static(静态定位) 当position属性定义为static时,可以将元素定义为静态位置,所谓静态位置就是各个元素在HTML文档流中应有的位置 podisition定位问题.所以当没有定义position属性时,并不说明该元素没有自己的位置,它会遵循默认显示为静态位置,在静态定位状态下无法通过坐标值(top,left,right,bottom)来改变它的位置. position:absolute(绝对定位) 当position属性定义为absolute时,元素会脱离文档流

python logging模块使用

近来再弄一个小项目,已经到收尾阶段了.希望加入写log机制来增加程序出错后的判断分析.尝试使用了python logging模块. #-*- coding:utf-8 -*- import logging import sys class LogRecord(object): def __init__(self): self.mylogger = logging.getLogger('iplog') self.mylogger.setLevel(logging.WARNING) #创建一个han

python logging模块可能会令人困惑的地方

python logging模块主要是python提供的通用日志系统,使用的方法其实挺简单的,这块就不多介绍.下面主要会讲到在使用python logging模块的时候,涉及到多个python文件的调用,而每个文件设置了对应的logging方式不同,可能会产生的令人困惑的现象. 下面以自己在开发的时候遇到的问题作为叙述的背景: 有三个python模块A.B.C.主模块A会import B和C模块,主模块有对应的logging方式, A使用logging的模块的方式为: import loggin