logging 模块

一、logging模块的主要结构

实现主要功能的四个类:

1、Loggers(记录器)

提供应用程序直接使用的接口,如相关配置设置。

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

创建方法:

logger = logging.getLogger(logger_name)

创建Logger实例后,可以使用以下方法进行日志级别设置,增加处理器Handler

logger.setLevel(logging.ERROR) 			# 设置日志级别为ERROR,即只有日志级别大于等于ERROR的日志才会输出
logger.addHandler(handler_name) 		# 为Logger实例增加一个处理器
logger.removeHandler(handler_name) 		# 为Logger实例删除一个处理器
2、Handlers(处理器)

Logger产生的日志信息传到指定位置,设置日志的保存位置。

Handler处理器类型有很多种,比较常用的有三个:StreamHandlerFileHandlerNullHandler

创建StreamHandler之后,可以通过使用以下方法设置日志级别,设置格式化器Formatter,增加或删除过滤器Filter

ch.setLevel(logging.WARN) 			# 指定日志级别,低于WARN级别的日志将被忽略
ch.setFormatter(formatter_name) 	 # 设置一个格式化器formatter
ch.addFilter(filter_name) 			# 增加一个过滤器,可以增加多个
ch.removeFilter(filter_name) 		# 删除一个过滤器

(1)StreamHandler

创建方法:

sh = logging.StreamHandler(stream = None)

(2)FileHandler

创建方法:

fh = logging.FileHandler(filename, mode=‘a’, encoding=None, delay=False)

其他的一些Handler处理器:

(3)RotatingFileHandler

类似于FileHandler,但他可以管理文件大小。当文件达到一定大小之后,他会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出。

创建方法:

rfh = logging.RotatingFileHandler(filename, mode, maxBytes, backupCount)
  • maxBytes:指定日志文件大小,如果为0,意味着文件可以无限大,这时上面的重命名过程就不会发生。
  • backupCount指定保留备份文件的个数。

(4)TimedRotatingFileHandler

类似于RotatingFileHandler,不过他没有通过判断文件大小来决定何时重新创建日志,二是间隔一定时间就自动创建一个新的日志文件。

创建方法:

trfh = logging.TimedRotatingFileHandler(filename, when, interval, backupCount)
  • interval:表示时间间隔

  • when:参数是一个字符串。表示时间间隔的单位,不区分大小写,他的取值为:S 秒M 分H 小时D 天W每星期interval==0代表星期一),midnight每天凌晨

(5)NullHandler
NullHandler类位于核心logging包,不做任何的格式化或者输出。
本质上它是个“什么都不做”的handler,由库开发者使用。

(6)SocketHandlerDatagramHandler

以上两个Handler类似,都是讲日志信息发送到网络,不同的是前者使用TCP协议,后者使用UDP协议。他们的构造函数是:Handlerhostport)(主机名, 端口名)

(7)其他
SysLogHandlerNTEventLogHandlerSMTPHandlerMemoryHandlerHTTPHandler

3、Filters(过滤器)

对输出日志进行过滤操作

HandlersLoggers可以使用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’等就不行。 如果用空字符串来初始化,所有的事件都接受。

创建方法:

filter = logging.Filter(name='')
4、Formatters(格式化器)

控制日志的输出格式

使用Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S

创建方法:

formatter = logging.Formatter(fmt=None, datafmt=None)

其中,fmt是消息的格式化字符串datefmt是日期字符串。如果不指明fmt,将使用'%(message)s'。如果不指明datefmt,将使用ISO8601日期格式。

5、总结:

    Logger是一个树形层级结构;一个Logger可以包含一个或者多个HandlerFilter。即LoggerHandler或者Filter时一对多的关系。

    一个Logger示例可以新增多个Handler,一个Handler可以新增多个格式化器或者多个过滤器,而且日志界别将会继承。

示例

import logging
import sys

