httpd: add country pie chart to dashboard
All checks were successful
CI / syntax-check (push) Successful in 6s
CI / memory-leak-check (push) Successful in 14s

This commit is contained in:
Username
2025-12-24 01:37:57 +01:00
parent 9738cc9664
commit 372d7643cc

View File

@@ -598,9 +598,30 @@ function update(d) {
$('failLegend').innerHTML = fhtml;
// Leaderboards (session data)
renderLeaderboard('topCountries', d.top_countries_session, 'code', 'count');
renderLeaderboard('topAsns', d.top_asns_session, 'asn', 'count');
// Country pie chart (database data)
var countryColors = ['#58a6ff','#3fb950','#d29922','#f85149','#a371f7','#39c5cf','#db61a2','#db6d28','#7ee787','#7d8590'];
if (d.db && d.db.top_countries && d.db.top_countries.length > 0) {
var countries = d.db.top_countries.slice(0, 8);
var countryTotal = countries.reduce(function(s, c) { return s + (c.count || c[1] || 0); }, 0);
var segs = [], chtml = '';
countries.forEach(function(c, i) {
var code = c.code || c[0], cnt = c.count || c[1] || 0;
var col = countryColors[i % countryColors.length];
var pctVal = countryTotal > 0 ? ((cnt / countryTotal) * 100).toFixed(1) : '0';
segs.push({c: col, d: (cnt / countryTotal) * 360});
chtml += '<div class="legend-item"><div class="legend-dot" style="background:' + col + '"></div>';
chtml += '<span class="legend-name">' + code + '</span><span class="legend-val">' + fmt(cnt) + '</span>';
chtml += '<span class="sub" style="margin-left:4px">' + pctVal + '%</span></div>';
});
$('countryPie').style.background = conicGrad(segs);
$('countryLegend').innerHTML = chtml;
} else {
$('countryPie').style.background = 'var(--border)';
$('countryLegend').innerHTML = '<div style="color:var(--dim);font-size:11px">No data</div>';
}
// Tor pool
var thtml = '';
if (d.tor_pool && d.tor_pool.hosts) {
@@ -639,15 +660,6 @@ function update(d) {
return '<div class="stat-row"><span class="stat-lbl">' + p.toUpperCase() + '</span><span class="stat-val">' + fmt(c) + '</span></div>';
}).join('');
var chtml = '';
if (dbs.top_countries) {
dbs.top_countries.slice(0, 5).forEach(function(c, i) {
var name = c.code || c[0], cnt = c.count || c[1];
chtml += '<div class="lb-item"><div class="lb-rank' + (i === 0 ? ' top' : '') + '">' + (i + 1) + '</div>';
chtml += '<span class="lb-name">' + name + '</span><span class="lb-val blu">' + fmt(cnt) + '</span></div>';
});
}
$('dbCountries').innerHTML = chtml || '<div style="color:var(--dim)">No data</div>';
}
// Scraper/Engine stats
@@ -705,6 +717,11 @@ function update(d) {
$('dbTestedHour').textContent = fmt(dbh.tested_last_hour);
$('dbAddedDay').textContent = fmt(dbh.added_last_day);
$('dbDead').textContent = fmt(dbh.dead_count);
$('dbFailing').textContent = fmt(dbh.failing_count);
$('dbFreelist').textContent = fmt(dbh.freelist_count);
$('dbAvgLat').textContent = fmtMs(dbh.db_avg_latency);
$('dbMinLat').textContent = fmtMs(dbh.db_min_latency);
$('dbMaxLat').textContent = fmtMs(dbh.db_max_latency);
}
// Tor pool enhanced stats
@@ -933,14 +950,17 @@ DASHBOARD_HTML = '''<!DOCTYPE html>
<!-- Geographic Distribution -->
<div class="sec">
<div class="sec-hdr">Geographic Distribution (Session)</div>
<div class="sec-hdr">Geographic Distribution <a href="/map" style="font-size:10px;font-weight:normal;margin-left:8px">View Map &rarr;</a></div>
<div class="g g2">
<div class="c">
<div class="lbl">Top Countries</div>
<div class="lb" id="topCountries"></div>
<div class="lbl">Proxies by Country (Database)</div>
<div class="pie-wrap">
<div class="pie" id="countryPie"></div>
<div class="legend" id="countryLegend"></div>
</div>
</div>
<div class="c">
<div class="lbl">Top ASNs</div>
<div class="lbl">Top ASNs (Session)</div>
<div class="lb" id="topAsns"></div>
</div>
</div>
@@ -1023,14 +1043,21 @@ DASHBOARD_HTML = '''<!DOCTYPE html>
<div class="val-sm red" id="dbDead">-</div>
</div>
</div>
<div class="g g2">
<div class="g g3">
<div class="c">
<div class="lbl">Working by Protocol</div>
<div id="dbByProto"></div>
</div>
<div class="c">
<div class="lbl">Top Countries (All Time)</div>
<div class="lb" id="dbCountries"></div>
<div class="lbl">Latency Stats</div>
<div class="stat-row"><span class="stat-lbl">Average</span><span class="stat-val cyn" id="dbAvgLat">-</span></div>
<div class="stat-row"><span class="stat-lbl">Min</span><span class="stat-val grn" id="dbMinLat">-</span></div>
<div class="stat-row"><span class="stat-lbl">Max</span><span class="stat-val red" id="dbMaxLat">-</span></div>
</div>
<div class="c">
<div class="lbl">Activity</div>
<div class="stat-row"><span class="stat-lbl">Failing</span><span class="stat-val yel" id="dbFailing">-</span></div>
<div class="stat-row"><span class="stat-lbl">Freelist</span><span class="stat-val" id="dbFreelist">-</span></div>
</div>
</div>
</div>