一个适用于 Python 学习的 Log 工厂类

前言: 本文所指的「Python 学习」涉及的范围大致是「平时工作业余,学习or测试一些Python特性,或者库代码逻辑时写的 toy program」

Python 的 logging 标准库

标准库的实现,已经很完备了,总的来说,几个基本目标已经达到(一个合格的日志库必须做到的):

  1. 线程安全
  2. 单例 + 工厂

而且,对 Logger/ Hanlder/ Formatter 等概念也封装得很完备,我们一般只需要少许工作便能得到一个能用的 logger。

我的初衷

为啥我还要来封装呢?仍然是为了方便。

不管是:

  1. 直接使用 logging.info
  2. 还是使用 fileConfig (官方已经不推荐)
  3. 还是 dictConfig (Django项目中就是用这个)

都还是需要做不少工作的(深入使用过的人都知道),况且2和3都是针对正式项目的做法,我们大可不必如何“繁文缛节”。

另外我们平时写 toy program,免不了要debug/log,我的初衷便是针对这种场景。

另外,我个人还有如下习惯:

  1. 拒绝在任何语言中使用任何形式的print,来作为调试工具,其功能性太过于孱弱,仅止步于“够用”是不够的
  2. 极少使用 debugger 进行单步调试(不管是IDE的debugger,亦或是pdb,或者各种加强版的xxdb)
  3. log 一般是我的首选调试手段
  4. 我一般期望利用 log 看到更多信息

实现

import logging
from logging import StreamHandler
from logging.handlers import RotatingFileHandler


class LogUtils(object):
    VERBOSE_FMT = ('%(levelname)s %(asctime)s %(name)s %(module)s %(process)d %(thread)d '
                   '%(filename)s_%(lineno)s_%(funcName)s  %(message)s')

    @classmethod
    def get_rotating_file_logger(cls, logger_name, filename, max_bytes=100 * 1024 * 1024, backup_count=10):
        """生成一个基于轮转文件的logger
        
        :param logger_name: 
        :param filename: 
        :param max_bytes: 
        :param backup_count: 
        :return:
        """
        logger = logging.getLogger(logger_name)

        fmtter = logging.Formatter(fmt=cls.VERBOSE_FMT)

        handler = RotatingFileHandler(filename, mode='a', maxBytes=max_bytes,
                                      backupCount=backup_count, encoding='utf-8')

        return cls._make_logger(fmtter, handler, logger)

    @classmethod
    def get_stream_logger(cls, logger_name='CONSOLE_DEBUGGER'):
        """生成一个定向到标准输出的logger, 可作为调试使用

        :param logger_name:
        :return:
        """
        logger = logging.getLogger(logger_name)

        formatter = logging.Formatter(fmt=cls.VERBOSE_FMT)

        handler = StreamHandler()

        return cls._make_logger(formatter, handler, logger)

    @classmethod
    def _make_logger(cls, formatter, handler, logger):
        handler.setFormatter(formatter)
        handler.setLevel(logging.INFO)

        logger.addHandler(handler)
        logger.setLevel(logging.INFO)

        return logger
复制代码

使用

# 我一般放在项目的 utils/log_util.py 中 :)
from log_util import LogUtils

LOGGER = LogUtils.get_stream_logger()

def func(a, b, c):
    LOGGER.info('====func start. %s ====' % [a, b, c])
    
    # 复杂的代码逻辑
    
    LOGGER.info('==== func end. ====')
    
    return something
复制代码

主要应用

  1. 调试包含异步逻辑的代码,典型如回调,async,协程程序
  2. 多线程代码,学习多线程的使用
  3. 调试多线程死锁和资源竞争问题
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值