def get_logger(appname):
    # 获取logger实例,如果参数为空则返回root logger
    logger = logging.getLogger(appname)
    # 创建日志输出格式
    formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')

    # 设置文件处理器,加载处理格式
    file_handler = logging.FileHandler("test.log") # 指定输出的文件路径
    file_handler.setFormatter(formatter)

    # 控制台日志
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.formatter = formatter

    # 为logger添加的日志处理器
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)

    # 指定日志的最低输出级别,默认为WARN级别
    logger.setLevel(logging.INFO)

if __name__  == "__main__":
    logger = get_logger('test')
    logger.debug('this is debug info')
    logger.info('this is information')
    logger.warn('this is warning message')
    logger.error('this is error message')
    logger.fatal('this is fatal message, it is same as logger.critical')
    logger.critical('this is critical message')
二、Logger日志记录的逻辑调用过程

    1. 记录日志通过调用logger.debug()等方法;

    2. 首先判断本条记录的日志级别是否大于设置的级别,如果不是,直接pass,不再执行;

    3. 将日志信息当做参数创建一个LogRecord日志记录对象;

    4. 将LogRecord对象经过logger过滤器过滤,如果被过滤掉则pass;

    5. 日志记录对象被Handler处理器的过滤器过滤;

    6. 判断本条记录的日志级别是否大于Handler处理器设置的级别,如果不是,直接pass,不再执行,最后调用处理器的emit方法处理日志记录;

三、logging的配置

logging的配置有以下几种方式:

    1、通过代码进行完整配置,主要通过getLogger方法实现,但不好修改

    2、通过BasicConfig方法实现,这种方式快速但不够层次分明

    3、通过logging.config.file(filepath),文件配置

    4、通过dictConfig的字典方式配置,这事py3.2版本引入的新的方法

    5、通过网络进行配置,使用listen()函数进行网络配置

常用的配置方式为1、2、3,下面通过示例分别对这三种配置方式进行介绍。

1、通过代码配置
import logging
import sys

def get_logger(appname):
    # 获取logger实例,如果参数为空则返回root logger
    logger = logging.getLogger(appname)
    # 创建日志输出格式
    formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')

    # 设置文件处理器,加载处理格式
    file_handler = logging.FileHandler("test.log") # 指定输出的文件路径
    file_handler.setFormatter(formatter)

    # 控制台日志
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.formatter = formatter

    # 为logger添加的日志处理器
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)

    # 指定日志的最低输出级别,默认为WARN级别
    logger.setLevel(logging.INFO)

if __name__  == "__main__":
    logger = get_logger('test')
    logger.debug('this is debug info')
    logger.info('this is information')
    logger.warn('this is warning message')
    logger.error('this is error message')
    logger.fatal('this is fatal message, it is same as logger.critical')
    logger.critical('this is critical message')
2、通过BasicConfig配置
# -*- 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')```
3、通过文件配置

配置文件logging.conf

# logging.conf

[loggers]    # 定义日志的对象名称是什么,注意必须定义root,否则报错。
keys=root,main

[handlers]  # 定义处理器的名称是什么,可以有多个,用逗号隔开
keys=consoleHandler

[formatters]  # 定义输出格式对象的名称,可以有多个,用逗号隔开
keys=simpleFormatter

[logger_root]  # 配置root对象的日志记录级别和使用的处理器
level=INFO
handlers=consoleHandler

[logger_main] # 配置main对象的日志记录级别和使用的处理器,qualname值得就是日志对象的名字
level=INFO
handlers=consoleHandler
qualname=main
propagate=0  # logger对象把日志记录传递给所有相关的handler的时候,会(逐级向上)寻找这个logger和它所有的父logger的全部handler,propagate=1表示会继续向上搜寻;propagate=0表示停止搜寻,这个参数涉及重复打印的坑。

[handler_consoleHandler] # 配置处理器consoleHandler
class=StreamHandler      
level=WARNING
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]  # 配置输出格式过滤器simpleFormatter
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

定义好配置文件后,需要在使用时加载配置文件。
【示例】

#!/usr/bin/python
# -*- 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’)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值