Add oldest and newest route timestamps to status page
Display oldest and newest route timestamps in the Routing Table card on the /status page. Timestamps are shown as relative times (e.g., "5m ago", "2h 30m ago"). Changes: - Add OldestRoute and NewestRoute fields to database.Stats - Query MIN/MAX of last_updated across live_routes_v4 and v6 tables - Include timestamps in both /status.json and /api/v1/stats responses - Add formatRelativeTime JavaScript function for display
This commit is contained in:
parent
8fc10ae98d
commit
aebdd1b23e
@ -946,6 +946,23 @@ func (d *Database) GetStatsContext(ctx context.Context) (Stats, error) {
|
||||
}
|
||||
stats.LiveRoutes = v4Count + v6Count
|
||||
|
||||
// Get oldest and newest route timestamps
|
||||
routeTimestampQuery := `
|
||||
SELECT MIN(last_updated), MAX(last_updated) FROM (
|
||||
SELECT last_updated FROM live_routes_v4
|
||||
UNION ALL
|
||||
SELECT last_updated FROM live_routes_v6
|
||||
)
|
||||
`
|
||||
var oldestRoute, newestRoute *time.Time
|
||||
err = d.db.QueryRowContext(ctx, routeTimestampQuery).Scan(&oldestRoute, &newestRoute)
|
||||
if err != nil {
|
||||
d.logger.Warn("Failed to get route timestamps", "error", err)
|
||||
} else {
|
||||
stats.OldestRoute = oldestRoute
|
||||
stats.NewestRoute = newestRoute
|
||||
}
|
||||
|
||||
// Get prefix distribution
|
||||
stats.IPv4PrefixDistribution, stats.IPv6PrefixDistribution, err = d.GetPrefixDistributionContext(ctx)
|
||||
if err != nil {
|
||||
|
||||
@ -18,6 +18,8 @@ type Stats struct {
|
||||
Peers int
|
||||
FileSizeBytes int64
|
||||
LiveRoutes int
|
||||
OldestRoute *time.Time
|
||||
NewestRoute *time.Time
|
||||
IPv4PrefixDistribution []PrefixDistribution
|
||||
IPv6PrefixDistribution []PrefixDistribution
|
||||
}
|
||||
|
||||
@ -164,6 +164,8 @@ func (s *Server) handleStatusJSON() http.HandlerFunc {
|
||||
LiveRoutes int `json:"live_routes"`
|
||||
IPv4Routes int `json:"ipv4_routes"`
|
||||
IPv6Routes int `json:"ipv6_routes"`
|
||||
OldestRoute *time.Time `json:"oldest_route,omitempty"`
|
||||
NewestRoute *time.Time `json:"newest_route,omitempty"`
|
||||
IPv4UpdatesPerSec float64 `json:"ipv4_updates_per_sec"`
|
||||
IPv6UpdatesPerSec float64 `json:"ipv6_updates_per_sec"`
|
||||
IPv4PrefixDistribution []database.PrefixDistribution `json:"ipv4_prefix_distribution"`
|
||||
@ -258,6 +260,8 @@ func (s *Server) handleStatusJSON() http.HandlerFunc {
|
||||
LiveRoutes: dbStats.LiveRoutes,
|
||||
IPv4Routes: ipv4Routes,
|
||||
IPv6Routes: ipv6Routes,
|
||||
OldestRoute: dbStats.OldestRoute,
|
||||
NewestRoute: dbStats.NewestRoute,
|
||||
IPv4UpdatesPerSec: routeMetrics.IPv4UpdatesPerSec,
|
||||
IPv6UpdatesPerSec: routeMetrics.IPv6UpdatesPerSec,
|
||||
IPv4PrefixDistribution: dbStats.IPv4PrefixDistribution,
|
||||
@ -369,6 +373,8 @@ func (s *Server) handleStats() http.HandlerFunc {
|
||||
LiveRoutes int `json:"live_routes"`
|
||||
IPv4Routes int `json:"ipv4_routes"`
|
||||
IPv6Routes int `json:"ipv6_routes"`
|
||||
OldestRoute *time.Time `json:"oldest_route,omitempty"`
|
||||
NewestRoute *time.Time `json:"newest_route,omitempty"`
|
||||
IPv4UpdatesPerSec float64 `json:"ipv4_updates_per_sec"`
|
||||
IPv6UpdatesPerSec float64 `json:"ipv6_updates_per_sec"`
|
||||
HandlerStats []HandlerStatsInfo `json:"handler_stats"`
|
||||
@ -530,6 +536,8 @@ func (s *Server) handleStats() http.HandlerFunc {
|
||||
LiveRoutes: dbStats.LiveRoutes,
|
||||
IPv4Routes: ipv4Routes,
|
||||
IPv6Routes: ipv6Routes,
|
||||
OldestRoute: dbStats.OldestRoute,
|
||||
NewestRoute: dbStats.NewestRoute,
|
||||
IPv4UpdatesPerSec: routeMetrics.IPv4UpdatesPerSec,
|
||||
IPv6UpdatesPerSec: routeMetrics.IPv6UpdatesPerSec,
|
||||
HandlerStats: handlerStatsInfo,
|
||||
|
||||
@ -321,6 +321,14 @@
|
||||
<span class="metric-label">IPv6 Updates/sec</span>
|
||||
<span class="metric-value" id="ipv6_updates_per_sec">-</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Oldest Route</span>
|
||||
<span class="metric-value" id="oldest_route">-</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Newest Route</span>
|
||||
<span class="metric-value" id="newest_route">-</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="status-card">
|
||||
@ -400,7 +408,23 @@
|
||||
return ms.toFixed(2) + ' ms';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function formatRelativeTime(isoString) {
|
||||
if (!isoString) return '-';
|
||||
const date = new Date(isoString);
|
||||
const now = new Date();
|
||||
const diffMs = now - date;
|
||||
const diffSec = Math.floor(diffMs / 1000);
|
||||
const diffMin = Math.floor(diffSec / 60);
|
||||
const diffHour = Math.floor(diffMin / 60);
|
||||
const diffDay = Math.floor(diffHour / 24);
|
||||
|
||||
if (diffSec < 60) return diffSec + 's ago';
|
||||
if (diffMin < 60) return diffMin + 'm ago';
|
||||
if (diffHour < 24) return diffHour + 'h ' + (diffMin % 60) + 'm ago';
|
||||
return diffDay + 'd ' + (diffHour % 24) + 'h ago';
|
||||
}
|
||||
|
||||
function updatePrefixDistribution(elementId, distribution) {
|
||||
const container = document.getElementById(elementId);
|
||||
container.innerHTML = '';
|
||||
@ -506,6 +530,8 @@
|
||||
document.getElementById('ipv6_routes').textContent = '-';
|
||||
document.getElementById('ipv4_updates_per_sec').textContent = '-';
|
||||
document.getElementById('ipv6_updates_per_sec').textContent = '-';
|
||||
document.getElementById('oldest_route').textContent = '-';
|
||||
document.getElementById('newest_route').textContent = '-';
|
||||
document.getElementById('whois_fresh').textContent = '-';
|
||||
document.getElementById('whois_stale').textContent = '-';
|
||||
document.getElementById('whois_never').textContent = '-';
|
||||
@ -566,6 +592,8 @@
|
||||
document.getElementById('ipv6_routes').textContent = formatNumber(data.ipv6_routes);
|
||||
document.getElementById('ipv4_updates_per_sec').textContent = data.ipv4_updates_per_sec.toFixed(1);
|
||||
document.getElementById('ipv6_updates_per_sec').textContent = data.ipv6_updates_per_sec.toFixed(1);
|
||||
document.getElementById('oldest_route').textContent = formatRelativeTime(data.oldest_route);
|
||||
document.getElementById('newest_route').textContent = formatRelativeTime(data.newest_route);
|
||||
|
||||
// Update stream stats
|
||||
if (data.stream) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user