Problem Description / Motivation
In enterprise Linux environments and high-density container platforms (e.g., Kubernetes nodes running latency-sensitive databases, caching tiers, JVMs, or memory-constrained workloads), knowing only coarse-grained MemTotal, MemAvailable, and MemUsed is inadequate for capacity planning, troubleshooting OOM incidents, and detecting memory leaks.
Modern Linux systems rely on complex memory tiering and subsystems:
- ZRAM / Zswap / Swap: Compressed in-RAM block devices (
zram0) and swap usage are critical indicators of memory pressure. Currently, web_htop has zero visibility into swap activity or compressed memory ratios.
- HugePages (Transparent HugePages & HugeTLB): Systems running enterprise workloads rely on 2MB/1GB hugepages (
AnonHugePages, HugePages_Total, HugePages_Free). Failing to allocate hugepages causes silent fallback to 4KB pages and severe TLB miss penalties.
- Shared Memory & IPC:
Shmem and Mapped pages, tmpfs mounts, and shared memory segments can pin significant portions of RAM without appearing in process RSS.
- Kernel Slab & Buffers:
SReclaimable, SUnreclaim, Dirty, and Writeback pages are vital to distinguish between memory that can be quickly freed under pressure versus locked kernel buffers.
Current Limitations in the Codebase
- Primitive Memory Metrics Model:
common/include/common/models/memory_metrics.hpp: struct MemoryMetrics only tracks total_bytes, available_bytes, used_bytes, and used_percent.
server/src/collectors/metrics_collector.cpp (MetricsCollector::Memory): Reads /proc/meminfo, extracts only MemTotal and MemAvailable, and discards the remaining ~50 kernel metrics parsed by KeyValues().
- Missing Swap & Subsystem Allocations:
- Fields such as
SwapTotal, SwapFree, Zram, Shmem, Buffers, Cached, Slab, SReclaimable, SUnreclaim, AnonHugePages, HugePages_Total, HugePages_Free, Dirty, and Writeback are completely ignored.
- No Per-Process Memory Breakdown:
ParseProcess in linux_samples.cpp parses /proc/[pid]/stat field 23 (RSS pages), ignoring /proc/[pid]/status or /proc/[pid]/statm (Shared, Text, Data, Lib, Swap). A process consuming gigabytes of shared memory or swap is reported with incomplete memory footprints.
- Lack of Diagnostics & Prometheus Exposure:
/diagnostics and /exporter endpoints in reactor.cpp do not export detailed memory breakdowns or swap saturation gauges.
Proposed Technical Architecture & Implementation Plan
1. Model & Protocol Enhancements (common/include/common/models/memory_metrics.hpp)
Extend MemoryMetrics with structured memory breakdown fields:
struct MemoryMetrics
{
TimeStamp timestamp{};
Bytes total_bytes{};
Bytes available_bytes{};
Bytes used_bytes{};
Percentage used_percent{};
// Swap & Compressed Memory
Bytes swap_total_bytes{};
Bytes swap_free_bytes{};
Bytes swap_used_bytes{};
Percentage swap_used_percent{};
// Kernel & Cache breakdown
Bytes buffers_bytes{};
Bytes cached_bytes{};
Bytes shared_bytes{}; // Shmem
Bytes slab_reclaimable_bytes{};
Bytes slab_unreclaimable_bytes{};
Bytes dirty_bytes{};
Bytes writeback_bytes{};
// Hugepages breakdown
Bytes anon_hugepages_bytes{};
std::uint64_t hugepages_total{};
std::uint64_t hugepages_free{};
std::uint64_t hugepages_reserved{};
Bytes hugepage_size_bytes{};
// Optional ZRAM stats (if /sys/block/zram0 exists)
std::optional<Bytes> zram_orig_data_size;
std::optional<Bytes> zram_compr_data_size;
std::optional<Bytes> zram_mem_used_total;
};
Update serialization and deserialization in common/src/common/models/memory_metrics.cpp with backward-compatible JSON schema mappings.
2. Collector Implementation (server/src/collectors/metrics_collector.cpp)
- In
MetricsCollector::Memory, expand the KeyValues() lookup:
SwapTotal, SwapFree, Cached, Buffers, Shmem, SReclaimable, SUnreclaim, Dirty, Writeback, AnonHugePages, HugePages_Total, HugePages_Free, Hugepagesize.
- Query
/sys/block/zram<id>/mm_stat or /sys/block/zram<id>/disksize via LinuxSource::Sys when present to compute compression ratios (orig_data_size / compr_data_size).
- Gracefully handle systems where HugePages or ZRAM are unconfigured or unsupported without marking the collector state as
unavailable.
3. Exporter & UI Integration
- In
reactor.cpp (Diagnostics(bool prometheus)), expose:
web_htop_memory_swap_used_bytes
web_htop_memory_hugepages_free
web_htop_memory_slab_bytes
web_htop_memory_zram_compression_ratio
- In
client/src/ui/terminal_ui.cpp, update memory gauge and add an advanced memory breakdown panel displaying Cache/Buffer, Shmem, HugeTLB, and ZRAM/Swap status.
Acceptance Criteria
Problem Description / Motivation
In enterprise Linux environments and high-density container platforms (e.g., Kubernetes nodes running latency-sensitive databases, caching tiers, JVMs, or memory-constrained workloads), knowing only coarse-grained
MemTotal,MemAvailable, andMemUsedis inadequate for capacity planning, troubleshooting OOM incidents, and detecting memory leaks.Modern Linux systems rely on complex memory tiering and subsystems:
zram0) and swap usage are critical indicators of memory pressure. Currently, web_htop has zero visibility into swap activity or compressed memory ratios.AnonHugePages,HugePages_Total,HugePages_Free). Failing to allocate hugepages causes silent fallback to 4KB pages and severe TLB miss penalties.ShmemandMappedpages, tmpfs mounts, and shared memory segments can pin significant portions of RAM without appearing in process RSS.SReclaimable,SUnreclaim,Dirty, andWritebackpages are vital to distinguish between memory that can be quickly freed under pressure versus locked kernel buffers.Current Limitations in the Codebase
common/include/common/models/memory_metrics.hpp:struct MemoryMetricsonly trackstotal_bytes,available_bytes,used_bytes, andused_percent.server/src/collectors/metrics_collector.cpp(MetricsCollector::Memory): Reads/proc/meminfo, extracts onlyMemTotalandMemAvailable, and discards the remaining ~50 kernel metrics parsed byKeyValues().SwapTotal,SwapFree,Zram,Shmem,Buffers,Cached,Slab,SReclaimable,SUnreclaim,AnonHugePages,HugePages_Total,HugePages_Free,Dirty, andWritebackare completely ignored.ParseProcessinlinux_samples.cppparses/proc/[pid]/statfield 23 (RSS pages), ignoring/proc/[pid]/statusor/proc/[pid]/statm(Shared, Text, Data, Lib, Swap). A process consuming gigabytes of shared memory or swap is reported with incomplete memory footprints./diagnosticsand/exporterendpoints inreactor.cppdo not export detailed memory breakdowns or swap saturation gauges.Proposed Technical Architecture & Implementation Plan
1. Model & Protocol Enhancements (
common/include/common/models/memory_metrics.hpp)Extend
MemoryMetricswith structured memory breakdown fields:Update serialization and deserialization in
common/src/common/models/memory_metrics.cppwith backward-compatible JSON schema mappings.2. Collector Implementation (
server/src/collectors/metrics_collector.cpp)MetricsCollector::Memory, expand theKeyValues()lookup:SwapTotal,SwapFree,Cached,Buffers,Shmem,SReclaimable,SUnreclaim,Dirty,Writeback,AnonHugePages,HugePages_Total,HugePages_Free,Hugepagesize./sys/block/zram<id>/mm_stator/sys/block/zram<id>/disksizeviaLinuxSource::Syswhen present to compute compression ratios (orig_data_size / compr_data_size).unavailable.3. Exporter & UI Integration
reactor.cpp(Diagnostics(bool prometheus)), expose:web_htop_memory_swap_used_bytesweb_htop_memory_hugepages_freeweb_htop_memory_slab_bytesweb_htop_memory_zram_compression_ratioclient/src/ui/terminal_ui.cpp, update memory gauge and add an advanced memory breakdown panel displaying Cache/Buffer, Shmem, HugeTLB, and ZRAM/Swap status.Acceptance Criteria
MemoryMetricscontains fields for swap, shared memory, slab reclaimable/unreclaimable, dirty/writeback, hugepages, and zram.tests/common/test_serialization.cppcover all new fields with both complete and missing/legacy payloads.FakeSourceintests/core/test_core.cppis updated with complete/proc/meminfoand/sys/block/zram0fixtures verifying correct calculations and edge cases (e.g. 0 swap, disabled hugepages)./exporterreport the new memory statistics accurately.