使用带有机器人框架的 python 根记录器

Posted

技术标签:

【中文标题】使用带有机器人框架的 python 根记录器【英文标题】:Using a python root logger with robot framework 【发布时间】:2018-11-23 09:55:51 【问题描述】:

我正在使用 Robot Framework 运行我制作的 python 脚本,当我尝试通过自定义根记录器进行日志记录时遇到问题,我一直使用该记录器在所需的格式。如果我不使用根记录器,RF 会很好地输出我的日志,但如果我使用我的根记录器,那么 RF 不会输出,并且不会输出由我的 python 脚本完成的日志记录。这是我的代码:

logger.py:

import logging.config
import os

_WORKSPACE = os.getenv(
    'WORKSPACE',
    default=R'C:\opt\ci\jenkins\workspace\Killer_Automation_Robot'
    )

def _get_named_logging_config(test_name):
    named_logging_config = dict(
        version = 1,
        disable_existing_loggers = False,
        formatters = 
            'file': 
                'format': '[%(asctime)-s] %(filename)-30s:%(lineno)-3d %(levelname)-8s - %(message)-s'
            ,
            'console': 
                'format': '[%(asctime)-s] %(filename)-30s:%(lineno)-3d %(levelname)-8s - %(message)-s'
            
        ,
        handlers = 
            'default': 
                'level': 'INFO',
                #'level': 'DEBUG',
                'formatter': 'console',
                'class': 'logging.StreamHandler',
            ,
            'file': 
                'level': 'DEBUG',
                'formatter': 'file',
                'class': 'logging.FileHandler',
                'filename': ''.join([
                    _WORKSPACE,
                    R'\!s.log'.format(
                        test_name
                        ),
                    ]),
                'mode': 'w',
                'encoding': 'utf-8'
            ,
        ,
        loggers = 
            '': 
                'handlers': ['default','file'],
                'level': 'DEBUG',
                'propagate': True
            ,
            'hammer': 
                'handlers': ['default'],
                'level': 'WARN',
                'propagate': False
            ,
        ,
        root = 
            'handlers': ['default','file'],
            'level': 'DEBUG',
        ,
    )
    return named_logging_config


def instantiate_logger(name):
    named_logging_config = _get_named_logging_config(
        ''.join([
            'robot_',
            name,
            ])
        )
    return named_logging_config

def make_logging():
    named_logging_config = instantiate_logger('do_math')
    logging.config.dictConfig(named_logging_config)
    log = logging.getLogger('')

do_something.robot

*** Settings ***
Library    do_math

*** Test Cases ***
Logging test
    do logging

do_something.py:

import logger
import logging

logger.make_logging()
log = logging.getLogger(__name__)
log.info('Starting !s'.format('Install Software Test'))

class do_math(object):

    def __init__(self):
        log.info('Starting !s'.format('do math'))

    def do_logging(self):
        log.info('this log worked')
        self.do_math1()

    def do_math1(self):
        log.warning('this is a warning')

当我使用 do_something.py 运行它时,没有任何记录。但是,当我自己运行 do_something.py 时,我会得到所有日志的预期输出。此外,如果我删除 python 文件中实例化根记录器的 logger.make_logging() 行并运行 RF 文件,RF 会输出所有日志,但显然不是所需的格式。

【问题讨论】:

【参考方案1】:

想出了一些解决方法。我所要做的就是在我的 logger.py 中添加一个函数 attach_to_logger() 来获取并返回一个全局日志变量,然后在任何登录我的 do_something.py 的方法中调用该函数.感觉有点hack-y,但对我来说效果很好。

logger.py:

#attach_to_logger() has been added
def instantiate_logger(name):
    named_logging_config = _get_named_logging_config(
        ''.join([
            'robot_',
            name,
            ])
        )
    return named_logging_config

def make_logging():
    named_logging_config = instantiate_logger('do_math')
    logging.config.dictConfig(named_logging_config)
    log = logging.getLogger('')

def attach_to_logger(name):
    global log
    make_logging()
    log = logging.getLogger(name)

然后我在模块中要做的就是在需要进行任何日志记录时调用 attach_to_logger()。

do_something.py:

import logger
import logging
class do_math(object):

    def do_logging(self):  
        log = logger.attach_to_logger(__name__)
        log.info('Starting !s'.format('Do Something test!'))
        log.info('this log worked')
        self.do_math1()

    def do_math1(self):
        log = logger.attach_to_logger(__name__)
        log.warning('this is a warning')

【讨论】:

【参考方案2】:

我也遇到过同样的问题,我不想让我们的测试库依赖于机器人记录器,而是为机器人框架定义一个日志处理程序。

幸运的是有a logging Handler already implemented in robot。因此,只需在您的 dict 中引用它们(对于dictConfig())就可以将 py 标准日志记录转发到 RF 的 log.html。这是一个要加载的示例字典:


    "version": 1,
    "disable_existing_loggers": false,
    "formatters": 
        "default": 
            "format": "[%(asctime)s] %(levelname)-8s [%(name)s] %(message)s"
        ,
        "nameAndMessage": 
            "format": "[%(name)s] %(message)s"
        
    ,
    "handlers": 
        "console": 
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "default"
        ,
        "file": 
            "formatter": "default",
            "class": "logging.FileHandler",
            "filename": "robot_pcc_atom_dev.log"
        ,
        "robotHandler": 
            "formatter": "nameAndMessage",
            "class": "robot.output.pyloggingconf.RobotHandler"
        
    ,
    "loggers": 
        "": 
            "handlers": [
                "file", "robotHandler"
            ],
            "level": "DEBUG"
        ,
        "asyncio": 
            "level": "WARN"
        ,
        "aiohttp": 
            "level": "WARN"
        
    

编辑 这样做你很快就会发现RobotHandler 不支持格式化程序(在上面的示例中名为nameAndMessage)。

问题 + 修复您可以在这里找到:https://github.com/robotframework/robotframework/issues/3208

Edit2:示例代码改进 我制作了一个名为 nameAndMessage 的新格式化程序,因为在机器人 log.html 输出中已经集成了时间和日志级别。

【讨论】:

以上是关于使用带有机器人框架的 python 根记录器的主要内容,如果未能解决你的问题,请参考以下文章

如何让机器人框架记录在 python 中调用的 python 方法?

当配置 org.hibernate.SQL 记录器时,Logback 显示带有根级别 INFO 的 DEBUG 输出

使用实体框架从聚合根中删除子记录

Spring boot - 如何获取 WARN 的框架日志记录和 DEBUG 的应用程序日志记录

确定根记录器是不是在 Python 中设置为 DEBUG 级别?

在 python 中配置根记录器