python日志模块logging

模块级函数

logging.getlogger([name]):返回一个logger对象,如果没有指定名字将返回root logger

logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical():设定root logger的日志级别

logging.basicconfig():用默认formatter为日志系统建立一个streamhandler,设置基础配置并加到root logger中

logger

logging.getlogger([name])

返回一个logger实例,如果没有指定name,返回root logger。

每个程序在输出信息之前都要获得一个logger。logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的logger:

log=logging.getlogger(”chat.gui”)

而核心模块可以这样:

log=logging.getlogger(”chat.kernel”)

logger.setlevel(logging.warning):指定最低的日志级别,低于warning的级别将被忽略

logger.addfilter(filt)、logger.removefilter(filt):添加或删除指定的filter

logger.addhandler(hdlr)、logger.removehandler(hdlr):增加或删除指定的handler

handlers

handler对象负责发送相关的信息到指定目的地。可以是文件、屏幕、网络、socket等

handler.setlevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略

handler.setformatter():给这个handler选择一个输出格式

handler.addfilter(filt)、handler.removefilter(filt):新增或删除一个filter对象

日志打印到屏幕

import logging
logging.debug(‘this is debug message’)
logging.info(‘this is info message’)
logging.warning(‘this is warning message’)
返回:
warning:root:this is warning message
打印到屏幕

默认情况下,logging将日志打印到屏幕,日志级别为warning;日志级别大小关系为:critical > error > warning > info > debug > notset,当然也可以自己定义日志级别。

格式化日志输出

logging.basicconfig函数各参数:filename: 指定日志文件名filemode: 和file函数意义相同,指定日志文件的打开模式,’w’或’a’format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:

import logging
logging.basicconfig(level=logging.debug,
format=’%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s’,
datefmt=’%a, %d %b %y %h:%m:%s’,
filename=’myapp.log’,
filemode=’w’)
logging.debug(‘this is debug message’)
logging.info(‘this is info message’)
logging.warning(‘this is warning message’)
./myapp.log文件中内容为:
sun, 24 may 2009 21:48:54 demo2.py[line:11] debug this is debug message
sun, 24 may 2009 21:48:54 demo2.py[line:12] info this is info message
sun, 24 may 2009 21:48:54 demo2.py[line:13] warning this is warning message
修改输出格式

日志格式变量

%(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcname)s: 打印日志的当前函数
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(thread)d: 打印线程id
%(threadname)s: 打印线程名称
%(process)d: 打印进程id
%(message)s: 打印日志信息
datefmt: 指定时间格式,同time.strftime()
level: 设置日志级别,默认为logging.warning
stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略
日志格式

logging方法

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服务器
logging方法

由于streamhandler和filehandler是常用的日志处理方式,所以直接包含在logging模块中,而其他方式则包含在logging.handlers模块中

在程序中定义日志模块

import logging
# create logger
def logger(log_type):
logger = logging.getlogger(log_type) # 创建logger对象,类型是’test-log’
logger.setlevel(logging.warning) # 设置最低的日志级别,此级别覆盖ch and fh的级别
# 创建输出到控制台处理程序,并设置级别为debug
ch = logging.streamhandler()
ch.setlevel(logging.debug) # 控制输出到屏幕的级别
# 创建输出到文件的处理程序,并设置级别
fh = logging.filehandler(“access.log”)
fh.setlevel(logging.warning)
# 创建日志格式
formatter_stream = logging.formatter(‘%(name)s – %(levelname)s – %(message)s’)
formatter_file = logging.formatter(‘%(asctime)s – %(name)s – %(levelname)s – %(message)s’)
# add formatter to ch and fh
ch.setformatter(formatter_stream)
fh.setformatter(formatter_file)
# add ch and fh to logger
logger.addhandler(ch)
logger.addhandler(fh)
return logger
eee = logger(‘eee’)
rrr = logger(‘rrr’)
rrr.debug(‘debug message’)
rrr.info(‘info message’)
rrr.warning(‘warn message’)
eee.error(‘error message’)
eee.critical(‘critical message’)
代码

屏幕显示内容

rrr – info – info message

rrr – warning – warn message

eee – error – error message

eee – critical – critical message

文件中内容

2017-02-21 21:35:05,700 – rrr – warning – warn message

2017-02-21 21:35:05,700 – eee – error – error message

2017-02-21 21:35:05,700 – eee – critical – critical message

过滤器

调用logging.getlogger()时参数的格式类似于“a.b.c”。采取这样的格式就是为了配置过滤器。添加过滤器后日志会经过过滤器处理后才输出

过滤器”aaa.bbb”只让名字以”aaa.bbb”开头的logger输出信息

可以添加多个过滤器,只要有一个过滤器拒绝,日志就不会输出

import logging
def logger(log_type):
logger = logging.getlogger(log_type) # 创建logger对象,类型是’test-log’
logger.setlevel(logging.debug) # 此级别覆盖ch and fh的级别
# 创建输出到控制台处理程序,并设置级别为debug
ch = logging.streamhandler()
ch.setlevel(logging.debug) # 控制输出到屏幕的级别
# 设置过滤器
filter = logging.filter(‘aaa.bbb.ccc’)
ch.addfilter(filter)
formatter_stream = logging.formatter(‘%(name)s – %(levelname)s – %(message)s’)
ch.setformatter(formatter_stream)
logger.addhandler(ch) # ch加入logger
return logger
eee = logger(‘aaa.bbb.ccc’)
rrr = logger(‘aaa.bbb.ddd’)
rrr.error(‘debug message’)
rrr.error(‘info message’)
eee.error(‘critical message’)
eee.error(‘critical message’)
代码

切割日志

按大小切割

import logging
from logging import handlers
# create logger
def logger(log_type):
logger = logging.getlogger(log_type)
logger.setlevel(logging.debug)
fh = logging.filehandler(“access.log”)
fh.setlevel(logging.warning)
# 按时间切割日志文件
fh = handlers.timedrotatingfilehandler(filename=’access.log’, when=’s’, interval=10 )
formatter_file = logging.formatter(‘%(asctime)s – %(name)s – %(levelname)s – %(message)s’)
fh.setformatter(formatter_file)
logger.addhandler(fh)
return logger
rrr = logger(‘aaa.bbb.ddd’)
rrr.error(‘debug message’)
rrr.error(‘info message’)
rrr.error(‘warn message’)
代码

interval:时间间隔

when: 时间单位 s 秒 m 分 h 小时 d 天 w 每星期(interval==0时代表星期一) midnight 每天凌晨

关于root logger以及logger的父子关系

前面多次提到root logger, 实际上logger实例之间还有父子关系, root logger就是处于最顶层的logger, 它是所有logger的祖先。如下图:root logger是默认的logger如果不创建logger实例, 直接调用logging.debug()、logging.info()logging.warning()、logging.error()、logging.critical()这些函数,那么使用的logger就是 root logger, 它可以自动创建,也是单实例的。

什么是effective levellogger有一个概念,叫effective level。 如果一个logger没有显示地设置level,那么它就用父亲的level。如果父亲也没有显示地设置level, 就用父亲的父亲的level,以此推….最后到达root logger,一定设置过level。默认为logging.warningchild loggers得到消息后,既把消息分发给它的handler处理,也会传递给所有祖先logger处理

更多python日志模块 logging 相关文章请关注php中文网!

Posted in 未分类

发表评论