欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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