首页 > 解决方案 > 使用带有机器人框架的 python 根记录器

问题描述

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

记录器.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 文件中实例化根记录器并运行 RF 文件的logger.make_logging()行,RF 会输出所有日志,但显然不是所需的格式。

标签: pythonpython-3.xloggingautomationrobotframework

解决方案


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

记录器.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')

推荐阅读