From e4629fd16470ff8644e2f784c879d1596ca65a3d Mon Sep 17 00:00:00 2001 From: Matthew Grotke Date: Tue, 9 Jun 2026 21:40:14 -0400 Subject: [PATCH] Development --- .../app/pages/dnsserver/action.py | 21 ++++++++++++ .../app/pages/dnsserver/content.json | 4 +++ .../routlin-dash/app/pages/dnsserver/view.py | 32 ++++++++++++++++++- .../routlin-dash/app/pages/overview/view.py | 14 +++++--- 4 files changed, 65 insertions(+), 6 deletions(-) diff --git a/docker/routlin-dash/app/pages/dnsserver/action.py b/docker/routlin-dash/app/pages/dnsserver/action.py index cbabfff..b1ede79 100644 --- a/docker/routlin-dash/app/pages/dnsserver/action.py +++ b/docker/routlin-dash/app/pages/dnsserver/action.py @@ -55,6 +55,27 @@ def upstreamdns_save(): return redirect(f'/{_PAGE}') +VALID_PERIODS = {0, 1, 7, 30, 60, 90, 365} + +@bp.route('/action/dnsserver/metrics_period_save', methods=['POST']) +@auth.require_level('administrator') +def metrics_period_save(): + try: + period = int(request.form.get('metrics_period', '0')) + except ValueError: + period = 0 + if period not in VALID_PERIODS: + flash('Invalid period value.', 'error') + return redirect(f'/{_PAGE}') + if not config_utils.verify_config_hash(request.form.get('config_hash', '')): + flash('Configuration was modified by another session. Please refresh and try again.', 'error') + return redirect(f'/{_PAGE}') + cfg = config_utils.load_config() + cfg.setdefault('upstream_dns', {})['metrics_period'] = period + config_utils.save_config(cfg) + return redirect(f'/{_PAGE}') + + @bp.route('/action/dnsserver/dnsforwarding_save', methods=['POST']) @auth.require_level('administrator') def dnsforwarding_save(): diff --git a/docker/routlin-dash/app/pages/dnsserver/content.json b/docker/routlin-dash/app/pages/dnsserver/content.json index 1405c1d..fadf664 100644 --- a/docker/routlin-dash/app/pages/dnsserver/content.json +++ b/docker/routlin-dash/app/pages/dnsserver/content.json @@ -104,6 +104,10 @@ "type": "card", "label": "DNS Statistics", "items": [ + { + "type": "raw_html", + "html": "%DNS_PERIOD_SELECTOR%" + }, { "type": "grid", "rows": [ diff --git a/docker/routlin-dash/app/pages/dnsserver/view.py b/docker/routlin-dash/app/pages/dnsserver/view.py index 7c659e9..18fb8af 100644 --- a/docker/routlin-dash/app/pages/dnsserver/view.py +++ b/docker/routlin-dash/app/pages/dnsserver/view.py @@ -1,7 +1,34 @@ import json import config_utils +import factory from pages.overview.view import load_dns_metrics, _dns_providers_table +_PERIOD_OPTIONS = [ + (1, '1 Day'), + (7, '7 Days'), + (30, '30 Days'), + (60, '60 Days'), + (90, '90 Days'), + (365, '365 Days'), + (0, 'All Time'), +] + + +def _period_selector_html(current_period): + opts = ''.join( + f'' + for v, label in _PERIOD_OPTIONS + ) + return ( + '
' + '' + f'' + f'' + '
' + ) + def collect_tokens(cfg): tokens = config_utils.collect_layout_tokens(cfg) @@ -11,7 +38,10 @@ def collect_tokens(cfg): tokens['DNS_CACHE_SIZE'] = str(dns.get('cache_size', '-')) tokens['DNS_UPSTREAM_SERVERS_JSON'] = json.dumps(servers) - dns_stats = load_dns_metrics() + period = int(dns.get('metrics_period', 0)) + dns_stats = load_dns_metrics(period=period) + + tokens['DNS_PERIOD_SELECTOR'] = _period_selector_html(period) tokens['DNS_METRICS_SINCE'] = dns_stats['since'] tokens['DNS_METRICS_UPDATED'] = dns_stats['updated'] tokens['DNS_STAT_QUERIES'] = dns_stats['queries'] diff --git a/docker/routlin-dash/app/pages/overview/view.py b/docker/routlin-dash/app/pages/overview/view.py index 3b9b419..562e716 100644 --- a/docker/routlin-dash/app/pages/overview/view.py +++ b/docker/routlin-dash/app/pages/overview/view.py @@ -63,7 +63,7 @@ def _dns_providers_table(servers): ) -def load_dns_metrics(): +def load_dns_metrics(period=0): import sqlite3 empty = { 'queries': '-', 'hits': '-', 'hit_rate': '-', 'forwarded': '-', @@ -71,16 +71,20 @@ def load_dns_metrics(): 'updated': '-', 'since': '-', 'servers': [], } try: + where = ( + f"WHERE date >= date('now','localtime','-{period - 1} days')" + if period and period > 0 else '' + ) con = sqlite3.connect(METRICS_DB, timeout=5) con.execute('PRAGMA journal_mode=WAL') - row = con.execute(''' + row = con.execute(f''' SELECT MIN(date), MAX(date), SUM(queries_forwarded), SUM(queries_answered_locally), SUM(queries_authoritative), SUM(cache_reused), MAX(tcp_hwm) - FROM daily_totals + FROM daily_totals {where} ''').fetchone() - srv_rows = con.execute(''' + srv_rows = con.execute(f''' SELECT ds.address, SUM(ds.queries_sent), @@ -90,7 +94,7 @@ def load_dns_metrics(): (SELECT avg_latency_ms FROM daily_servers d2 WHERE d2.address = ds.address AND d2.avg_latency_ms > 0 ORDER BY d2.date DESC LIMIT 1) - FROM daily_servers ds + FROM daily_servers ds {where} GROUP BY ds.address ORDER BY SUM(ds.queries_sent) DESC ''').fetchall()