python logging日志记录并异步发送

需求: 将日志记录异步发送到指定服务地址

实现思路:新建一个队列,将logging的http 发送任务放入队列中。启动一个线程监控队列情况,并从队列依次取任务发送。从而将日志记录和日志发送分离开,日志发送与业务功能代码解耦,提高运行速率。 

import pytz
import logging
from logging.handlers import RotatingFileHandler
from logging.handlers import QueueHandler
from logging.handlers import QueueListener
from logging import Handler
import os
from datetime import datetime

HOST = 'https://www.leontom.com'   # 日志接收的域名
PATH = '/log'                      # 日志接收path


# --------------------------------------------log queue------------------------
class SlackQueueHandler(QueueHandler):
    """日志队列"""
    def __init__(self, queue=None):
        QueueHandler.__init__(self, queue)

    def prepare(self, record):
        """
        Override the method to allow the formatter to work.
        """
        record.msg = self.format(record)
        record.args = None
        record.exc_info = None
        return record


class SlackQueueListener(QueueListener, Handler):
    """日志队列监听者,异步发送日志"""
    def __init__(self, queue=None):
        QueueListener.__init__(self, queue)
        Handler.__init__(self)

        secure = True if HOST.startswith('https://') else False
        self.HttpHandler = TestHTTPHandler(HOST, url=PATH, method="POST", secure=secure)

    def handle(self, record):
        """
        Override the QueueListener.handle method with the Handler.handle
        method
        """
        Handler.handle(self, record)

    def emit(self, record):
        # msg = self.format(record)
        self.HttpHandler.emit(record)
# --------------------------------------------log queue------------------------


class TestHTTPHandler(logging.handlers.HTTPHandler):
    """HTTP Log日志发送"""
    def __init__(self, host, url, method="POST", secure=False, credentials=None, context=None, report_id=None):
        super().__init__(host, url, method=method, secure=secure, credentials=credentials, context=context)
        self.report_id = report_id

    def mapLogRecord(self, record):
        """发送内容"""
        tz = pytz.timezone('Asia/Shanghai')
        asctime = datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
        if hasattr(record,'name') and hasattr(record, 'message'):
            data = {"asctime":asctime, "name": record.name, "message":record.message}
        else:
            data = {"asctime":asctime, "name": 'requests', "message": str(record)}
        record_ = '%(asctime)s | %(name)s | %(message)s' % dict(data)
        record_msg = {'record': record_}
        print('----record msg----{}'.format(record_msg))
        return record_msg


class TestLogger():
    def __init__(self, filePath, fileName):
        self.filePath = filePath                     # 存放文件的路径
        self.fileName = fileName                     # 存放文件的名字
        # self.BACK_UP_COUNT = 5000                  # 文件分割上限数
        # self.MAX_LOG_BYTES = 1024 * 1024 * 10      # 单个文件最大记录数10M
        self.create_handler()                        # 初始化创建日志handler
        self.create_logger()                         # 初始化创建Logger

    def create_handler(self):
        """建立handler"""
        self.handler = RotatingFileHandler(filename=os.path.join(self.filePath, self.fileName),
                                           # maxBytes=self.MAX_LOG_BYTES,
                                           # backupCount=self.BACK_UP_COUNT,
                                           delay=1
                                           )
        formatter = logging.Formatter('%(asctime)s | %(name)s | %(message)s')         # 设定输出格式
        # formatter.converter = time.gmtime                                           # 时间转换
        self.handler.setFormatter(formatter)                                          # 格式加载到handler
        secure = True if HOST.startswith('https://') else False
        log_host = HOST.replace('https://', '').replace('http://', '')
        self.http_handler = TestHTTPHandler(host=log_host, url=PATH, secure=secure)   # 域名不带http:// , secure=False 表示http, secure=True 表示https 请求

    def create_logger(self):
        """建立Logger"""
        self.mylogger = logging.getLogger('testlog')

    def log(self, msg):
        self.mylogger.info(msg)
        self.http_handler.emit(record=msg)


if __name__ == '__main__':
    logger = TestLogger(filePath='./', fileName='test1.logs')
    logger.log('---test msg---')

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值