From 510d5d05a9e20f8aeebd3fdfd73981491c3bbcf2 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 16:57:00 -0400 Subject: [PATCH] SIGHUP-based configuration reload: address review feedback (#700) * Initial plan * Address review feedback: kafka_ssl, duplicate silent, exception chain, log file reload, should_reload timing Co-authored-by: seanthegeek <44679+seanthegeek@users.noreply.github.com> Agent-Logs-Url: https://github.com/domainaware/parsedmarc/sessions/a8a43c55-23fa-4471-abe6-7ac966f381f9 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: seanthegeek <44679+seanthegeek@users.noreply.github.com> --- parsedmarc/cli.py | 39 ++++++++++++++++++++++++++++++++------- parsedmarc/mail/gmail.py | 6 ++++-- parsedmarc/mail/graph.py | 4 ++-- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/parsedmarc/cli.py b/parsedmarc/cli.py index 9f001e2..ffba4ee 100644 --- a/parsedmarc/cli.py +++ b/parsedmarc/cli.py @@ -254,7 +254,7 @@ def _parse_config_file(config_file, opts): except Exception as ns_error: raise ConfigurationError( "DNS pre-flight check failed: {}".format(ns_error) - ) + ) from ns_error if not dummy_hostname: raise ConfigurationError( "DNS pre-flight check failed: no PTR record for {} from {}".format( @@ -271,8 +271,6 @@ def _parse_config_file(config_file, opts): opts.debug = bool(general_config.getboolean("debug")) if "verbose" in general_config: opts.verbose = bool(general_config.getboolean("verbose")) - if "silent" in general_config: - opts.silent = bool(general_config.getboolean("silent")) if "warnings" in general_config: opts.warnings = bool(general_config.getboolean("warnings")) if "fail_on_output_error" in general_config: @@ -946,15 +944,17 @@ def _init_output_clients(opts): if opts.kafka_hosts: ssl_context = None - if opts.kafka_skip_certificate_verification: - logger.debug("Skipping Kafka certificate verification") + if opts.kafka_ssl: ssl_context = create_default_context() - ssl_context.check_hostname = False - ssl_context.verify_mode = CERT_NONE + if opts.kafka_skip_certificate_verification: + logger.debug("Skipping Kafka certificate verification") + ssl_context.check_hostname = False + ssl_context.verify_mode = CERT_NONE clients["kafka_client"] = kafkaclient.KafkaClient( opts.kafka_hosts, username=opts.kafka_username, password=opts.kafka_password, + ssl=opts.kafka_ssl, ssl_context=ssl_context, ) @@ -2047,6 +2047,31 @@ def _main(): if opts.debug: logger.setLevel(logging.DEBUG) + # Refresh FileHandler if log_file changed + old_log_file = getattr(opts, "active_log_file", None) + new_log_file = opts.log_file + if old_log_file != new_log_file: + # Remove old FileHandlers + for h in list(logger.handlers): + if isinstance(h, logging.FileHandler): + h.close() + logger.removeHandler(h) + # Add new FileHandler if configured + if new_log_file: + try: + fh = logging.FileHandler(new_log_file, "a") + file_formatter = logging.Formatter( + "%(asctime)s - %(levelname)s" + " - [%(filename)s:%(lineno)d] - %(message)s" + ) + fh.setFormatter(file_formatter) + logger.addHandler(fh) + except Exception as log_error: + logger.warning( + "Unable to write to log file: {}".format(log_error) + ) + opts.active_log_file = new_log_file + logger.info("Configuration reloaded successfully") except Exception: logger.exception( diff --git a/parsedmarc/mail/gmail.py b/parsedmarc/mail/gmail.py index fd9fb64..6eec937 100644 --- a/parsedmarc/mail/gmail.py +++ b/parsedmarc/mail/gmail.py @@ -178,10 +178,12 @@ class GmailConnection(MailboxConnection): def watch(self, check_callback, check_timeout, should_reload=None): """Checks the mailbox for new messages every n seconds""" while True: - sleep(check_timeout) - check_callback(self) if should_reload and should_reload(): return + sleep(check_timeout) + if should_reload and should_reload(): + return + check_callback(self) @lru_cache(maxsize=10) def _find_label_id_for_label(self, label_name: str) -> str: diff --git a/parsedmarc/mail/graph.py b/parsedmarc/mail/graph.py index 2b12e6e..513ece3 100644 --- a/parsedmarc/mail/graph.py +++ b/parsedmarc/mail/graph.py @@ -281,10 +281,10 @@ class MSGraphConnection(MailboxConnection): def watch(self, check_callback, check_timeout, should_reload=None): """Checks the mailbox for new messages every n seconds""" while True: - sleep(check_timeout) - check_callback(self) if should_reload and should_reload(): return + sleep(check_timeout) + check_callback(self) @lru_cache(maxsize=10) def _find_folder_id_from_folder_path(self, folder_name: str) -> str: