def __init__(self, config: Config) -> None: """Creates a new plugin to capture log messages. The formatter can be safely shared across all handlers so create a single one for the entire test session here. """ self._config = config self.print_logs = get_option_ini(config, "log_print") if not self.print_logs: from _pytest.warnings import _issue_warning_captured from _pytest.deprecated import NO_PRINT_LOGS _issue_warning_captured(NO_PRINT_LOGS, self._config.hook, stacklevel=2) self.formatter = self._create_formatter( get_option_ini(config, "log_format"), get_option_ini(config, "log_date_format"), get_option_ini(config, "log_auto_indent"), ) self.log_level = get_log_level_for_setting(config, "log_level") self.log_file_level = get_log_level_for_setting( config, "log_file_level") self.log_file_format = get_option_ini(config, "log_file_format", "log_format") self.log_file_date_format = get_option_ini(config, "log_file_date_format", "log_date_format") self.log_file_formatter = logging.Formatter( self.log_file_format, datefmt=self.log_file_date_format) log_file = get_option_ini(config, "log_file") if log_file: self.log_file_handler = logging.FileHandler( log_file, mode="w", encoding="UTF-8") # type: Optional[logging.FileHandler] self.log_file_handler.setFormatter(self.log_file_formatter) else: self.log_file_handler = None self.log_cli_handler = None self.live_logs_context = lambda: nullcontext() # Note that the lambda for the live_logs_context is needed because # live_logs_context can otherwise not be entered multiple times due # to limitations of contextlib.contextmanager. if self._log_cli_enabled(): self._setup_cli_logging()
def emit(self, record: logging.LogRecord) -> None: ctx_manager = (self.capture_manager.global_and_fixture_disabled() if self.capture_manager else nullcontext()) with ctx_manager: if not self._first_record_emitted: self.stream.write("\n") self._first_record_emitted = True elif self._when in ("teardown", "finish"): if not self._test_outcome_written: self._test_outcome_written = True self.stream.write("\n") if not self._section_name_shown and self._when: self.stream.section("live log " + self._when, sep="-", bold=True) self._section_name_shown = True super().emit(record)
def __init__(self, config): """Creates a new plugin to capture log messages. The formatter can be safely shared across all handlers so create a single one for the entire test session here. """ self._config = config self.print_logs = get_option_ini(config, "log_print") self.formatter = self._create_formatter( get_option_ini(config, "log_format"), get_option_ini(config, "log_date_format"), get_option_ini(config, "log_auto_indent"), ) self.log_level = get_actual_log_level(config, "log_level") self.log_file_level = get_actual_log_level(config, "log_file_level") self.log_file_format = get_option_ini(config, "log_file_format", "log_format") self.log_file_date_format = get_option_ini(config, "log_file_date_format", "log_date_format") self.log_file_formatter = logging.Formatter( self.log_file_format, datefmt=self.log_file_date_format) log_file = get_option_ini(config, "log_file") if log_file: self.log_file_handler = logging.FileHandler(log_file, mode="w", encoding="UTF-8") self.log_file_handler.setFormatter(self.log_file_formatter) else: self.log_file_handler = None self.log_cli_handler = None self.live_logs_context = lambda: nullcontext() # Note that the lambda for the live_logs_context is needed because # live_logs_context can otherwise not be entered multiple times due # to limitations of contextlib.contextmanager. if self._log_cli_enabled(): self._setup_cli_logging()