Files
ProxMenux/AppImage/scripts/zram_metrics.py
T

69 lines
2.2 KiB
Python
Raw Normal View History

"""Read zram swap metrics from procfs and sysfs."""
import re
from pathlib import Path
def _swap_usage(swaps_path):
usage = {}
try:
lines = Path(swaps_path).read_text(encoding="utf-8").splitlines()
except OSError:
return usage
for line in lines[1:]:
fields = line.split()
if len(fields) < 4:
continue
name = Path(fields[0]).name
if not re.fullmatch(r"zram\d+", name):
continue
try:
usage[name] = int(fields[3]) * 1024
except ValueError:
continue
return usage
def read_zram_metrics(sys_block_root="/sys/block", swaps_path="/proc/swaps"):
"""Return zram device counters with byte units and active swap usage."""
root = Path(sys_block_root)
try:
device_paths = sorted(
path for path in root.iterdir()
if path.is_dir() and re.fullmatch(r"zram\d+", path.name)
)
except OSError:
device_paths = []
swap_usage = _swap_usage(swaps_path)
devices = []
for path in device_paths:
try:
capacity = int((path / "disksize").read_text(encoding="utf-8").strip())
counters = (path / "mm_stat").read_text(encoding="utf-8").split()
if len(counters) < 3:
continue
original, compressed, memory_used = map(int, counters[:3])
if min(capacity, original, compressed, memory_used) < 0:
continue
algorithms = (path / "comp_algorithm").read_text(encoding="utf-8")
except (OSError, ValueError):
continue
selected = re.search(r"\[([^\]]+)\]", algorithms)
devices.append({
"name": path.name,
"active": path.name in swap_usage,
"capacity_bytes": capacity,
"swap_used_bytes": swap_usage.get(path.name, 0),
"original_bytes": original,
"compressed_bytes": compressed,
"memory_used_bytes": memory_used,
"algorithm": selected.group(1) if selected else None,
"compression_ratio": original / compressed if compressed else None,
"saved_bytes": original - memory_used,
})
return {"available": bool(devices), "devices": devices}