python多线程日志打印封装

日志记录统一格式和位置,多线程多文件多策略分类记录和打印

# -*- coding: utf-8 -*-
import atexit
import hashlib
import logging.config
import os
import sys
import queue
import time
from logging.handlers import QueueHandler, TimedRotatingFileHandler

class HiwayTimedRotatingFileHandler(TimedRotatingFileHandler):
	"""修改日志文件命名格式"""
    def __init__(self, *args, **kwargs):
        super(HiwayTimedRotatingFileHandler, self).__init__(*args, **kwargs)

    def doRollover(self):
        """
        do a rollover; in this case, a date/time stamp is appended to the filename
        when the rollover happens.  However, you want the file to be named for the
        start of the interval, not the current time.  If there is a backup count,
        then we have to get a list of matching filenames, sort them and remove
        the one with the oldest suffix.
        """
        if self.stream:
            self.stream.close()
            self.stream = None
        # get the time that this sequence started at and make it a TimeTuple
        currentTime = int(time.time())
        dstNow = time.localtime(currentTime)[-1]
        t = self.rolloverAt - self.interval
        if self.utc:
            timeTuple = time.gmtime(t)
        else:
            timeTuple = time.localtime(t)
            dstThen = timeTuple[-1]
            if dstNow != dstThen:
                if dstNow:
                    addend = 3600
                else:
                    addend = -3600
                timeTuple = time.localtime(t + addend)
        dfn = self.rotation_filename(self.baseFilename[:-4] +
                                     time.strftime(self.suffix, timeTuple) + ".log")
        if os.path.exists(dfn):
            os.remove(dfn)
        self.rotate(self.baseFilename, dfn)
        if self.backupCount > 0:
            for s in self.getFilesToDelete():
                os.remove(s)
        if not self.delay:
            self.stream = self._open()
        newRolloverAt = self.computeRollover(currentTime)
        while newRolloverAt <= currentTime:
            newRolloverAt = newRolloverAt + self.interval
        # If DST changes and midnight or weekly rollover, adjust for this.
        if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
            dstAtRollover = time.localtime(newRolloverAt)[-1]
            if dstNow != dstAtRollover:
                if not dstNow:  # DST kicks in before next rollover, so we need to deduct an hour
                    addend = -3600
                else:  # DST bows out before next rollover, so we need to add an hour
                    addend = 3600
                newRolloverAt += addend
        self.rolloverAt = newRolloverAt
        
LOG_DIR = os.path.join("logs", datetime.datetime.now().strftime("%Y-%m-%d"))
if not os.path.exists(LOG_DIR):
    os.makedirs(LOG_DIR)

# 全局日志把手
logger_handlers = {}

def get_logger(log_name='defalut', console_mode=True, when='D',level=logging.INFO):
    """

    :param log_name: 日志名
    :param console_mode: 是否打印标志
    :param when: 分页模式;D--每天,H--每小时
    :param level: 日志默认记录等级
    :return: 日志把手
    """
    log_md5=hashlib.md5(log_name.encode('utf-8')).hexdigest()
    logger_obj = logger_handlers.get(log_md5)
    if logger_obj:
        return logger_obj
    # 定义线程中日志队列
    default_queue = queue.Queue(-1)
    default_queue_handler = QueueHandler(default_queue)

    # 定义日志文件把手
    default_handler = HiwayTimedRotatingFileHandler(filename=os.path.join(LOG_DIR, f"{log_name}.log"), when=when,
                                                    backupCount=5, encoding='utf-8')
    # 定义日志打印把手
    default_stream_handler = logging.StreamHandler()
    # 定义日志格式
    simple_formater = '%(asctime)s - %(levelname)s - %(name)s - %(filename)s:%(lineno)d >> %(message)s'
    standard_formater = '[%(asctime)s][%(threadName)s:%(thread)d][log_name:%(name)s][%(filename)s:%(lineno)d][%(levelname)s] >> %(message)s'
    formatter = logging.Formatter(standard_formater)
    default_handler.setFormatter(formatter)
    default_stream_handler.setFormatter(formatter)
    # 定义日志监听器
    default_listener = logging.handlers.QueueListener(default_queue, default_handler, respect_handler_level=True)

    # 定义日志记录器
    default_logger = logging.getLogger(log_name)
    default_logger.propagate = False
    default_logger.addHandler(default_queue_handler)
    if console_mode:
        default_logger.addHandler(default_stream_handler)
    default_logger.setLevel(level)
    default_listener.start()
    atexit.register(default_listener.stop)
    logger_handlers.update({log_md5: default_logger})
    return default_logger



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值