Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions admin-ui/dist/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ class NextStepBanner extends LiveElement {
method: 'POST',
credentials: 'same-origin',
redirect: 'manual',
keepalive: true,
body: new URLSearchParams(new FormData(form)),
}).catch(() => {});
});
Expand Down
76 changes: 52 additions & 24 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ pub struct TimelineMultiPoint {
pub cached: i64,
}

#[derive(Debug, Clone)]
pub struct DomainStats {
pub unique: i64,
pub top: Vec<TopDomain>,
}

#[derive(Debug, Clone, Serialize)]
pub struct HeatmapCell {
pub weekday: i64, // 0 = Sunday, 6 = Saturday (matches strftime('%w'))
Expand Down Expand Up @@ -418,7 +424,8 @@ impl Database {
upstream TEXT,
doh_token TEXT,
result TEXT,
authenticated_data INTEGER NOT NULL DEFAULT 0
authenticated_data INTEGER NOT NULL DEFAULT 0,
has_result INTEGER GENERATED ALWAYS AS (result IS NOT NULL AND result != '') VIRTUAL
);
CREATE INDEX IF NOT EXISTS idx_query_logs_timestamp ON query_logs(timestamp);
CREATE INDEX IF NOT EXISTS idx_query_logs_domain_ts ON query_logs(domain, timestamp);
Expand Down Expand Up @@ -642,7 +649,22 @@ impl Database {
)?;
}

const LATEST_VERSION: i64 = 11;
if version < 12 {
add_column_if_missing(
conn,
"query_logs",
"has_result",
"INTEGER GENERATED ALWAYS AS (result IS NOT NULL AND result != '') VIRTUAL",
)?;
conn.execute_batch(
"DROP INDEX IF EXISTS idx_query_logs_ts_metrics;
CREATE INDEX idx_query_logs_ts_metrics \
ON query_logs(timestamp, blocked, cached, response_ms, query_type, has_result);
ANALYZE;",
)?;
}

const LATEST_VERSION: i64 = 12;
if version < LATEST_VERSION {
conn.pragma_update(None, "user_version", LATEST_VERSION)?;
}
Expand Down Expand Up @@ -1891,25 +1913,43 @@ impl Database {
since: i64,
limit: i64,
) -> Result<Vec<TopDomain>, DbError> {
Ok(self.domain_stats_since(since, limit).await?.top)
}

pub async fn domain_stats_since(&self, since: i64, limit: i64) -> Result<DomainStats, DbError> {
let since_ms = since * 1000;
let rows = self
let stats = self
.reader()
.call(move |conn| {
let mut stmt = conn.prepare_cached(
"SELECT domain, COUNT(*) as cnt FROM query_logs WHERE timestamp >= ?1 GROUP BY domain ORDER BY cnt DESC LIMIT ?2",
"WITH d AS ( \
SELECT domain, COUNT(*) AS cnt \
FROM query_logs \
WHERE timestamp >= ?1 \
GROUP BY domain \
) \
SELECT (SELECT COUNT(*) FROM d), domain, cnt \
FROM d ORDER BY cnt DESC LIMIT ?2",
)?;
let rows = stmt
.query_map(params![since_ms, limit], |row| {
Ok(TopDomain {
domain: row.get(0)?,
count: row.get(1)?,
})
Ok((
row.get::<_, i64>(0)?,
TopDomain {
domain: row.get(1)?,
count: row.get(2)?,
},
))
})?
.collect::<Result<Vec<_>, _>>()?;
Ok(rows)
let unique = rows.first().map_or(0, |(n, _)| *n);
Ok(DomainStats {
unique,
top: rows.into_iter().map(|(_, d)| d).collect(),
})
})
.await?;
Ok(rows)
Ok(stats)
}

pub async fn top_clients_since(
Expand Down Expand Up @@ -2119,19 +2159,7 @@ impl Database {
}

pub async fn unique_domains_since(&self, since: i64) -> Result<i64, DbError> {
let since_ms = since * 1000;
let count = self
.reader()
.call(move |conn| {
let n: i64 = conn.query_row(
"SELECT COUNT(DISTINCT domain) FROM query_logs WHERE timestamp >= ?1",
params![since_ms],
|row| row.get(0),
)?;
Ok(n)
})
.await?;
Ok(count)
Ok(self.domain_stats_since(since, 1).await?.unique)
}

pub async fn latency_summary_since(&self, since: i64) -> Result<LatencySummary, DbError> {
Expand Down Expand Up @@ -2297,7 +2325,7 @@ fn add_column_if_missing(
) -> Result<(), rusqlite::Error> {
let exists: bool = conn
.query_row(
&format!("SELECT COUNT(*) FROM pragma_table_info('{table}') WHERE name = ?1"),
&format!("SELECT COUNT(*) FROM pragma_table_xinfo('{table}') WHERE name = ?1"),
params![column],
|row| row.get::<_, i64>(0),
)
Expand Down