Enhance notification system and logging

This commit is contained in:
Space-Banane
2026-03-12 16:05:20 +01:00
parent 66ec4945d5
commit d340d60b52

View File

@@ -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)