logging

1. 定义

Python的logging模块提供了通用的日志系统,可以方便第三方模块或者应用使用。这个模块提供不同的日志级别,并可以采用不同的方式记录日志。

Java中的日志模块是Log4j,python的logging模块和它类似。

2. 组成

logging主要由三个部分组成:logger、handle、formatter

  • logger用来获取日志对象
  • handler用来设置日志输出的方向
  • formatter用来设置日志内容的格式

logger:

logger=logging.getLogger('name')

handler:

handler1=logging.FileHandler('log path')   #输出到日志文件

handler2=logging.StreamHandler(sys.stderr)   #输出到控制台

formatter:

formatter=logging.Formatter('%(asctime)s...')

定义完三个主要组成部分后,需要关联这三个部分:

handler1.setFormatter(formatter)   #把handle和formatter绑定在一起
logger.addHandle(handler1)   #logger和handle绑定在一起

3.细节

3.1 logger

logging.getLogger(),是一个顶级父对象,没有指定name时返回root looger

logging.getLogger('a'),是顶级父对象的子对象

logging.getLogger('a.b'),是a对象的子对象

设置basicConfig

logging.basicConfig(path,level,filemode,format)   #把handler配置好了,日志级别设置好了,输出格式配置好了

logging.basicConfig(filename=os.path.join(os.getcwd(),'log.txt'),level=logging.WARN,filemode='w',format='%(asctime)s-%(levelname)s:%(message)s')

 

3.2 handler

logging模块常用三个handler:

logging.StreamHandler(stream=None)  #日志信息会输出到指定的stream中,如果stream为空则默认输出到sys.stderr,也可设置sys.__stdout__
logging.FileHandler(filename, mode='a', encoding=None, delay=False)  #默认情况下,日志文件可以无限增大
logging.NullHandler   #空操作

logging其他的handler:

logging.handlers.WatchedFileHandler(filename, mode='a', encoding=None, delay=False)
用于监视文件的状态,如果文件被改变了,那么就关闭当前流,重新打开文件,创建一个新的流。这个handler是专门为linux/unix系统设计的,因为在windows系统下,正在被打开的文件是不会被改变的
logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0)
参数maxBytes和backupCount允许日志文件在达到maxBytes时rollover.当文件大小达到或者超过maxBytes时,就会新创建一个日志文件。backupcount是备份数目,也就是最多能有多少个备份
logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False)
定时循环日志handler,位于logging.handlers,支持定时生成新日志文件。参数when决定了时间间隔的类型,参数interval决定了多少的时间间隔。如when=‘D’,interval=2,就是指两天的时间间隔,backupCount决定了能留几个日志文件。超过数量就会丢弃掉老的日志文件
'S'         |  秒

 'M'         |  分

 'H'         |  时

 'D'         |  天

 'W0'-'W6'   |  周一至周日

 'midnight'  |  每天的凌晨
其他handler具体参加官方文档其他handlers

3.3 formatter

用于设置日志信息的规则、结构、内容,默认的时间格式为%Y-%m-%d %H:%M:%S

%(name)s

Logger的名字

%(levelno)s

数字形式的日志级别

%(levelname)s

文本形式的日志级别

%(pathname)s

调用日志输出函数的模块的完整路径名,可能没有

%(filename)s

调用日志输出函数的模块的文件名

%(module)s

调用日志输出函数的模块名

%(funcName)s

调用日志输出函数的函数名

%(lineno)d

调用日志输出函数的语句所在的代码行

%(created)f

当前时间,用UNIX标准的表示时间的浮 点数表示

%(relativeCreated)d

输出日志信息时的,自Logger创建以 来的毫秒数

%(asctime)s

字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

%(thread)d

线程ID。可能没有

%(threadName)s

线程名。可能没有

%(process)d

进程ID。可能没有

%(message)s

用户输出的消息

 

一般格式   '%(asctime)s-%(name)s-%(levelname)s-%(message)s'

3.4 设置日志级别

logger和handler在设置日志级别之前都有默认的日志级别,logging.getLogger()默认的level是logging.WARNING,低于该级别的就不输出了,可以修改日志级别

logging.getLogger().level=logging.DEBUG  

logging.getLogger().setLevel(logging.DEBUG)或logging.FileHandler('').setLevel(logging.DEBUG)

logging.NOTSET<logging.DEBUG<logging.INFO<logging.WARNING<logging.Error<logging.CRITICAL

对应数字  0<10<20<30<40<50

 

3.5 输出日志级别

输出日志

logging.getLogger().info('输出内容')

logging.getLogger().debug('')

logging.getLogger().warning('')

logging.getLogger().error('')

logging.getLogger().notset('')

4. 例子 

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')

 

运行后,再控制台和日志文件都有一条日志:

2011-08-31 19:18:29,816-mylogger-INFO-foorbar

-----------------------------------------------------------------------------------------------------

例子1:

import logging

logging.error('xxx')

这种是用python默认的logger名字为root的日志,输出到日志中的形式是ERROR:root:xxx  。

默认设置为   logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

例子2:

import logging

logger=logging.getLogger('define')

file_handler=logging.FileHandler(os.path.join(os.path.dirname(__file__),'auto.log'))
logger.addHandler(file_handler)
logger.setLevel(logging.DEBUG)                 #logger作为‘母’设置了日志等级
console=logging.StreamHandler()
console.setLevel(logging.DEBUG)              #console作为‘子’设置比logger等级更高的level,不设置则继承‘母’的日志等级
formatter=logging.Formatter('%(message)s')    #设置‘母’的输出格式
console.setFormatter(formatter)
logger.addHandler(console)
logger.info('this is a logger info')
logger.debug('this is a logger debug')
logger.error('this is a logger error')

filehandler和consolehandler都遵从logging的设置

例子2:

其他py文件若想跟主py文件输出的日志放到一个文件中,则需要在次py文件中获取主py文件定义的logger,logger=logging.getLogger('define')

 

posted @ 2017-11-23 11:08  eudaemonia  阅读(456)  评论(0编辑  收藏  举报