参考 python logging 的官方文档:
https://docs.python.org/2/library/logging.html
日志是用来记录程序在运行过程中发生的状况,在程序开发过程中添加日志模块能够帮助我们了解程序运行过程中发生了哪些事件,这些事件也有轻重之分。
根据事件的轻重可分为以下几个级别:
DEBUG: 详细信息,通常仅在诊断问题时才受到关注
INFO: 确认程序按预期工作
WARNING:出现了异常,但是不影响正常工作
ERROR:由于某些原因,程序 不能执行某些功能
CRITICAL:严重的错误,导致程序不能运行
日志级别 debug < info < warning < error < critical
默认的级别是WARNING,也就意味着只有级别大于等于的才会被看到,跟踪日志的方式可以是写入到文件中,也可以直接输出到控制台。
4个主要的组件
- logger: 日志类,应用程序往往通过调用它提供的api来记录日志;
- handler: 对日志信息处理,可以将日志发送(保存)到不同的目标域中;
- filter: 对日志信息进行过滤;
- formatter:日志的格式化;
输出到控制台
import logging
logging.warning('Watch out!') # 将输出到控制台
logging.info('I told you so') # 不会输出
logging.error("an error occurrence!") #将输出到控制台
输出结果:
输出到文件中
logging.basicConfig([**kwargs]) 模块
为日志模块配置基本信息。kwargs 支持如下几个关键字参数:
- filename :日志文件的保存路径。如果配置了些参数,将自动创建一个FileHandler作为Handler;
- filemode :日志文件的打开模式。 默认值为'a',表示日志消息以追加的形式添加到日志文件中。如果设为'w', 那么每次程序启动的时候都会创建一个新的日志文件;
- format :设置日志输出格式;
- datefmt :定义日期格式;
- level :设置日志的级别.对低于该级别的日志消息将被忽略;
- stream :设置特定的流用于初始化StreamHandler;
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',
filename='a.log',
filemode='a'
)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
handlers.TimedRotatingFileHandler() 能按照时间自动分割日志文件(自动备份、自动删除)
import logging
from logging import handlers
Logger = logging.getLogger() #创建一个办公室
Logger.setLevel(logging.DEBUG) #设置日志级别
th = handlers.TimedRotatingFileHandler(filename='a1.log',when='D',
backupCount=5,encoding='utf-8')
#TimedRotatingFileHandler本身无法指定日志级别,默认warning
Logger.addHandler(th)#添加日志消息处理器。把这个对象加入到logger里面,也就是把干活的人塞到办公室里面
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error("an error occurrence!")
既输出到控制台又输出到文件中
import logging
from logging import handlers
Logger = logging.getLogger() #创建一个办公室
Logger.setLevel(logging.DEBUG) #设置日志级别
#一个往屏幕上输出 StreamHandler
#一个往文件里面写东西 TimedRotatingFileHandler
fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
#定义格式
st = logging.StreamHandler() #实例化StreamHandler,相当于找一个人给你干活 往屏幕上输出
st.setFormatter(fmt) #设置屏幕上显示的格式
th = handlers.TimedRotatingFileHandler(
'my.log',when='D',encoding='utf-8',backupCount=5
#第一个参数是文件名,第二个 when是隔多久生成一个日志,backupCount就是保存几个日志文件
) #实例化TimedRotatingFileHandler 相当于找一个人给你干活 往文件里面写东西
#S 秒 M 分 H 小时 D 天 W 每星期(interval==0时代表星期一) midnight 每天凌晨
th.setFormatter(fmt)#设置文件里面写入的格式
Logger.addHandler(st) #添加日志消息处理器。把这两个对象加入到logger里面,也就是把干活的人塞到办公室里面
Logger.addHandler(th)
Logger.debug('my_log debug 信息')
Logger.info('my_log info 信息')
Logger.warning('my_log warning 信息')
Logger.error('my_log error 信息')
输出结果:控制台和my.log 文件中
2018-03-28 16:02:18,521 - C:/Users/lidal/PycharmProjects/llq-code/day10/日志模块.py[line:19] - DEBUG: my_log debug 信息
2018-03-28 16:02:18,521 - C:/Users/lidal/PycharmProjects/llq-code/day10/日志模块.py[line:20] - INFO: my_log info 信息
2018-03-28 16:02:18,521 - C:/Users/lidal/PycharmProjects/llq-code/day10/日志模块.py[line:21] - WARNING: my_log warning 信息
2018-03-28 16:02:18,521 - C:/Users/lidal/PycharmProjects/llq-code/day10/日志模块.py[line:22] - ERROR: my_log error 信息
日志模块封装:
import logging
from logging import handlers
class Logger(object):
level_relations = {
'debug': logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARNING,
'error': logging.ERROR,
'crit': logging.CRITICAL
} # 日志级别关系映射
def __init__(self,filename,level='debug',
when='D',
back_count=3,
fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
self.logger = logging.getLogger(filename) #创建一个logger对象,相当于一个办公室
# 分割日志的单位 S 秒、M 分、 H 小时、 D 天、 W 每星期(interval==0时代表星期一)、midnight 每天凌晨
#back_Count是备份文件的个数,如果超过这个个数,就会自动删除
format_str = logging.Formatter(fmt) #设置日志格式
self.logger.setLevel(self.level_relations.get(level)) #设置日志级别
sh = logging.StreamHandler()#实例化StreamHandler,相当于找一个人给你干活 往屏幕上输出
sh.setFormatter(format_str)#设置屏幕上显示的格式
th = handlers.TimedRotatingFileHandler(filename=filename,when=when,
backupCount=back_count,encoding='utf-8')
#实例化TimedRotatingFileHandler 相当于找一个人给你干活 往文件里面写东西
th.setFormatter(format_str)#设置文件里写入的格式
self.logger.addHandler(sh)#添加日志消息处理器。把这两个对象加入到logger里面,也就是把干活的人塞到办公室里面
self.logger.addHandler(th)
# log = Logger(LOG_PATH).logger
#直接在本文件里面实例化,用的时候导入log就行了,不需要再实例化了
if __name__ == '__main__':
# log = Logger(filename='test.log',level='warning')
log = Logger('test_1.log')
log.logger.debug('i的是100')
log.logger.info('开机')
log.logger.warning('警告 飞机没油了')
log.logger.error('错误 飞机要爆炸')
知识拓展:
logging模块中主要有4个类,分别负责不同的工作:
Logger 记录器,暴露了应用程序代码能直接使用的接口;简单点说就是一个创建一个办公室,让人在里头工作
Handler 处理器,将(记录器产生的)日志记录发送至合适的目的地;这个简单点说就是办事的人,你可以指定是让在控制输出日志,还是在文件里面打印日志,常用的有4种:
StreamHandler 控制台输出
FileHandler 文件输出
下面两种需要导入
handlers
from logging import handlers
TimedRotatingFileHandler 按照时间自动分割日志文件
RotatingFileHandler 按照大小自动分割日志文件,一旦达到指定的大小重新生成文件
Filter
过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。(不常用)
Formatter
格式化器,指明了最终输出中日志记录的布局。指定输出日志的格式