【Python 模块】logging 日志模块

日志级别

级别说明

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

级别等级

默认等级是WARNING,这意味着仅仅这个等级及以上的才会反馈信息,除非logging模块被用来做其它事情。

级别 数字值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

中间处理器(Handler)

是配置日志是打印在控制台还是输出到文件 等等,多个处理器可以共用

logging.FileHandler

该类会把日志写入磁盘文件

import logging
from logging import FileHandler

# 返回一个指定记录器名称
logger = logging.getLogger(__name__)

# 该中间程序器会把日志写入磁盘文件
handler = FileHandler(
                    filename="error.log", # 日志文件名称
                    mode='a', # 写入模式
                    encoding="utf-8" # 编码
                )
# 该中间程序处理器的日志级别
handler.setLevel(logging.ERROR)
# 设置该中间处理器的日志输出格式
handler.setFormatter(logging.Formatter('%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s'))

# 添加中间处理器
logger.addHandler(handler)

# 使用
logger.error(msg=f'文件输出')

logging.StreamHandler

控制台输出

import logging
from logging import StreamHandler

# 返回一个指定记录器名称
logger = logging.getLogger(__name__)

# 该中间程序器会把日志写入到流中
handler = StreamHandler()
# 该中间程序处理器的日志级别
handler.setLevel(logging.ERROR)
# 设置该中间处理器的日志输出格式
handler.setFormatter(logging.Formatter('%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s'))
# 添加中间处理器
logger.addHandler(handler)

# 使用
logger.error(msg=f'文件输出')

日志输入格式配置(Formatter)

规定日志输出的内容的格式

格式 描述
%(levelno)s 打印日志级别的数值
%(levelname)s 日志级别
%(pathname)s 当前执行程序的路径
%(filename)s 当前执行程序名称
%(funcName)s 日志的当前函数
%(lineno)d 日志的当前行号
%(asctime)s 日志的时间
%(thread)d 线程id
%(threadName)s 线程名称
%(process)d 进程ID
%(message)s 日志信息
logging.Formatter('%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s')
----
2020-08-10 17:20:50,687 ERROR test.py 22 33480 文件输出

常见配置

单个文件使用

默认输出到控制台

import logging
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
logger.info(msg=f"大数据男孩")

输出结果

2020-08-10 17:48:30,772 - __main__ - INFO - 大数据男孩

多个文件应用

import logging
import sys
from os import makedirs
from os.path import dirname, exists

loggers = {}

LOG_ENABLED = True  # 是否开启日志
LOG_TO_CONSOLE = True  # 是否输出到控制台
LOG_TO_FILE = True  # 是否输出到文件
LOG_TO_ES = True  # 是否输出到 Elasticsearch

LOG_PATH = './runtime.log'  # 日志文件路径
LOG_LEVEL = 'DEBUG'  # 日志级别
LOG_FORMAT = '%(levelname)s - %(asctime)s - process: %(process)d - %(filename)s - %(name)s - %(lineno)d - %(module)s - %(message)s'  # 每条日志输出格式

def get_logger(name=None):
    """
    get logger by name
    :param name: name of logger
    :return: logger
    """
    global loggers

    if not name: name = __name__

    if loggers.get(name):
        return loggers.get(name)

    logger = logging.getLogger(name)
    logger.setLevel(LOG_LEVEL)

    # 输出到控制台
    if LOG_ENABLED and LOG_TO_CONSOLE:
        stream_handler = logging.StreamHandler(sys.stdout)
        stream_handler.setLevel(level=LOG_LEVEL)
        formatter = logging.Formatter(LOG_FORMAT)
        stream_handler.setFormatter(formatter)
        logger.addHandler(stream_handler)

    # 输出到文件
    if LOG_ENABLED and LOG_TO_FILE:
        # 如果路径不存在,创建日志文件文件夹
        log_dir = dirname(LOG_PATH)
        if not exists(log_dir): makedirs(log_dir)
        # 添加 FileHandler
        file_handler = logging.FileHandler(LOG_PATH, encoding='utf-8')
        file_handler.setLevel(level=LOG_LEVEL)
        formatter = logging.Formatter(LOG_FORMAT)
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)

    # 保存到全局 loggers
    loggers[name] = logger
    return logger

if __name__ == '__main__':
    logger = get_logger()
    logger.debug('this is a message')

输出结果

DEBUG - 2020-08-10 17:46:12,213 - process: 17884 - demo.py - __main__ - 59 - demo - this is a message
发表评论 / Comment

用心评论~