From 0fa5b07d4bf4bc5d5aaad1de52b78058e472fe24 Mon Sep 17 00:00:00 2001 From: Hemna Date: Wed, 26 Feb 2025 17:41:40 -0500 Subject: [PATCH] Added new config to disable logging to console This patch adds a new config setting to the logging section that allows the user to disable logging to stdout. This is useful for terminal UI apps :) --- aprsd/cli_helper.py | 71 ++++++++++++++++++++++---------------------- aprsd/client/base.py | 25 +++++++++------- aprsd/conf/log.py | 5 ++++ aprsd/log/log.py | 21 +++++++------ 4 files changed, 67 insertions(+), 55 deletions(-) diff --git a/aprsd/cli_helper.py b/aprsd/cli_helper.py index b99a8b0..657e882 100644 --- a/aprsd/cli_helper.py +++ b/aprsd/cli_helper.py @@ -13,35 +13,35 @@ from aprsd.utils import trace CONF = cfg.CONF home = str(Path.home()) -DEFAULT_CONFIG_DIR = f"{home}/.config/aprsd/" -DEFAULT_SAVE_FILE = f"{home}/.config/aprsd/aprsd.p" -DEFAULT_CONFIG_FILE = f"{home}/.config/aprsd/aprsd.conf" +DEFAULT_CONFIG_DIR = f'{home}/.config/aprsd/' +DEFAULT_SAVE_FILE = f'{home}/.config/aprsd/aprsd.p' +DEFAULT_CONFIG_FILE = f'{home}/.config/aprsd/aprsd.conf' -F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +F = t.TypeVar('F', bound=t.Callable[..., t.Any]) common_options = [ click.option( - "--loglevel", - default="INFO", + '--loglevel', + default='INFO', show_default=True, type=click.Choice( - ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"], + ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'], case_sensitive=False, ), show_choices=True, - help="The log level to use for aprsd.log", + help='The log level to use for aprsd.log', ), click.option( - "-c", - "--config", - "config_file", + '-c', + '--config', + 'config_file', show_default=True, default=DEFAULT_CONFIG_FILE, - help="The aprsd config file to use for options.", + help='The aprsd config file to use for options.', ), click.option( - "--quiet", + '--quiet', is_flag=True, default=False, help="Don't log to stdout", @@ -59,7 +59,7 @@ class AliasedGroup(click.Group): """ def decorator(f): - aliases = kwargs.pop("aliases", []) + aliases = kwargs.pop('aliases', []) cmd = click.decorators.command(*args, **kwargs)(f) self.add_command(cmd) for alias in aliases: @@ -77,7 +77,7 @@ class AliasedGroup(click.Group): """ def decorator(f): - aliases = kwargs.pop("aliases", []) + aliases = kwargs.pop('aliases', []) cmd = click.decorators.group(*args, **kwargs)(f) self.add_command(cmd) for alias in aliases: @@ -101,36 +101,37 @@ def process_standard_options(f: F) -> F: ctx = args[0] ctx.ensure_object(dict) config_file_found = True - if kwargs["config_file"]: - default_config_files = [kwargs["config_file"]] + if kwargs['config_file']: + default_config_files = [kwargs['config_file']] else: default_config_files = None + try: CONF( [], - project="aprsd", + project='aprsd', version=aprsd.__version__, default_config_files=default_config_files, ) except cfg.ConfigFilesNotFoundError: config_file_found = False - ctx.obj["loglevel"] = kwargs["loglevel"] + ctx.obj['loglevel'] = kwargs['loglevel'] # ctx.obj["config_file"] = kwargs["config_file"] - ctx.obj["quiet"] = kwargs["quiet"] + ctx.obj['quiet'] = kwargs['quiet'] log.setup_logging( - ctx.obj["loglevel"], - ctx.obj["quiet"], + ctx.obj['loglevel'], + ctx.obj['quiet'], ) if CONF.trace_enabled: - trace.setup_tracing(["method", "api"]) + trace.setup_tracing(['method', 'api']) if not config_file_found: - LOG = logging.getLogger("APRSD") # noqa: N806 + LOG = logging.getLogger('APRSD') # noqa: N806 LOG.error("No config file found!! run 'aprsd sample-config'") - del kwargs["loglevel"] - del kwargs["config_file"] - del kwargs["quiet"] + del kwargs['loglevel'] + del kwargs['config_file'] + del kwargs['quiet'] return f(*args, **kwargs) return update_wrapper(t.cast(F, new_func), f) @@ -142,17 +143,17 @@ def process_standard_options_no_config(f: F) -> F: def new_func(*args, **kwargs): ctx = args[0] ctx.ensure_object(dict) - ctx.obj["loglevel"] = kwargs["loglevel"] - ctx.obj["config_file"] = kwargs["config_file"] - ctx.obj["quiet"] = kwargs["quiet"] + ctx.obj['loglevel'] = kwargs['loglevel'] + ctx.obj['config_file'] = kwargs['config_file'] + ctx.obj['quiet'] = kwargs['quiet'] log.setup_logging( - ctx.obj["loglevel"], - ctx.obj["quiet"], + ctx.obj['loglevel'], + ctx.obj['quiet'], ) - del kwargs["loglevel"] - del kwargs["config_file"] - del kwargs["quiet"] + del kwargs['loglevel'] + del kwargs['config_file'] + del kwargs['quiet'] return f(*args, **kwargs) return update_wrapper(t.cast(F, new_func), f) diff --git a/aprsd/client/base.py b/aprsd/client/base.py index 9bf5a14..d4d9b5a 100644 --- a/aprsd/client/base.py +++ b/aprsd/client/base.py @@ -9,7 +9,7 @@ from aprsd.packets import core from aprsd.utils import keepalive_collector CONF = cfg.CONF -LOG = logging.getLogger("APRSD") +LOG = logging.getLogger('APRSD') class APRSClient: @@ -20,8 +20,8 @@ class APRSClient: connected = False login_status = { - "success": False, - "message": None, + 'success': False, + 'message': None, } filter = None lock = threading.Lock() @@ -59,17 +59,20 @@ class APRSClient: @property def login_success(self): - return self.login_status.get("success", False) + return self.login_status.get('success', False) @property def login_failure(self): - return self.login_status["message"] + return self.login_status['message'] def set_filter(self, filter): self.filter = filter if self._client: self._client.set_filter(filter) + def get_filter(self): + return self.filter + @property def client(self): if not self._client: @@ -80,16 +83,16 @@ class APRSClient: try: self._client = self.setup_connection() if self.filter: - LOG.info("Creating APRS client filter") + LOG.info('Creating APRS client filter') self._client.set_filter(self.filter) except Exception as e: - LOG.error(f"Failed to create APRS client: {e}") + LOG.error(f'Failed to create APRS client: {e}') self._client = None raise def stop(self): if self._client: - LOG.info("Stopping client connection.") + LOG.info('Stopping client connection.') self._client.stop() def send(self, packet: core.Packet) -> None: @@ -103,16 +106,16 @@ class APRSClient: @wrapt.synchronized(lock) def reset(self) -> None: """Call this to force a rebuild/reconnect.""" - LOG.info("Resetting client connection.") + LOG.info('Resetting client connection.') if self._client: self._client.close() del self._client self._create_client() else: - LOG.warning("Client not initialized, nothing to reset.") + LOG.warning('Client not initialized, nothing to reset.') # Recreate the client - LOG.info(f"Creating new client {self.client}") + LOG.info(f'Creating new client {self.client}') @abc.abstractmethod def setup_connection(self): diff --git a/aprsd/conf/log.py b/aprsd/conf/log.py index bb29b38..6da1cbc 100644 --- a/aprsd/conf/log.py +++ b/aprsd/conf/log.py @@ -54,6 +54,11 @@ logging_opts = [ default=True, help='Enable ANSI color codes in logging', ), + cfg.BoolOpt( + 'enable_console_stdout', + default=True, + help='Enable logging to the console/stdout.', + ), ] diff --git a/aprsd/log/log.py b/aprsd/log/log.py index b014b59..95c9a10 100644 --- a/aprsd/log/log.py +++ b/aprsd/log/log.py @@ -84,15 +84,18 @@ def setup_logging(loglevel=None, quiet=False): logging.getLogger(name).handlers = [] logging.getLogger(name).propagate = name not in disable_list - handlers = [ - { - 'sink': sys.stdout, - 'serialize': False, - 'format': CONF.logging.logformat, - 'colorize': CONF.logging.enable_color, - 'level': log_level, - }, - ] + handlers = [] + if CONF.logging.enable_console_stdout: + handlers.append( + { + 'sink': sys.stdout, + 'serialize': False, + 'format': CONF.logging.logformat, + 'colorize': CONF.logging.enable_color, + 'level': log_level, + }, + ) + if CONF.logging.logfile: handlers.append( {