python中logging初体验

2022-06-21 16:17:42 浏览数 (1)

前言

程序开发过程中,很多程序都有记录日志的需求,并且日志包含的信息有正常的程序访问日志还可能有错误、警告等信息输出。

python默认的print方法可以打印程序的日志,但是无法满足我们工作中对日志存储、展示更深层的需求。

本文介绍一个python常用的日志库"logging",接下来我们就看看如何使用吧~

logging介绍

Python的logging模块定义了为应用程序和库实现灵活的事件日志记录的函数和类。

Python的logging 模块提供了标准的日志接口,可以通过它存储各种格式的日志,日志记录提供了一组便利功能,用于简单的日志记录用法。

logging安装

代码语言:javascript复制
pip3 install logging

简单使用

代码如下:

代码语言:javascript复制
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
import logging

logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')

默认情况下,logging模块将日志打印到屏幕上(stdout),日志级别为WARNING(即只有日志级别高于WARNING的日志信息才会输出),日志格式如下图所示:

问题来了,日志级别等级及设置是怎样的?

怎样设置日志的输出方式?比如输出到日志文件中?

简单配置

简单配置日志级别

  • DEBUG 详细信息。
  • INFO 证明事情按预期工作。
  • WARNING 表明发生了一些意外,或者不久的将来会发生问题(如‘磁盘满了’)。软件还是在正常工作。
  • ERROR 由于更严重的问题,软件已不能执行一些功能了。
  • CRITICAL 严重错误,表明软件已不能继续运行了。
代码语言:javascript复制
#!/usr/local/bin/python
# -*- coding:utf-8 -*-
import logging

# 通过下面的方式进行简单配置输出方式与日志级别
logging.basicConfig(filename='logger.log', level=logging.INFO)

logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')

标准输出(屏幕)未显示任何信息,发现当前工作目录下生成了logger.log,内容如下:

因为通过level=logging.INFO设置日志级别为INFO,所以所有的日志信息均输出出来了。 问题又来了。

通过上述配置方法都可以配置哪些信息?

Logger,Handler,Formatter,Filter

几个重要的概念

  • Logger 记录器,暴露了应用程序代码能直接使用的接口。
  • Handler 处理器,将(记录器产生的)日志记录发送至合适的目的地。
  • Filter 过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。
  • Formatter 格式化器,指明了最终输出中日志记录的布局。

Logger 记录器

Logger是一个树形层级结构,在使用接口debug,info,warn,error,critical之前必须创建Logger实例,即创建一个记录器,如果没有显式的进行创建,则默认创建一个root logger,并应用默认的日志级别(WARN),处理器Handler(StreamHandler,即将日志信息打印输出在标准输出上),和格式化器Formatter(默认的格式即为第一个简单使用程序中输出的格式)。

代码语言:javascript复制
创建方法: logger = logging.getLogger(logger_name)
创建Logger实例后,可以使用以下方法进行日志级别设置,增加处理器Handler。
logger.setLevel(logging.ERROR) # 设置日志级别为ERROR,即只有日志级别大于等于ERROR的日志才会输出
logger.addHandler(handler_name) # 为Logger实例增加一个处理器
logger.removeHandler(handler_name) # 为Logger实例删除一个处理器

Handler 处理器

Handler处理器类型有很多种,比较常用的有三个,StreamHandler,FileHandler,NullHandler,详情可以访问Python logging.handlers 创建StreamHandler之后,可以通过使用以下方法设置日志级别,设置格式化器Formatter,增加或删除过滤器Filter。

代码如下:

代码语言:javascript复制
ch.setLevel(logging.WARN) # 指定日志级别,低于WARN级别的日志将被忽略
ch.setFormatter(formatter_name) # 设置一个格式化器formatter
ch.addFilter(filter_name) # 增加一个过滤器,可以增加多个
ch.removeFilter(filter_name) # 删除一个过滤器
StreamHandler
创建方法: sh = logging.StreamHandler(stream=None)
FileHandler
创建方法: fh = logging.FileHandler(filename, mode='a', encoding=None, delay=False)

Filter 过滤器

Handlers和Loggers可以使用Filters来完成比级别更复杂的过滤。Filter基类只允许特定Logger层次以下的事件。例如用‘A.B’初始化的Filter允许Logger ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’等记录的事件,logger‘A.BB’, ‘B.A.B’ 等就不行。如果用空字符串来初始化,所有的事件都接受。

代码如下:

代码语言:javascript复制
创建方法: filter = logging.Filter(name='')

代码如下:

代码语言:javascript复制
# -*- encoding:utf-8 -*-
import logging

# create logger
logger_name = "example"
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)

# create file handler
log_path = "./log.log"
fh = logging.FileHandler(log_path)
fh.setLevel(logging.WARN)

# create formatter
fmt = "%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s"
datefmt = "%a %d %b %Y %H:%M:%S"
formatter = logging.Formatter(fmt, datefmt)

# add handler and formatter to logger
fh.setFormatter(formatter)
logger.addHandler(fh)

# print log info
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

文件配置

配置文件logging.conf如下:

代码语言:javascript复制
keys=root,example01
[logger_root]
level=DEBUG
handlers=hand01,hand02

[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0

[handlers]
keys=hand01,hand02

[handler_hand01]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stderr,)

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('log.log', 'a')

[formatters]
keys=form01,form02

[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s

代码如下:

代码语言:javascript复制
# -*- encoding:utf-8 -*-
import logging
import logging.config

logging.config.fileConfig("./logging.conf")

# create logger
logger_name = "example"
logger = logging.getLogger(logger_name)

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

0 人点赞