Logs are being printed twice when using logger in pytest. [I check all the stackoverflow links and non of the suggestions fixed my issue]

Viewed 338

Logs are being printed twice when using logger in pytest. I am using a custom plugging to collect all the logs from each test and log them in teardown. I am running the tests in parallel so I need this so that all test outputs doesnt get mixed up in console.

class OutputHandler(object):

    def __init__(self, log_to_console=True):
        self.exceptions = {}
        self.log_to_console = log_to_console
        self.log_formatter = logging.Formatter(
            fmt='%(asctime)s %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S')

    def get_header(self, text):
        return "\n" + " {} ".format(text).center(60, "-")

    def get_subheader(self, text):
        return "\n" + " {} ".format(text).center(30, "-")

    def get_logger(self, file_path):
        logger = logging.getLogger(file_path)
        logging.propagate = False
        logger.setLevel(logging.INFO)

        if not logger.handlers:
            if self.log_to_console:
                stream_handler = logging.StreamHandler()
                stream_handler.setFormatter(self.log_formatter)
                logger.addHandler(stream_handler)

        return logger

    def pytest_runtest_logreport(self, report):
        **print(report.when)**
        # Maintain all exceptions so we can report them all at once.
        if report.outcome == "failed":
            if report.nodeid not in self.exceptions:
                self.exceptions[report.nodeid] = {}
            self.exceptions[report.nodeid][report.when] = str(report.longrepr)

        # Don't print anything until all output is done being captured in the final phase
        if report.when == "teardown":
            logs_directory = shared_resources.get_logs_directory()
            file_path = os.path.abspath(os.path.join(logs_directory, report.location[-1]))

            logger = self.get_logger(file_path)
            **print("I am a print")
            logger.info("I am an log")**
            logger.info("\n{}".format(report.nodeid))

            for report_section_name, report_section_content in report.sections:
                logger.info(report_section_name)
                logger.info(report_section_content)

            if report.nodeid in self.exceptions:
                logger.info(self.get_header("Exceptions"))
                for k in self.exceptions[report.nodeid]:
                    logger.info(self.get_subheader(k))
                    logger.info(self.exceptions[report.nodeid][k])

            logger.info("\n\n")


def pytest_addoption(parser):
    group = parser.getgroup(constants.plugin_group_name)


def pytest_configure(config):
    log_to_console = not config.getvalue("--quiet")

    if log_to_console:
        config.pluginmanager.register(
            OutputHandler(log_to_console=log_to_console),
            "output_handler")

If I add a print statement, it will be outputted to console only once in teardown. But If use logger is used, it get printed twice

output:

[Edited the output to remove report details]. But I added custom logs and print statements in above code for which output looks like

call I am an log teardown I am a print I am an log

0 Answers
Related