xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/isctest/log/basic.py (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
2#
3# SPDX-License-Identifier: MPL-2.0
4#
5# This Source Code Form is subject to the terms of the Mozilla Public
6# License, v. 2.0.  If a copy of the MPL was not distributed with this
7# file, you can obtain one at https://mozilla.org/MPL/2.0/.
8#
9# See the COPYRIGHT file distributed with this work for additional
10# information regarding copyright ownership.
11
12import logging
13from pathlib import Path
14from typing import Dict, Optional
15
16
17CONFTEST_LOGGER = logging.getLogger("conftest")
18LOG_FORMAT = "%(asctime)s %(levelname)7s:%(name)s  %(message)s"
19
20LOGGERS = {
21    "conftest": None,
22    "module": None,
23    "test": None,
24}  # type: Dict[str, Optional[logging.Logger]]
25
26
27def init_conftest_logger():
28    """
29    This initializes the conftest logger which is used for pytest setup
30    and configuration before tests are executed -- aka any logging in this
31    file that is _not_ module-specific.
32    """
33    LOGGERS["conftest"] = logging.getLogger("conftest")
34    LOGGERS["conftest"].setLevel(logging.DEBUG)
35    file_handler = logging.FileHandler("pytest.conftest.log.txt")
36    file_handler.setFormatter(logging.Formatter(LOG_FORMAT))
37    LOGGERS["conftest"].addHandler(file_handler)
38
39
40def avoid_duplicated_logs():
41    """
42    Remove direct root logger output to file descriptors.
43    This default is causing duplicates because all our messages go through
44    regular logging as well and are thus displayed twice.
45    """
46    todel = []
47    for handler in logging.root.handlers:
48        if handler.__class__ == logging.StreamHandler:
49            # Beware: As for pytest 7.2.2, LiveLogging and LogCapture
50            # handlers inherit from logging.StreamHandler
51            todel.append(handler)
52    for handler in todel:
53        logging.root.handlers.remove(handler)
54
55
56init_conftest_logger()
57avoid_duplicated_logs()
58
59
60def init_module_logger(system_test_name: str, testdir: Path):
61    logger = logging.getLogger(system_test_name)
62    logger.handlers.clear()
63    logger.setLevel(logging.DEBUG)
64    handler = logging.FileHandler(testdir / "pytest.log.txt", mode="w")
65    handler.setFormatter(logging.Formatter(LOG_FORMAT))
66    logger.addHandler(handler)
67    LOGGERS["module"] = logger
68
69
70def deinit_module_logger():
71    for handler in LOGGERS["module"].handlers:
72        handler.flush()
73        handler.close()
74    LOGGERS["module"] = None
75
76
77def init_test_logger(system_test_name: str, test_name: str):
78    LOGGERS["test"] = logging.getLogger(f"{system_test_name}.{test_name}")
79
80
81def deinit_test_logger():
82    LOGGERS["test"] = None
83
84
85def log(lvl: int, msg: str, *args, **kwargs):
86    """Log message with the most-specific logger currently available."""
87    logger = LOGGERS["test"]
88    if logger is None:
89        logger = LOGGERS["module"]
90    if logger is None:
91        logger = LOGGERS["conftest"]
92    assert logger is not None
93    logger.log(lvl, msg, *args, **kwargs)
94
95
96def debug(msg: str, *args, **kwargs):
97    log(logging.DEBUG, msg, *args, **kwargs)
98
99
100def info(msg: str, *args, **kwargs):
101    log(logging.INFO, msg, *args, **kwargs)
102
103
104def warning(msg: str, *args, **kwargs):
105    log(logging.WARNING, msg, *args, **kwargs)
106
107
108def error(msg: str, *args, **kwargs):
109    log(logging.ERROR, msg, *args, **kwargs)
110
111
112def critical(msg: str, *args, **kwargs):
113    log(logging.CRITICAL, msg, *args, **kwargs)
114