def configure(self, logger: logging.Logger, verbosity: int = 0) -> int: """ Add all configured handlers to the supplied logger. If verbosity > 0 then make sure we have a console logger and force the level of the console logger based on the verbosity. :param logger: The logger to add the handlers to :param verbosity: The verbosity level given as command line argument :return: The lowest log level that is going to be handled """ # Remove any previously configured loggers, in case we are re-configuring # We are deleting, so copy the list first for handler in list(logger.handlers): logger.removeHandler(handler) # Add the handlers, keeping track of console loggers and saving the one with the "best" level. console = None for handler_factory in self.handlers: handler = handler_factory() logger.addHandler(handler) if isinstance(handler_factory, ConsoleHandlerFactory): console = handler # Set according to verbosity set_verbosity_logger(logger, verbosity, console) # Find the lowest log level lowest_level = logging.CRITICAL for handler in logger.handlers: if handler.level < lowest_level: lowest_level = handler.level # Return the lowest log level we want, so that we can filter lower priority messages earlier (where appropriate) return lowest_level
def configure(self, logger: logging.Logger, verbosity: int = 0) -> int: """ Add all configured handlers to the supplied logger. If verbosity > 0 then make sure we have a console logger and force the level of the console logger based on the verbosity. :param logger: The logger to add the handlers to :param verbosity: The verbosity level given as command line argument :return: The lowest log level that is going to be handled """ # Remove any previously configured loggers, in case we are re-configuring # We are deleting, so copy the list first for handler in list(logger.handlers): logger.removeHandler(handler) # Add the handlers, keeping track of console loggers and saving the one with the "best" level. console = None for handler_factory in self.handlers: handler = handler_factory() logger.addHandler(handler) if isinstance(handler_factory, ConsoleHandlerFactory): console = handler # Set according to verbosity set_verbosity_logger(logger, verbosity, console) # Find the lowest log level lowest_level = logging.CRITICAL for handler in logger.handlers: if handler.level < lowest_level: lowest_level = handler.level # Return the lowest log level we want, so that we can filter lower priority messages earlier (where appropriate) return lowest_level
def test_create_handler(self): tests = [ # Auto-created handler initially has level logging.ERROR (logging.ERROR, 0, logging.ERROR), (logging.ERROR, 1, logging.WARNING), (logging.ERROR, 2, logging.INFO), (logging.ERROR, 3, logging.DEBUG), (logging.ERROR, 4, DEBUG_HANDLING), (logging.ERROR, 5, DEBUG_PACKETS), ] for original_level, verbosity, expected_level in tests: name = "{} & {} = {}".format(original_level, verbosity, expected_level) with self.subTest(test=name): logger = logging.Logger(name=name, level=logging.ERROR) self.assertEqual(logger.level, logging.ERROR) set_verbosity_logger(logger=logger, verbosity=verbosity) self.assertEqual(logger.level, logging.NOTSET) handler = logger.handlers[0] self.assertEqual(handler.level, expected_level)
def main(args: Iterable[str]): """ The main program loop :param args: Command line arguments :return: The program exit code """ # Handle command line arguments args = handle_args(args) set_verbosity_logger(logger, args.verbosity) conn = DHCPKitControlClient(args.control_socket) output = conn.execute_command(args.command) for line in output: print(line) try: output = list(conn.execute_command('quit', optional=True)) if output: raise CommunicationError("Unexpected reply from server: {}".format(output[0])) except BrokenPipeError: pass
def main(args: Iterable[str]) -> int: """ The main program :param args: Command line arguments :return: The program exit code """ # Handle command line arguments options = handle_args(args) set_verbosity_logger(logger, options.verbosity) query = options.create(options) # Add ORO for relay data if options.relay_data: query.options.append(OptionRequestOption([OPTION_LQ_RELAY_DATA])) # Generate the outgoing message transaction_id = random.getrandbits(24).to_bytes(3, 'big') message_out = LeasequeryMessage(transaction_id, [ ClientIdOption(EnterpriseDUID(40208, b'LeaseQueryTester')), query ]) # Create client socket if options.tcp: client = TCPClientSocket(options) else: # Check permission if os.getuid() != 0: raise RuntimeError("This tool needs to be run as root") client = UDPClientSocket(options) destination = client.send(message_out) logger.info("Sent to {}:\n{}".format(destination, message_out)) # Wait for responses wait_for_multiple = options.server.is_multicast or options.tcp start = time.time() deadline = start + 3 received = 0 while time.time() < deadline: client.set_timeout(deadline - time.time()) try: sender, message_in = client.recv() received += 1 logger.info("Received from {}:\n{}".format(sender, message_in)) if options.tcp: # Check bulk leasequery ending if isinstance(message_in, LeasequeryReplyMessage): if not message_in.get_option_of_type(ClientDataOption): # Reply without data, the end break if isinstance(message_in, LeasequeryDoneMessage): break if not wait_for_multiple: break except socket.timeout: pass logger.info(gettext.ngettext("{} response received", "{} responses received", received).format(received))
def main(args: Iterable[str]) -> int: """ The main program :param args: Command line arguments :return: The program exit code """ # Handle command line arguments options = handle_args(args) set_verbosity_logger(logger, options.verbosity) query = options.create(options) # Add ORO for relay data if options.relay_data: query.options.append(OptionRequestOption([OPTION_LQ_RELAY_DATA])) # Generate the outgoing message transaction_id = random.getrandbits(24).to_bytes(3, 'big') message_out = LeasequeryMessage( transaction_id, [ClientIdOption(EnterpriseDUID(40208, b'LeaseQueryTester')), query]) # Create client socket if options.tcp: client = TCPClientSocket(options) else: # Check permission if os.getuid() != 0: raise RuntimeError("This tool needs to be run as root") client = UDPClientSocket(options) destination = client.send(message_out) logger.info("Sent to {}:\n{}".format(destination, message_out)) # Wait for responses wait_for_multiple = options.server.is_multicast or options.tcp start = time.time() deadline = start + 3 received = 0 while time.time() < deadline: client.set_timeout(deadline - time.time()) try: sender, message_in = client.recv() received += 1 logger.info("Received from {}:\n{}".format(sender, message_in)) if options.tcp: # Check bulk leasequery ending if isinstance(message_in, LeasequeryReplyMessage): if not message_in.get_option_of_type(ClientDataOption): # Reply without data, the end break if isinstance(message_in, LeasequeryDoneMessage): break if not wait_for_multiple: break except socket.timeout: pass logger.info( gettext.ngettext("{} response received", "{} responses received", received).format(received)) return 0
def test_existing_handler(self): tests = [ # Only critical errors to start with, so verbosity level increases output (logging.CRITICAL, 0, logging.CRITICAL), (logging.CRITICAL, 1, logging.WARNING), (logging.CRITICAL, 2, logging.INFO), (logging.CRITICAL, 3, logging.DEBUG), (logging.CRITICAL, 4, DEBUG_HANDLING), (logging.CRITICAL, 5, DEBUG_PACKETS), # Already showing errors, so verbosity 0 doesn't lower output (logging.ERROR, 0, logging.ERROR), (logging.ERROR, 1, logging.WARNING), (logging.ERROR, 2, logging.INFO), (logging.ERROR, 3, logging.DEBUG), (logging.ERROR, 4, DEBUG_HANDLING), (logging.ERROR, 5, DEBUG_PACKETS), # Already showing warnings, so verbosity 0 doesn't lower output (logging.WARNING, 0, logging.WARNING), (logging.WARNING, 1, logging.WARNING), (logging.WARNING, 2, logging.INFO), (logging.WARNING, 3, logging.DEBUG), (logging.WARNING, 4, DEBUG_HANDLING), (logging.WARNING, 5, DEBUG_PACKETS), # Already showing info, so verbosity 0 and 1 don't lower output (logging.INFO, 0, logging.INFO), (logging.INFO, 1, logging.INFO), (logging.INFO, 2, logging.INFO), (logging.INFO, 3, logging.DEBUG), (logging.INFO, 4, DEBUG_HANDLING), (logging.INFO, 5, DEBUG_PACKETS), # Already showing debug, so verbosity 0, 1 and 2 don't lower output (logging.DEBUG, 0, logging.DEBUG), (logging.DEBUG, 1, logging.DEBUG), (logging.DEBUG, 2, logging.DEBUG), (logging.DEBUG, 3, logging.DEBUG), (logging.DEBUG, 4, DEBUG_HANDLING), (logging.DEBUG, 5, DEBUG_PACKETS), # Already showing handling, so verbosity 0, 1, 2 and 3 don't lower output (DEBUG_HANDLING, 0, DEBUG_HANDLING), (DEBUG_HANDLING, 1, DEBUG_HANDLING), (DEBUG_HANDLING, 2, DEBUG_HANDLING), (DEBUG_HANDLING, 3, DEBUG_HANDLING), (DEBUG_HANDLING, 4, DEBUG_HANDLING), (DEBUG_HANDLING, 5, DEBUG_PACKETS), # Already showing packets, so verbosity 0, 1, 2, 3 and 4 don't lower output (DEBUG_PACKETS, 0, DEBUG_PACKETS), (DEBUG_PACKETS, 1, DEBUG_PACKETS), (DEBUG_PACKETS, 2, DEBUG_PACKETS), (DEBUG_PACKETS, 3, DEBUG_PACKETS), (DEBUG_PACKETS, 4, DEBUG_PACKETS), (DEBUG_PACKETS, 5, DEBUG_PACKETS), # Already showing everything, so not lowering output at all (logging.NOTSET, 0, logging.NOTSET), (logging.NOTSET, 1, logging.NOTSET), (logging.NOTSET, 2, logging.NOTSET), (logging.NOTSET, 3, logging.NOTSET), (logging.NOTSET, 4, logging.NOTSET), (logging.NOTSET, 5, logging.NOTSET), ] for original_level, verbosity, expected_level in tests: name = "{} & {} = {}".format(original_level, verbosity, expected_level) with self.subTest(test=name): logger = logging.Logger(name=name, level=logging.ERROR) handler = logging.Handler(level=original_level) logger.addHandler(handler) self.assertEqual(logger.level, logging.ERROR) self.assertEqual(handler.level, original_level) set_verbosity_logger(logger=logger, verbosity=verbosity, existing_console=handler) self.assertEqual(logger.level, logging.NOTSET) self.assertEqual(handler.level, expected_level)
def test_logger_level(self): logger = logging.Logger('test_logger_level', logging.ERROR) self.assertEqual(logger.level, logging.ERROR) set_verbosity_logger(logger=logger, verbosity=0) self.assertEqual(logger.level, logging.NOTSET)