def test__logs_messages(self): events = [] namespace = factory.make_name("namespace") legacy_logger = LegacyLogger(namespace, self, events.append) message = factory.make_name("message") keywords = { factory.make_name("key"): factory.make_name("value") for _ in range(3) } legacy_logger.msg(message, **keywords) expected = { 'log_format': Equals('{_message_0}'), 'log_level': Equals(logger.LogLevel.info), 'log_logger': Is(legacy_logger), 'log_namespace': Equals(namespace), 'log_source': Is(self), 'log_time': IsInstance(float), '_message_0': Equals(message), } expected.update( {key: Equals(value) for key, value in keywords.items()}) self.assertThat(events, HasLength(1)) self.assertThat(events[0], MatchesDict(expected)) self.assertThat( logger.formatEventAsClassicLogText(events[0], formatTimeStatic), Equals("<when> [%s#info] %s\n" % (namespace, message)))
def test__logs_errors(self): events = [] namespace = factory.make_name("namespace") legacy_logger = LegacyLogger(namespace, self, events.append) message = factory.make_name("message") exception_type = factory.make_exception_type() keywords = { factory.make_name("key"): factory.make_name("value") for _ in range(3) } try: raise exception_type() except exception_type: legacy_logger.err(None, message, **keywords) expected = { 'log_failure': MatchesAll( IsInstance(Failure), AfterPreprocessing( (lambda failure: failure.value), IsInstance(exception_type), ), ), 'log_format': Equals('{_why}'), 'log_level': Equals(logger.LogLevel.critical), 'log_logger': Is(legacy_logger), 'log_namespace': Equals(namespace), 'log_source': Is(self), 'log_time': IsInstance(float), '_why': Equals(message), } expected.update( {key: Equals(value) for key, value in keywords.items()}) self.assertThat(events, HasLength(1)) self.assertThat(events[0], MatchesDict(expected)) # Twisted 16.6.0 (see issue #8858) now includes a traceback, # so we only match on the beginning of the string. self.assertThat( logger.formatEventAsClassicLogText(events[0], formatTimeStatic), StartsWith("<when> [%s#critical] %s\n" % (namespace, message)))
def configure_tftp_logging(verbosity: int, mode: LoggingMode): """Configure logging in `python-tx-tftp`. This is done by monkey-patching `LegacyLogger`s into three of its modules. Each of these is connected to a custom observer, `observe_tftp`, that has an opportunity to filter or modify log events before passing them on to the global log publisher. :param verbosity: See `get_logging_level`. :param mode: The mode in which to configure logging. See `LoggingMode`. """ try: from tftp import bootstrap, protocol, session except ImportError: # python-tx-tftp not installed; nothing to be done. return for module in (bootstrap, protocol, session): LegacyLogger.install(module, observer=observe_tftp)
def test__logs_multiple_messages(self): events = [] legacy_logger = LegacyLogger(observer=events.append) messages = [ factory.make_name("message"), factory.make_name("message"), factory.make_name("message"), ] legacy_logger.msg(*messages) expected = { "_message_0": messages[0], "_message_1": messages[1], "_message_2": messages[2], "log_format": "{_message_0} {_message_1} {_message_2}", } self.assertThat(events, HasLength(1)) self.assertThat(events[0], ContainsDictByEquality(expected)) self.assertThat( logger.formatEventAsClassicLogText(events[0], formatTimeStatic), Equals("<when> [%s#info] %s\n" % (__name__, " ".join(messages))))