#!/bin/bash
# collect <outfile> : append one CSV line every 5s with memory-pressure telemetry.
# columns: epoch, psi_some_avg10, psi_full_avg10, pgmajfault/s, pgpgin_kB/s,
#          pgscan/s, pgsteal/s, MemFree_MB, AnonPages_MB, ActiveFile_MB, InactiveFile_MB, oom_kill_total
out=$1
echo "epoch,psi_some10,psi_full10,majflt_s,pgpgin_kBs,pgscan_s,pgsteal_s,free_MB,anon_MB,act_file_MB,inact_file_MB,oom_kill" >> "$out"
read_vm() { awk -v k="$1" '$1==k {print $2}' /proc/vmstat; }
read_mi() { awk -v k="$1:" '$1==k {print int($2/1024)}' /proc/meminfo; }
prev_maj=$(read_vm pgmajfault); prev_in=$(read_vm pgpgin)
prev_scan=$(( $(read_vm pgscan_kswapd) + $(read_vm pgscan_direct) ))
prev_steal=$(( $(read_vm pgsteal_kswapd) + $(read_vm pgsteal_direct) ))
while sleep 5; do
  maj=$(read_vm pgmajfault); in=$(read_vm pgpgin)
  scan=$(( $(read_vm pgscan_kswapd) + $(read_vm pgscan_direct) ))
  steal=$(( $(read_vm pgsteal_kswapd) + $(read_vm pgsteal_direct) ))
  some=$(awk '/^some/ {split($2,a,"="); print a[2]}' /proc/pressure/memory)
  full=$(awk '/^full/ {split($2,a,"="); print a[2]}' /proc/pressure/memory)
  printf "%s,%s,%s,%d,%d,%d,%d,%d,%d,%d,%d,%d\n" "$(date +%s)" "$some" "$full" \
    $(( (maj-prev_maj)/5 )) $(( (in-prev_in)/5 )) $(( (scan-prev_scan)/5 )) $(( (steal-prev_steal)/5 )) \
    "$(read_mi MemFree)" "$(read_mi AnonPages)" "$(read_mi 'Active(file)')" "$(read_mi 'Inactive(file)')" \
    "$(read_vm oom_kill)" >> "$out"
  prev_maj=$maj; prev_in=$in; prev_scan=$scan; prev_steal=$steal
done
