python-logging模块的简单使用:如何同时输出到控制台和本地日志文件
程序员文章站
2022-07-15 15:54:25
...
本文简单记录logging模块使用方法。参考博客
提供两种记录日志的方式:
- 使用logging提供的模块级别的函数
- 使用logging模块的四大组件
一、简单使用——函数
下面是常用函数
logging.debug()
logging.info()
logging.warning()
logging.error()
logging.critical() #输出函数,级别从低到高逐渐递增
logging.log(logging.debug, msg)#与上面的函数等价
logging.basicConfig()#配置函数
1.配置函数说明
通过设置配置函数(basicConfig)然后,调用log打印函数就可以满足简单的使用了,下面对配置函数接收参数进行简单的说明。
参数名称 | 描述 |
---|---|
filename | 指定输出文件名,如果指定后就不会输出到控制台。 |
format | 指定日志格式字符串,详细见下面。 |
datefmt | 指定时间格式。只有在format包含%(asctime)才有效 |
level | 指定日志级别 |
stream | 指定日志输出目标stream,比如sys.stdout等(默认是sys.stderr)。 |
handlers | python 3.3新添加的,该项如果被指定,应该是一个创建了多个Handler的可迭代对象,这些handler将会被添加到root logger。注意filename、stream和handlers只能有一个存在,否则会引发ValueError异常 |
2.格式字符串——format
使用格式 | 描述 |
---|---|
%(asctime)s | 日志事件发生的时间——人类可读时间,可以通过datefmt修改格式 |
%(created)f | 日志事件发生的时间——时间戳 |
%(levelname)s | 日志级别 |
%(name)s | 日志器名称,默认是‘root’ |
%(message)s | 日志记录的文本内容 |
%(pathname)s | 调用日志记录函数的源码文件的全路径 |
%(filename)s | pathname的文件名部分,包含后缀 |
%(lineno)s | 调用日志记录函数的源代码所在行号 |
%(fucName)s | 调用日志函数名 |
3.样例
程序
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"
logging.basicConfig(filename='my.log', level=logging.DEBUG, format=LOG_FORMAT, datefmt=DATE_FORMAT)
logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
文件输出内容
08/26/2018 15:37:14 PM - DEBUG - This is a debug log.
08/26/2018 15:37:14 PM - INFO - This is a info log.
08/26/2018 15:37:14 PM - WARNING - This is a warning log.
08/26/2018 15:37:14 PM - ERROR - This is a error log.
08/26/2018 15:37:14 PM - CRITICAL - This is a critical log.
4.注意事项
- logging.basicConfig()函数是一个一次性简单配置工具,只会在第一次调用时生效,后续再次调用将不会产生任何效果。
- 日志器(Logger)是有层级关系的,上面调用的logging模块级别的函数所使用的日志器是RootLogger类的实例,名称为’root’,它处于日志器层级关系最顶层的日志器,以单例模式存在。
二、高阶使用——四大组件
组件名称 | 对应类名 | 功能描述 |
---|---|---|
日志器 | Logger | 提供了应用程序使用的结构的接口 |
处理器 | Handler | 将logger创建的日志记录发送发合适的目的输出 |
过滤器 | Filter | 提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录 |
格式器 | Formatter | 决定日志记录的最终输出格式 |
整个处理流程相对而言还是很复杂,建议去看前文提到的链接。
常见方法
名称 | 描述 |
---|---|
Logger.setLevel() | 设置日志器处理级别 |
Logger.addHandler()、Logger.removeHandler() | 为该logger对象添加和移除一个handler对象 |
Logger.addFilter()、Logger.removeFilter() | 为该logger对象添加和移除一个filter对象 |
Handler.setLevel() | 设置handler将会处理的日志级别 |
Handler.setFormatter() | 为handler设置一个格式器对象 |
Handler.addFilter()、Handler.removeFilter() | 为handler添加和删除一个过滤对象 |
logging.StreamHandler | 将日志消息发送到输出到Stream,如std.out,std.err |
logging.FileHandler | 将日志消息发送到磁盘文件,默认文件大小会无限增长 |
logging.hanlders.TimeRotatingFileHandler | 将日志消息发送到磁盘文件,并支持日志文件按时间切割 |
一条日志消息想被最终输出,需要经过以下几次过滤:
- 日志器等级过滤
- 日志器的过滤器过滤
- 日志器的处理器等级过滤
- 日志器的处理器的过滤器过滤
简单实例
在该样例中,实现了既将日志信息打印到控制台,又将日志信息存储到磁盘。注意以最高等级过滤为准。
import logging
import datetime
import sys
logger = logging.getLogger('mylogger')
logger.setLevel(logging.INFO)
rf_handler = logging.StreamHandler(sys.stderr)#默认是sys.stderr
rf_handler.setLevel(logging.DEBUG)
#rf_handler = logging.handlers.TimedRotatingFileHandler('all.log', when='midnight', interval=1, backupCount=7, atTime=datetime.time(0, 0, 0, 0))
rf_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(message)s"))
f_handler = logging.FileHandler('error.log')
f_handler.setLevel(logging.ERROR)
f_handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(filename)s[:%(lineno)d] - %(message)s"))
logger.addHandler(rf_handler)
logger.addHandler(f_handler)
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')