locust 日志记录

 locust 日志记录并发送至指定服务器

新建文件

locust_log.py
from locust import events
import logging
from logging.handlers import RotatingFileHandler
import pytz
import datetime
import os

PERF_HOST = 'http://www.leontom.com'  # 日志接收的服务地址
REPORT_LOCUST_LOGS_URL = '/test/logs'  # 日志API url
LOGGING_SECURE = False  # logging 发送请求方式 False ->http; True->https


class LocustLogHTTPHandler(logging.handlers.HTTPHandler):
    """用于发送日志"""

    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.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_}
        return record_msg


class LocustLogger():
    """日志记录"""

    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
        self.LocutHttpHandler = None

    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.localtime                                      # 时间转换
        self.handler.setFormatter(formatter)  # 格式加载到handler
        log_host = PERF_HOST.replace('https://', '').replace('http://', '')
        if not all([log_host, REPORT_LOCUST_LOGS_URL, LOGGING_SECURE]):
            self.LocutHttpHandler = LocustLogHTTPHandler(log_host, url=REPORT_LOCUST_LOGS_URL, method="POST", secure=LOGGING_SECURE)
            self.LocutHttpHandler.setFormatter(formatter)

    def create_logger(self):
        """建立Logger"""
        self.success_logger = logging.getLogger('Success')
        self.success_logger.propagate = False
        self.success_logger.addHandler(self.handler)

        self.failure_logger = logging.getLogger('Failure')
        self.failure_logger.propagate = False
        self.failure_logger.addHandler(self.handler)

        self.failure_logger = logging.getLogger('stderr')
        self.failure_logger.propagate = False
        self.failure_logger.addHandler(self.handler)

        self.requests_logger = logging.getLogger('requests')
        self.requests_logger.propagate = False
        self.requests_logger.addHandler(self.handler)

        if self.LocutHttpHandler:
            self.add_httphandler()

    def add_httphandler(self):
        self.success_logger.addHandler(self.LocutHttpHandler)
        self.failure_logger.addHandler(self.LocutHttpHandler)
        self.requests_logger.addHandler(self.LocutHttpHandler)

    def success_request(self, request_type, name, response_time, response_length):
        # 成功日志输出格式加载到Logger中
        msg = ' | '.join([str(request_type), name, str(response_time), str(response_length)])
        self.success_logger.info(msg)

    def failure_request(self, request_type, name, response_time, exception):
        msg = ' | '.join([str(request_type), name, str(response_time), str(exception)])
        self.failure_logger.info(msg)

    def execpt_error(self, locust_instance, exception, tb, *args, **kwargs):
        stderr_logger = logging.getLogger("stderr")
        stderr_logger.exception(exception)
        stderr_logger.exception('-' * 12)

    def get_locust_Hook(self):
        """钩子挂载到Locust中"""
        events.request_success += self.success_request
        events.request_failure += self.failure_request
        events.locust_error += self.execpt_error

    def get_locust_success_Hook(self):
        events.request_success += self.success_request

    def get_locust_failure_Hook(self):
        events.request_failure += self.failure_request

    def get_locust_error_Hook(self):
        events.locust_error += self.execpt_error

    def get_requests_log(self, method, path, requests, response):
        msg = ' | '.join([method, path, '请求数据: {}'.format(str(requests)), '返回数据: {}'.format(str(response))])
        self.requests_logger.info(msg)
        if self.LocutHttpHandler:
            self.LocutHttpHandler.emit(record=msg)  # 发送日志


# ------------------------------------------------------------------------
# 以上为封装好的Log日志输出
# 在并发时带入log日志输出为本地文件存放,代码如下:
from locust import TaskSet, task, HttpLocust


class UserBehaviorSet(TaskSet):
    def on_start(self):
        self.logger = LocustLogger(filePath='./', fileName='test.logs')
        self.logger.get_locust_Hook()

    @task(1)
    def test(self):
        headers = {
            'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
            'Cache-Control': "no-cache",
            'Postman-Token': "9889c0b4-b91c-4b23-a713-cae4d60e623a"
        }
        resp = self.client.get("/LeonTom/article/details/102842207", headers=headers, verify=False)
        # 记录请求日志并发送到指定服务
        self.logger.get_requests_log(method='GET', path='/', requests={}, response=resp.text)


class WebsiteUser(HttpLocust):
    task_set = UserBehaviorSet
    min_wait = 3000
    max_wait = 5000


if __name__ == '__main__':
    import os
    os.system("locust -f ./locust_log.py --host=https://blog.csdn.net")

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值