• python结合logging模块编写打印日志的装饰器+python结合time模块编写计算时间装饰器【杭州多测师】【杭州多测师_王sir】


    import datetime
    import logging
    import requests
    
    #获取日志记录器、配置日志等级
    logger = logging.getLogger(__name__)
    logger.setLevel("DEBUG")
    
    #默认日志格式
    formatter = logging.Formatter("%(asctime)s - [%(levelname)s] - %(message)s")
    #输出到控制台的handler
    chlr = logging.StreamHandler()
    #配置默认日志格式
    chlr.setFormatter(formatter)
    #日志记录器增加此handler
    logger.addHandler(chlr)
    
    def log(func):
        """
        日志装饰器、简单记录函数的日志
        :param func: 函数
        :return:
        """
        def inner(*args,**kwargs):
            timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            res = func(*args,**kwargs)
            logger.debug(f"func: {func.__name__}{args}->{res}")
            return res
        return inner
    
    @log
    def cms_login(userAccount=None,loginPwd=None):
        url = "http://cms.duoceshi.cn/cms/manage/loginJump.do?userAccount="+userAccount+"&"+"loginPwd"+"="+str(loginPwd)
        response = requests.get(url)
        return (response.json())
    
    cms_login("admin",123456)
    import logging
    from logging import handlers
    from typing import Text
    import colorlog
    from common.setting import ConfigHandler
    
    
    class LogHandler:
        """ 日志打印封装"""
        # 日志级别关系映射
        level_relations = {
            'debug': logging.DEBUG,
            'info': logging.INFO,
            'warning': logging.WARNING,
            'error': logging.ERROR,
            'critical': logging.CRITICAL
        }
    
        def __init__(
                self,
                filename: Text,
                level: Text = "info",
                when: Text = "D",
                fmt: Text = "%(levelname)-8s%(asctime)s%(name)s:%(filename)s:%(lineno)d %(message)s"
        ):
            self.logger = logging.getLogger(filename)
    
            formatter = self.log_color()
    
            # 设置日志格式
            format_str = logging.Formatter(fmt)
            # 设置日志级别
            self.logger.setLevel(self.level_relations.get(level))
            # 往屏幕上输出
            screen_output = logging.StreamHandler()
            # 设置屏幕上显示的格式
            screen_output.setFormatter(formatter)
            # 往文件里写入#指定间隔时间自动生成文件的处理器
            time_rotating = handlers.TimedRotatingFileHandler(
                filename=filename,
                when=when,
                backupCount=3,
                encoding='utf-8'
            )
            # 设置文件里写入的格式
            time_rotating.setFormatter(format_str)
            # 把对象加到logger里
            self.logger.addHandler(screen_output)
            self.logger.addHandler(time_rotating)
            self.log_path = ConfigHandler.log_path
    
        @classmethod
        def log_color(cls):
            """ 设置日志颜色 """
            log_colors_config = {
                'DEBUG': 'cyan',
                'INFO': 'green',
                'WARNING': 'yellow',
                'ERROR': 'red',
                'CRITICAL': 'red',
            }
    
            formatter = colorlog.ColoredFormatter(
                '%(log_color)s[%(asctime)s] [%(name)s] [%(levelname)s]: %(message)s',
                log_colors=log_colors_config
            )
            return formatter
    
    
    INFO = LogHandler(ConfigHandler.info_log_path, level='info')
    ERROR = LogHandler(ConfigHandler.error_log_path, level='error')
    WARNING = LogHandler(ConfigHandler.warning_log_path, level='warning')
    
    if __name__ == '__main__':
        ERROR.logger.error("测试")
    """
    日志装饰器,控制程序日志输入,默认为 True
    如设置 False,则程序不会打印日志
    """
    from functools import wraps
    from utils.logging_tool.log_control import INFO, ERROR
    
    
    def log_decorator(switch: bool):
        """
        封装日志装饰器, 打印请求信息
        :param switch: 定义日志开关
        :return:
        """
        def decorator(func):
            @wraps(func)
            def swapper(*args, **kwargs):
    
                # 判断日志为开启状态,才打印日志
                res = func(*args, **kwargs)
                # 判断日志开关为开启状态
                if switch:
                    _log_msg = f"\n======================================================\n" \
                                   f"用例标题: {res['detail']}\n" \
                                   f"请求路径: {res['url']}\n" \
                                   f"请求方式: {res['method']}\n" \
                                   f"请求头:   {res['headers']}\n" \
                                   f"请求内容: {res['request_body']}\n" \
                                   f"接口响应内容: {res['response_data']}\n" \
                                   f"接口响应时长: {res['res_time']} ms\n" \
                                   f"Http状态码: {res['status_code']}\n" \
                                   "====================================================="
                    _is_run = res['is_run']
                    # 判断正常打印的日志,控制台输出绿色
                    if _is_run in (True, None) and res['status_code'] == 200:
                        INFO.logger.info(_log_msg)
                    else:
                        # 失败的用例,控制台打印红色
                        ERROR.logger.error(_log_msg)
                return res
            return swapper
        return decorator
    """
    统计请求运行时长装饰器,如请求响应时间超时
    程序中会输入红色日志,提示时间 http 请求超时,默认时长为 3000ms
    """
    from utils.logging_tool.log_control import ERROR
    
    
    def execution_duration(number: int):
        """
        封装统计函数执行时间装饰器
        :param number: 函数预计运行时长
        :return:
        """
    
        def decorator(func):
            def swapper(*args, **kwargs):
                res = func(*args, **kwargs)
                run_time = res['res_time']
                # 计算时间戳毫米级别,如果时间大于number,则打印 函数名称 和运行时间
                if run_time > number:
                    ERROR.logger.error(
                        "\n==============================================\n"
                        "测试用例执行时间较长,请关注.\n"
                        "函数运行时间: %s ms\n"
                        "测试用例相关数据: %s\n"
                        "================================================="
                        , run_time, res)
                return res
            return swapper
        return decorator
    import logging
    import os
    
    from testlib.common.MyConfigParser import conf
    from testlib.common.pathOperation import LOG_DIR
    
    
    # 获取配置信息
    level = conf.get_str("logging", "level")
    f_level = conf.get_str("logging", "f_level")
    s_level = conf.get_str("logging", "s_level")
    filename = conf.get_str("logging", "filename")
    # 获取日志文件路径
    file_path = os.path.join(LOG_DIR, filename)
    
    
    class Log:
    
        @staticmethod
        def log_collection():
            """日志收集器"""
            # 创建日志收集器
            log = logging.getLogger()
            # 设置日志收集器等级
            log.setLevel(level)
            """控制台输出"""
            # 添加输出渠道
            sh = logging.StreamHandler()
            # 设置输出等级
            sh.setLevel(s_level)
            # 将输出渠道绑定在日志收集器上
            log.addHandler(sh)
            """日志输出"""
            # 添加输出渠道
            fh = logging.FileHandler(file_path, encoding="utf8")
            # 设置输出等级
            fh.setLevel(f_level)
            # 设置日志输出格式
            formatter = logging.Formatter('%(asctime)s-%(levelname)s: %(message)s')
            # 输出渠道和输出格式绑定
            fh.setFormatter(formatter)
            # 输出渠道和日志收集器绑定
            log.addHandler(fh)
            return log
    
    log = Log.log_collection()
    
    
    if __name__ == '__main__':
        log = Log.log_collection()
        res= log.info("DEBUE")
        print(res)
    # coding:utf-8
    import logging,time,os
    # 这个是日志保存本地的路径
    root_path = os.path.dirname(__file__)
    app_path = os.path.join(root_path, "resultReport/").replace("\\", "/")
    log_path = app_path
    
    class Log:
        def __init__(self):
            # 文件的命名
            self.logname = os.path.join(log_path, '%s.log'%time.strftime('%Y_%m_%d'))
            self.logger = logging.getLogger()
            self.logger.setLevel(logging.DEBUG)
            # 日志输出格式
            self.formatter = logging.Formatter('[%(asctime)s] - %(filename)s[line:%(lineno)d] - fuc:%(funcName)s- %(levelname)s: %(message)s')
        def __console(self, level, message):
            # 创建一个FileHandler,用于写到本地
            fh = logging.FileHandler(self.logname, 'a')  # 追加模式
            fh.setLevel(logging.DEBUG)
            fh.setFormatter(self.formatter)
            self.logger.addHandler(fh)
    
            # 创建一个StreamHandler,用于输出到控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.DEBUG)
            ch.setFormatter(self.formatter)
            self.logger.addHandler(ch)
    
            if level == 'info':
                self.logger.info(message)
            elif level == 'debug':
                self.logger.debug(message)
            elif level == 'warning':
                self.logger.warning(message)
            elif level == 'error':
                self.logger.error(message)
            # 这两行代码是为了避免日志输出重复问题
            self.logger.removeHandler(ch)
            self.logger.removeHandler(fh)
            # 关闭打开的文件
            fh.close()
    
        def debug(self, message):
            self.__console('debug', message)
    
        def info(self, message):
            self.__console('info', message)
    
        def warning(self, message):
            self.__console('warning', message)
    
        def error(self, message):
            self.__console('error', message)
    
    if __name__ == "__main__":
       log = Log()
       log.info("---测试开始----")
       log.info("输入密码")
       log.warning("----测试结束----")
    import logging, time, os
    
    BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
    # 定义日志文件路径
    LOG_PATH = os.path.join(BASE_PATH, "log")
    if not os.path.exists(LOG_PATH):
        os.mkdir(LOG_PATH)
    
    
    class Logger():
    
        def __init__(self):
            self.logname = os.path.join(LOG_PATH, "{}.log".format(time.strftime("%Y%m%d")))
            self.logger = logging.getLogger("log")
            self.logger.setLevel(logging.DEBUG)
    
            self.formater = logging.Formatter(
                '[%(asctime)s][%(filename)s %(lineno)d][%(levelname)s]: %(message)s')
    
            self.filelogger = logging.FileHandler(self.logname, mode='a', encoding="UTF-8")
            self.console = logging.StreamHandler()
            self.console.setLevel(logging.DEBUG)
            self.filelogger.setLevel(logging.DEBUG)
            self.filelogger.setFormatter(self.formater)
            self.console.setFormatter(self.formater)
            self.logger.addHandler(self.filelogger)
            self.logger.addHandler(self.console)
    
    
    logger = Logger().logger
    
    if __name__ == '__main__':
        logger.info("---测试开始---")
        logger.debug("---测试结束---")
  • 相关阅读:
    Bit Calculation
    Create ArcGIS maps in Power BI Desktop
    Power Apps visual for Power BI
    Create Power BI visuals by using Python
    运行 R 脚本
    Introduction to ASP.NET Core Blazor
    Tips and tricks for color formatting in Power BI
    Sharepoint Create, Update, and Delete List Items
    Power BI Office Online Server
    jQuery Organization Chart
  • 原文地址:https://www.cnblogs.com/xiaoshubass/p/16839044.html
Copyright © 2020-2023  润新知