logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;
在python中,logging由logger,handler,filter,formater四个部分组成,
logger是提供我们记录日志的方法;handler是让我们选择日志的输出地方,如:控制台,文件,邮件发送等,一个logger添加多个handler;filter是给用户提供更加细粒度的控制日志的输出内容;formater用户格式化输出日志的信息。
python中配置logging有三种方式
第一种:基础配置,logging.basicConfig(filename="config.log",filemode="w",format="%(asctime)s-%(name)s-%(levelname)s-%(message)s",level=logging.INFO)。
第二种:使用配置文件的方式配置logging,使用fileConfig(filename,defaults=None,disable_existing_loggers=Ture )函数来读取配置文件。
第三种:使用一个字典方式来写配置信息,然后使用dictConfig(dict,defaults=None, disable_existing_loggers=Ture )函数来瓦按成logging的配置.
一 .level
日志一共分成5个等级,从低到高分别是:DEBUG ,INFO ,WARNING ,ERROR, CRITICAL。
DEBUG:详细的信息,通常只出现在诊断问题上
INFO:确认一切按预期运行
WARNING:一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”)。这个软件还能按预期工作。
ERROR:更严重的问题,软件没能执行一些功能
CRITICAL:一个严重的错误,这表明程序本身可能无法继续运行
这5个等级,也分别对应5种打日志的方法: debug 、info 、warning 、error 、critical。默认的是WARNING,当在WARNING或之上时才被跟踪。
二.日志输出:可以输出在控制台和文件,我选择的是输出在文件
StreamHandler:logging.StreamHandler;日志输出到流,可以是sys.stderr,sys.stdout或者文件
FileHandler:logging.FileHandler;日志输出到文件
BaseRotatingHandler:logging.handlers.BaseRotatingHandler;基本的日志回滚方式
RotatingHandler:logging.handlers.RotatingHandler;日志回滚方式,支持日志文件最大数量和日志文件回滚
日志回滚的意思为:比如日志文件是chat.log,当chat.log达到指定的大小之后,RotatingFileHandler自动把文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。最后重新创建 chat.log,继续输出日志信息。【这样保证了chat.log里面是最新的日志】
TimeRotatingHandler:logging.handlers.TimeRotatingHandler;日志回滚方式,在一定时间区域内回滚日志文件
SocketHandler:logging.handlers.SocketHandler;远程输出日志到TCP/IP sockets
DatagramHandler:logging.handlers.DatagramHandler;远程输出日志到UDP sockets
SMTPHandler:logging.handlers.SMTPHandler;远程输出日志到邮件地址
SysLogHandler:logging.handlers.SysLogHandler;日志输出到syslog
NTEventLogHandler:logging.handlers.NTEventLogHandler;远程输出日志到Windows NT/2000/XP的事件日志
MemoryHandler:logging.handlers.MemoryHandler;日志输出到内存中的指定buffer
HTTPHandler:logging.handlers.HTTPHandler;通过"GET"或者"POST"远程输出到HTTP服务器
三、日志格式说明
logging.basicConfig函数中,可以指定日志的输出格式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: 打印日志信息
我在工作中给的常用格式在前面已经看到了。就是:
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'
这个格式可以输出日志的打印时间,是哪个模块输出的,输出的日志级别是什么,以及输入的日志内容。
实例代码:
#!/usr/bin/env python
# coding=utf-8
import logging
import os
import datetime
import logging.config
# **** 日志配置 ****
from config.VarConfig import parentDirPath
#通过创建一个包含配置信息的dict,然后把它传递个dictConfig()函数,来配置logging
'''
Python 3.2中引入的一种新的配置日志记录的方法--用字典来保存logging配置信息。
我们可把很多的数据转换成字典。比如,我们可以使用JSON格式的配置文件、YAML格式的配置文件,然后将它们填充到一个配置字典中;或者,我们也可以用Python代码构建这个配置字典,
或者通过socket接收pickled序列化后的配置信息。
总之,你可以使用你的应用程序可以操作的任何方法来构建这个配置字典。
'''
LOG_PATH = os.path.join(parentDirPath, "logs")
LOG_SETTINGS = dict(
#version是必选项,其值是一个整数值,表示配置格式的版本,当前唯一可用的值就是1
version=1,
#这是一个布尔型值,默认值为True(为了向后兼容)表示禁用已经存在的logger,除非它们或者它们的祖先明确的出现在日志配置中;
# 如果值为False则对已存在的loggers保持启动状态。
disable_existing_loggers=False,
#Formatter 格式化器,指明了最终输出中日志的格式。
formatters={
'standard': {
'format': '%(asctime)s [%(filename)s:%(lineno)d] %(levelname)s: %(message)s'
},
},
#Handler 处理器,将日志记录发送至合适的路径。
handlers={
'file': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(LOG_PATH,
"result_{}.log".format(datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S'))),
'formatter': 'standard',
'maxBytes': 1024 * 1024 * 5, # 5 MB
'backupCount': 5
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'standard'
},
},
#配置logger信息。必须包含一个名字叫做root的logger,当使用无参函数logging.getLogger()时,默认返回root这个
root={
'handlers': ['console', 'file'],
'level': logging.DEBUG,
},
#Logger 记录器,用于设置日志采集
loggers={
'default': {
'handlers': ['file', 'console'],
'level': logging.DEBUG,
'propagate': False
},
}
)
if not os.path.exists(LOG_PATH):
os.mkdir(LOG_PATH)
def init_log():
logging.config.dictConfig(LOG_SETTINGS)
if __name__ == "__main__":
init_log()
logging.debug("测试一个debug的log")
logging.info("测试一个info的log")