一.Logging工作流
使用Lgging模块的主要步骤如下。
1.导入Logging模块
无论是初次导人Loging模块,还是使用reload函数重新导人Logging模块,Logging模块中的代码都将被执行,在这个过程中将生成日志系统的默认配置信息。
2.自定义配置日志
日志模块丈持如下3种配置方式。
1)显式创建:在代码中显式创建loggers、handlers 和formatters并分别调用它们的配置函数。最快的方式是通过basconfig()方法创建具备默认配置的日志。
2)通过配置文件创建:创建一个 日志配置文件,然后使用fileConfg()函数读取该文件的内容。文件配置方式分离了日志配置和日志代码,使日志代码的维护和日志的管理变得更容易。
3)通过配置字典创建:创建一个包含配置信息的字典,然后把它传递给dictConfig)函数。
3.获取Logger对象实例
日志配置好后,可以使用日志模块的getLogger()函数获取一个Logger对象实例,代码如下。
import logging
logger = logging.getLogger(logger_name)
4.记录日志
获取Logger对象后,即可使用Lgger对象中的debug()、info(). waring(),error()和critical()方法来记录日志信息。
基于如上步骤,我们可以列出; Lggig模块的详细工作流,下面逐步讲解
第一步:在客户端/应用程序的代码中,显式调用日志记录语句发出日志请求。
发出日志请求需要显式调用日志记录语句,例如logger.info(),logger.debug()等。通查我们还会设置日志的等级和日志的展示格式。
第二步:日志对象Logger会检查第一步记录的日志级别是否满足日志记录级别的要求。
需要注意的是,要记录的日志级别须大于或等于日志记录要求的等级。如不满足,则该日志记录会被丢弃,日志流程结束。如果满足,则进行下一步操作。
5.日志等级
日志级别 | 何时适用 |
DEBUG | 最详细的日志细节信息,适用于调试问题 |
INFO | 日志详细程度仅次于DEBUG,通常用于确认程序是否按预期执行 |
WARNING | 警告信息(如空间磁盘不足),程序此时依旧按预期执行 |
ERROR | 由于发生严重问题,导致程序的某些功能不能再正常被执行 |
CRITICAL | 当发生严重错误,导致程序已不能继续执行 |
二.logging核心组成
1.了解了Logging工作流后,我们来看看Logging模块的核心组成部分。
1)日志对象(Logger): 日志对象是我们进行日志记录时创建的对象,我们可以通用它的方法传人日志模板和信息,生成一条条日志记录(Log Record),日志对象通常通过getLogger()方法获取。
2)日志格式器(Formatter);: 日志格式器用于规定日志记录的格式。通过给日志记录送加上下文信息,可以使日志记录的展示内容更为丰富。一般情况下,日志格式器负责将日志记录(Log Record)转换为可由人或外部系统解释的字符串,设置日志格式的方式如下代码:
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s-%(levlename)s-%(filename)s-%(funcname)s-%(message)s')
logger = logging.getLogger(logger_name)
logger.debug('logging')
2.对应的日志格式代表了什么:
%(asctiome)s | 表示日志记录何时被创建 |
%(filename)s | pathname的文件名部分 |
%(funcName)s | 函数名包括调用日志记录 |
%(levelname)s | 日志记录的级别(如DEBUG,INFO) |
%(levleno)s | 日志几率级别对应的数字 |
%(module)s | 模块(filename名称的部分) |
%(pathname)s | 发出日志记录调用的源文件的完整路径 |
%(name)s | 用于记录调用的日志记录器名称 |
%(lineno)d | 发出日志记录调用所在的源行号 |
三.简单实现日志系统:
import logging
import sys
# 设置日志的名称
LOGGER_NAME = 'main'
# 指定日志的等级必须在LOG_LEVEL变量里
LOG_LEVEL = ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG']
# 创建一个日志对象
def setup_logger(logger_name=LOGGER_NAME, log_level: LOG_LEVEL = None,
log_format='%(asctime)s-%(levlename)s-%(filename)s-%(funcname)s-%(message)s'):
logger = logging.getLogger(logger_name)
# 设置日志等级
try:
logger.setLevel(logging.DEBUG if not log_level else log_level)
except Exception:
raise ValueError('log等级必须属于LOG_LEVEL变量')
# 设置日志格式
formatter = logging.Formatter(log_format)
# 创建一个流处理器handler
sh = logging.StreamHandler(sys.stdout)
# 创建一个日志格式器formatter并将其添加到处理器handler中
sh.setFormatter(formatter)
# 为日志对象添加上面创建的处理器handler
logger.addHandler(sh)
def get_logger(module_name):
return logging.getLogger(LOGGER_NAME).getChild(module_name)