python logging 实现日志分级输出到文件的全局配置(详细)

本文详细介绍了如何使用Python的logging模块进行日志配置,实现不同级别的日志信息分别输出到文件,为你的Python应用提供全面的日志记录解决方案。
import logging
import logging.config
import logging.handlers
import os
import re

from enum import Enum,unique
@unique
class DirMode(Enum):
    CONFIG = 0
    PACKAGE = 1


# """
# 日志等级:使用范围
#
# FATAL:致命错误
# CRITICAL:特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用
# ERROR:发生错误时,如IO操作失败或者连接问题
# WARNING:发生很重要的事件,但是并不是错误时,如用户登录密码错误
# INFO:处理请求或者状态变化等日常事务
# DEBUG:调试过程中使用DEBUG等级,如算法中每个循环的中间状态
# """
# """
# fomatter中可用变量
# %(levelno)s: 打印日志级别的数值
# %(levelname)s: 打印日志级别名称
# %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
# %(module)s: 打印当前模块名称
# %(filename)s: 打印当前执行程序名
# %(funcName)s: 打印日志的当前函数
# %(lineno)d: 打印日志的当前行号
# %(asctime)s: 打印日志的时间
# %(thread)d: 打印线程ID
# %(threadName)s: 打印线程名称
# %(process)d: 打印进程ID
# %(message)s: 打印日志信息
# """

LOGGING_CONFIG = {
    "version": 1,
    "disable_existing_loggers": False,
    "log_dir": "D:/logs/",
    "formatters": {
        "simple": {
            'format': '%(asctime)s [%(name)s] [%(module)s#%(funcName)s] [%(levelname)s]- %(message)s'
        },
        'standard': {
            'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(levelname)s]- %(message)s'
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "simple",
            "stream": "ext://sys.stdout"
        },
        "debug": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "level": "DEBUG",
            "formatter": "simple",
            "filename": "debug.log",
            "when": "midnight",
            "interval": 1,
            "backupCount": 6,
            "encoding": 'utf-8'
        },
        "info": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "level": "INFO",
            "formatter": "simple",
            "filename": "info.log",
            "when": "midnight",
            "interval": 1,
            "backupCount": 6,
            "encoding": 'utf-8'
        },
        "warn": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "level": "WARN",
            "formatter": "simple",
            "filename": "warn.log",
            "when": "midnight",
            "interval": 1,
            "backupCount": 6,
            "encoding": 'utf-8'
        },
        "error": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "level": "ERROR",
            "formatter": "simple",
            "filename": "error.log",
            "when": "midnight",
            "interval": 1,
            "backupCount": 6,
            "encoding": 'utf-8'
        }
    },

    # "loggers": {
    #     "data": {
    #         "level": "DEBUG",
    #         "handlers": ['debug',"info","warn","error","console"],
    #         "propagate": False
    #     }
    # },

    "root": {
        'handlers': ['debug',"info","warn","error","console"],
        'level': "DEBUG",
        'propagate': False
    }
}



def get_filter(level):
    if level == logging.DEBUG:
        return lambda record: record.levelno < logging.INFO
    elif level == logging.INFO:
        return lambda record: record.levelno < logging.WARN
    elif level == logging.WARN:
        return lambda record: record.levelno < logging.ERROR
    else:
        return lambda record: record.levelno <= logging.FATAL

def adjust_config(logging_config,dir_mode = DirMode.CONFIG):
    # 使用配置目录
    if dir_mode == DirMode.CONFIG:
        dirName = logging_config['log_dir']
    # 使用logger.py同级目录
    else:
        currentdir = os.path.dirname(__file__).replace('\\', '/')
        dirName = currentdir + '/logs/'

    handlers = logging_config.get('handlers')
    for handler_name,handler_config in handlers.items():
        filename = handler_config.get('filename',None)
        if filename is None:
            continue
        if dirName is not None:
            if not os.path.exists(dirName):
                try:
                    os.makedirs(dirName)
                except Exception as e:
                    print(e)
            handler_config['filename'] = dirName + filename
    return logging_config


def get_logger(name=None):
    #  拷贝配置字典
    logging_config = copy.deepcopy(LOGGING_CONFIG)

    # 调整配置内容
    adjust_config(logging_config,DirMode.PACKAGE)

    # 使用调整后配置生成logger
    logging.config.dictConfig(logging_config)
    res_logger = logging.getLogger(name)


    for handler in res_logger.root.handlers:
        if handler.name == 'console':
            continue
        log_filter = logging.Filter()
        log_filter.filter = get_filter(handler.level)
        handler.addFilter(log_filter)
    return res_logger







#use_logger.py 和 logger.py在同级目录

from logger import get_logger

if __name__ == '__main__':
    logger = get_logger('test')
    logger.debug('debug')
    logger.inf('info')
    logger.warn('warn')
    logger.error('error')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值