Python日志logging模块

Python日志logging模块

logging模块架构

日志级别

默认的级别是 “WARNING“,意味着只会追踪该级别及以上的事件。

级别 何时使用
DEBUG 细节信息,仅当诊断问题时适用。
INFO 确认程序按预期运行
WARNING 表明有已经或即将发生的意外(例如:磁盘空间不足)。程序仍按预期进行
ERROR 由于严重的问题,程序的某些功能已经不能正常执行
CRITICAL 严重的错误,表明程序已不能继续执行

涉及到的类

logging采用了模块化设计,主要包含四种组件:

Logger:记录器,提供应用程序代码能直接使用的接口。(类似于笔,使用不同的笔记录不同的日志,例如一个项目里有很多功能模块,每个模块可以设置不同的Logger去记录,然后设置每只笔的不同格式)

Handler:处理器,将记录器产生的日志发送到目的地。(输出到文件或者控制台或者邮件等,一个记录器可以对应多个处理器。)

Filter:过滤器,提供更好的粒度控制,决定哪些日志会被输出。

Formatter:格式化器,设置日志内容的组成结构和消息字段。

img

Logger

有默认的 root logger 和额外声明的 logger。

  1. 提供应用程序的调用接口
logger = logging.getLogger(__name__)
# logger是单例的,也就是__name__不变,获取到的logger都是同一个

2.决定日志记录的级别

logger.setLevel()

3.将日志内容传递到相关联的handlers中

logger.addHandler()
logger.removeHandler()

Handler

将日志写入到不同的位置:

  • StreamHandler #流输出,默认是控制台 stderr

    sh = logging.StreamHandler(stream=None)
    
  • FileHandler #文件记录

    fh = logging.FileHandler(filename,mode='a',encoding=None,delay=False)
    
  • BaseRotatingHandler #标准的分割文件日志

  • RotatingFileHandler #按文件大小记录日志

  • TimeRotatingFileHandler #按时间记录日志

Filter

Filters 可被 HandlersLoggers 用来实现比按层级提供更复杂的过滤操作。我没用过。

Formatter

设置当前Handler对象使用的消息格式。

使用

基本使用

import logging

# 根日志器默认日志级别为WARNING,这里将其重置,以保证debug、info级别的日志也能输出
logging.basicConfig(level=logging.DEBUG #设置日志输出格式
                    ,filename="demo.log" #log日志输出的文件位置和文件名
                    ,filemode="w" #文件的写入格式,w为重新写入文件,默认是追加
                    ,format="%(asctime)s - %(name)s - %(levelname)-9s - %(filename)-8s : %(lineno)s line - %(message)s" #日志输出的格式
                    # -8表示占位符,让输出左对齐,输出长度都为8位
                    ,datefmt="%Y-%m-%d %H:%M:%S" #时间输出的格式
                    )

logging.debug("This is a %s message.",logging.getLevelName(logging.DEBUG))
logging.info("This is an %s message.",logging.getLevelName(logging.INFO))
logging.warning("This is a %s message.",logging.getLevelName(logging.WARNING))
logging.error("This is an %s message.",logging.getLevelName(logging.ERROR))
logging.critical("This is a %s message.",logging.getLevelName(logging.CRITICAL))

logging.log(logging.INFO,"This ia a message from logging.log().") # 也可以这样用

或者为每个记录器自己设置:

import logging
#记录器
logger1 = logging.getLogger("logger1")
logger1.setLevel(logging.DEBUG)

logger2 = logging.getLogger("logger2")
logger2.setLevel(logging.INFO)


#处理器
#1.标准输出
sh1 = logging.StreamHandler()
sh1.setLevel(logging.WARNING)

sh2 = logging.StreamHandler()


# 2.文件输出
# 没有设置输出级别,将用logger1的输出级别(并且输出级别在设置的时候级别不能比Logger的低!!!),设置了就使用自己的输出级别
fh1 = logging.FileHandler(filename="fh.log",mode='w')

fh2 = logging.FileHandler(filename="fh.log",mode='a')
fh2.setLevel(logging.WARNING)

# 格式器
fmt1 = logging.Formatter(fmt="%(asctime)s - %(levelname)-9s - %(filename)-8s : %(lineno)s line - %(message)s")
fmt2 = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)-9s - %(filename)-8s : %(lineno)s line - %(message)s"
                        ,datefmt="%Y/%m/%d %H:%M:%S")

#给处理器设置格式
sh1.setFormatter(fmt1)
fh1.setFormatter(fmt2)

sh2.setFormatter(fmt2)
fh2.setFormatter(fmt1)

#记录器设置处理器
logger1.addHandler(sh1)
logger1.addHandler(fh1)

logger2.addHandler(sh2)
logger2.addHandler(fh2)

#打印日志代码
logger1.debug("This is  DEBUG of logger1 !!")
logger1.info("This is  INFO of logger1 !!")
logger1.warning("This is  WARNING of logger1 !!")
logger1.error("This is  ERROR of logger1 !!")
logger1.critical("This is  CRITICAL of logger1 !!")

logger2.debug("This is  DEBUG of logger2 !!")
logger2.info("This is  INFO of logger2 !!")
logger2.warning("This is  WARNING of logger2 !!")
logger2.error("This is  ERROR of logger2 !!")
logger2.critical("This is  CRITICAL of logger2 !!")

高级使用

上述的方法都写的很死板,在小工程或者单个文件还可以,但是当项目大了,我们就必须使用配置文件的方式配置logging的信息,从而来灵活使用,主要有两种方式去配置,一种是分section的conf文件,一种是JSON字典文件。

import logging.config

logging.config.fileConfig("/path/to/configfile") # 读取conf格式的配置文件
logging.config.dictConfig("/path/to/configfile") # 读取字典格式的配置文件
posted @ 2024-03-02 09:14  3的4次方  阅读(32)  评论(0编辑  收藏  举报