Python logging模块

默认logging函数输出的warning级别的日志。

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

import logging
logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

日志级别

日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET

logging库提供了多个组件:Logger、Handler、Filter、Formatter:

Logger      对象提供应用程序可直接使用的接口,供应用代码使用;
Handler     发送日志到适当的目的地,比如socket和文件等
Filter      提供了过滤日志信息的方法,控制输出;
Formatter  指定日志输出和显示的具体格式。

 

通过logging.basicConfig对日志的输出格式配置

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

import logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%Y-%m-%d  %H:%M:%S',
                    filename='test.log',
                    filemode='w')


logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

cat test.log

2019-07-22  15:31:50 loggin-module.py[line:12] DEBUG This is debug message
2019-07-22  15:31:50 loggin-module.py[line:13] INFO This is info message
2019-07-22  15:31:50 loggin-module.py[line:14] WARNING This is warning message

 

需要注意的是
只有等级大于等于basicConfig定义的level的log才会被输出,比如这里定义的等级为DEBUG、debug、info、warning、error日志等级都大于等于debug

logging.basicConfig各参数
level:日志等级
format格式

format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:
 %(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: 打印日志信息
 filename:输出文件名
filemode:写入模式w为直接写入,a为追加
datafmt:输出的时间格式  这里用%Y-
python中时间日期格式化符号:
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称

 

将日志同时输出到屏幕和文件

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

import logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%Y-%m-%d  %H:%M:%S',
                    filename='test.log',
                    filemode='w')

#设置 一个streamaHandler用于将大于等于INFO级别的日志打到屏幕上
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)


logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

logging 日志轮询

使用TimedRotatingFileHandler设置日志轮转,轮转的方式有两种一种是基于时间的轮转,一种是基于日志文件大小的轮转
TimedRotatingFileHandler函数参数说明

logging.handlers.TimedRotatingFileHandler(file_name,when=时间单位, interval='时间间隔',backupCount="保留的文件个数")

 

interval:表示等待多长时间文件重建,重建的文件名等于file_name+suffix

以下面例子说明

 

 

myadd.addHandler(filehandler)的意思是给myapp这个logger添加filehandler这个handler。

执行脚本可以看见每隔一秒会自动生成一个新的日志文件,到满3个时会自动进行一次新的轮转

 

TimedRotatingFileHandler设置的重建时间间隔后,suffix就需要按装下面的进行配置不然删除不了,比如设置的为S则suffix为%Y-%m-%d_%H-%M-%S

 

RotatingFileHandler按文件大小切分

 

logger实例的父子关系

通过前面几个例子对比你应该发现了前面我用logging.basicConfig()去设置format,后面我是通过getlogger创建一个logger后,通过setformat方法去给他对应的handler设置format。

root logger是处于最顶层的logger,同时也是默认的logger,如果不创建logger实例默认调用logger.info(),logger.debug(),logger.error()使用

如何得到root logger
通过logging.getLogger()和logging.getLogger(“”)得到root logger实例。

logger的父子关系
logger以name命名方式来表达父子关系
比如

logging.getLogger(foo)

logging.getLogger(foo.tar)

 

 

effective level

一个looger如果没有指定level,就继承父level,如果父logger也没有就直接继承root的level。
handler同样,子没有就继承父的,父也没有的话就继承root的

root logger这里没设置logger的setLevel默认是warning,但父logger设置了,所以父logger会将自己的logger setlevel传递给root logger

 

 

调用配置好的logging

正常写程序中只要配置好一个logging,其他程序只要调用他就可以了一种是通过logging.config,一种是通过模块导入

介绍方法二:
比如我将配置好的logging写在test.py里面

 

在另外一个程序中调用它

import test
test.myapp.info("test")

 

这样输出的就是按test.py里面myapp这个logger配置好的log了

发表评论