From d340d60b5216b694e9a20ae1618d37276e469dc4 Mon Sep 17 00:00:00 2001 From: Space-Banane Date: Thu, 12 Mar 2026 16:05:20 +0100 Subject: [PATCH] Enhance notification system and logging --- monitor.py | 58 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/monitor.py b/monitor.py index 10dbf59..a533abb 100644 --- a/monitor.py +++ b/monitor.py @@ -39,9 +39,11 @@ except (EnvironmentError, json.JSONDecodeError) as e: print(f"Error during startup: {e}") exit(1) -def notify_hass(message,title): +def notify_hass(client_name, host, reason, title="🛡️ Adguard Blocked a Request"): + msg = f"{client_name} tried to access \"{host}\"" + payload = { - "message": message, + "message": msg, "title": title, "data": { "push": { @@ -74,6 +76,8 @@ class MonitorStats: self.api_calls = 0 self.total_blocked = 0 self.last_log_id = None + self.current_limit = 150 + self.last_notified_key = None # To prevent double notifications def log_api_call(self): self.api_calls += 1 @@ -82,7 +86,7 @@ class MonitorStats: self.total_blocked += 1 def get_summary(self): - return f"API Polls: {self.api_calls} | Total Blocked: {self.total_blocked}" + return f"API Polls: {self.api_calls} | Total Blocked: {self.total_blocked} | Current Limit: {self.current_limit}" stats = MonitorStats() @@ -91,10 +95,14 @@ def get_auth_session(): session.auth = HTTPBasicAuth(USERNAME, PASSWORD) return session -def fetch_and_analyze(session): +def hour_and_minute(): + now = datetime.now() + return now.strftime("%H:%M") + +def fetch_and_analyze(session, verbose=False): stats.log_api_call() try: - response = session.get(QUERY_LOG_URL, params={'limit': 50}, timeout=10) + response = session.get(QUERY_LOG_URL, params={'limit': stats.current_limit}, timeout=10) response.raise_for_status() data = response.json() @@ -123,13 +131,30 @@ def fetch_and_analyze(session): reason = log.get('reason') host = log.get('question', {}).get('name') client_name = CLIENTS[client_ip] + + if verbose: + logger.info(f"[{client_name}] Query: {host} | Reason: {reason}") - if reason in ["FilteredBlackList", "Rewrite"]: + if reason in ["FilteredBlackList", "FilteredParental", "FilteredSafeBrowsing"]: + # Check for duplicate notifications within the same "event" + # Using host + client_ip as a unique key for the last notification + notification_key = f"{client_ip}:{host}:{reason}:{hour_and_minute()}" + if stats.last_notified_key == notification_key: + continue + stats.log_blocked() - msg = f"🚫 Blocked: {host}\nReason: {reason}" - logger.warning(msg) - notify_hass(msg, f"BLOCKED: {client_name}") + logger.warning(f"BLOCKED: {client_name} -> {host} ({reason})") + notify_hass(client_name, host, reason) + stats.last_notified_key = notification_key + # Dynamic limit adjustment + if new_items_processed == 0 and stats.current_limit < 350: + stats.current_limit = min(350, stats.current_limit + 50) + logger.info(f"No relevant client traffic found. Increasing pull limit to {stats.current_limit}") + elif new_items_processed > 0 and stats.current_limit > 150: + stats.current_limit = 150 + logger.info(f"Client traffic found. Resetting pull limit to {stats.current_limit}") + logger.info(f"Analyzed {new_items_processed} new entries since last pull.") logger.debug(f"Status Update: {stats.get_summary()}") @@ -139,11 +164,24 @@ def fetch_and_analyze(session): if __name__ == "__main__": parser = argparse.ArgumentParser(description="AdGuard Monitor Service") parser.add_argument("--interval", type=int, default=15, help="Update interval in seconds") + parser.add_argument("--verbose", action="store_true", help="Log all queries for monitored clients") + parser.add_argument("--test", action="store_true", help="Send a fake test notification and exit") args = parser.parse_args() + if args.test: + import random + test_ip, test_name = random.choice(list(CLIENTS.items())) + test_host = "test-domain.com" + test_reason = "ManualTest" + logger.info(f"Sending test notification for {test_name} ({test_ip})...") + notify_hass(test_name, test_host, test_reason, "🛠️ AdGuard Monitor Test") + logger.info("Test notification sent. Exiting.") + exit(0) + logger.info(f"AdGuard Monitor Service Started. Interval: {args.interval}s") + logger.info(f"Monitoring {len(CLIENTS)} clients: {', '.join([f'{name} ({ip})' for ip, name in CLIENTS.items()])}") session = get_auth_session() while True: - fetch_and_analyze(session) + fetch_and_analyze(session, verbose=args.verbose) time.sleep(args.interval)