feat: add memory footprint to /stats and dashboard #26

Merged
razvandimescu merged 3 commits from feat/memory-footprint into main 2026-04-01 14:09:44 +08:00
7 changed files with 10 additions and 20 deletions
Showing only changes of commit 987e3aeeae - Show all commits

View File

@@ -814,15 +814,15 @@ function renderMemory(mem, stats) {
if (!mem) return;
// Stat card
document.getElementById('memoryRss').textContent = formatBytes(mem.process_rss_bytes);
document.getElementById('memoryRss').textContent = formatBytes(mem.process_memory_bytes);
document.getElementById('memorySub').textContent = 'est. ' + formatBytes(mem.total_estimated_bytes);
const entryCounts = {
cache: mem.cache_entries,
blocklist: mem.blocklist_entries,
cache: stats.cache.entries,
blocklist: stats.blocking.domains_loaded,
query_log: mem.query_log_entries,
srtt: mem.srtt_entries,
overrides: mem.overrides_entries,
overrides: stats.overrides.active,
};
// Sidebar panel
@@ -852,7 +852,7 @@ function renderMemory(mem, stats) {
${rows}
<div class="memory-rss">
<span>Process Footprint</span>
<span>${formatBytes(mem.process_rss_bytes)}</span>
<span>${formatBytes(mem.process_memory_bytes)}</span>
</div>
`;
}

View File

@@ -214,17 +214,14 @@ struct BlockingStatsResponse {
#[derive(Serialize)]
struct MemoryStats {
cache_bytes: usize,
cache_entries: usize,
blocklist_bytes: usize,
blocklist_entries: usize,
query_log_bytes: usize,
query_log_entries: usize,
srtt_bytes: usize,
srtt_entries: usize,
overrides_bytes: usize,
overrides_entries: usize,
total_estimated_bytes: usize,
process_rss_bytes: usize,
process_memory_bytes: usize,
}
#[derive(Serialize)]
@@ -556,17 +553,14 @@ async fn stats(State(ctx): State<Arc<ServerCtx>>) -> Json<StatsResponse> {
},
memory: MemoryStats {
cache_bytes,
cache_entries: cache_len,
blocklist_bytes,
blocklist_entries: bl_stats.domains_loaded,
query_log_bytes,
query_log_entries,
srtt_bytes,
srtt_entries,
overrides_bytes,
overrides_entries: override_count,
total_estimated_bytes: total_estimated,
process_rss_bytes: crate::stats::process_rss_bytes(),
process_memory_bytes: crate::stats::process_memory_bytes(),
},
})
}

View File

@@ -184,7 +184,6 @@ impl BlocklistStore {
}
pub fn heap_bytes(&self) -> usize {
// HashSet<String> stores (hash, String) per slot + 1 control byte
let per_slot_overhead = std::mem::size_of::<u64>() + std::mem::size_of::<String>() + 1;
let domains_table = self.domains.capacity() * per_slot_overhead;
let domains_heap: usize = self.domains.iter().map(|d| d.capacity()).sum();

View File

@@ -143,7 +143,6 @@ impl DnsCache {
}
pub fn heap_bytes(&self) -> usize {
// Outer HashMap<String, HashMap>: (hash, String, HashMap) per slot + control byte
let outer_slot = std::mem::size_of::<u64>()
+ std::mem::size_of::<String>()
+ std::mem::size_of::<HashMap<QueryType, CacheEntry>>()
@@ -151,7 +150,6 @@ impl DnsCache {
let mut total = self.entries.capacity() * outer_slot;
for (domain, type_map) in &self.entries {
total += domain.capacity();
// Inner HashMap<QueryType, CacheEntry>: (hash, QueryType, CacheEntry) per slot + control byte
let inner_slot = std::mem::size_of::<u64>()
+ std::mem::size_of::<QueryType>()
+ std::mem::size_of::<CacheEntry>()

View File

@@ -118,7 +118,6 @@ impl OverrideStore {
}
pub fn heap_bytes(&self) -> usize {
// HashMap<String, OverrideEntry>: (hash, String, OverrideEntry) per slot + control byte
let per_slot = std::mem::size_of::<u64>()
+ std::mem::size_of::<String>()
+ std::mem::size_of::<OverrideEntry>()

View File

@@ -101,7 +101,6 @@ impl SrttCache {
}
pub fn heap_bytes(&self) -> usize {
// HashMap stores (hash, key, value) per slot + 1 control byte
let per_slot = std::mem::size_of::<u64>()
+ std::mem::size_of::<IpAddr>()
+ std::mem::size_of::<SrttEntry>()

View File

@@ -1,7 +1,8 @@
use std::time::Instant;
/// Returns the process resident set size in bytes, or 0 if unavailable.
pub fn process_rss_bytes() -> usize {
/// Returns the process memory footprint in bytes, or 0 if unavailable.
/// macOS: phys_footprint (matches Activity Monitor). Linux: RSS from /proc/self/statm.
pub fn process_memory_bytes() -> usize {
#[cfg(target_os = "macos")]
{
macos_rss()