memguard.py 1.2 KB

12345678910111213141516171819202122232425
  1. #!/usr/bin/env python3
  2. """Memory guard: sample the head's MemAvailable every second over ssh-less HTTP? No: run ON the head.
  3. Usage (on the head): python3 memguard.py <logfile> [threshold_gb]
  4. Writes 'ts memavail_gb' lines; on breach POSTs /abort_request to the server and writes ABORT line."""
  5. import sys, time, json, urllib.request
  6. log = open(sys.argv[1], 'a', buffering=1)
  7. thr = float(sys.argv[2]) if len(sys.argv) > 2 else 1.5
  8. minv = 1e9
  9. while True:
  10. with open('/proc/meminfo') as f:
  11. for line in f:
  12. if line.startswith('MemAvailable'):
  13. gb = int(line.split()[1]) / 1024 / 1024
  14. break
  15. minv = min(minv, gb)
  16. log.write(f'{time.strftime("%H:%M:%S")} {gb:.2f} min={minv:.2f}\n')
  17. if gb < thr:
  18. log.write(f'{time.strftime("%H:%M:%S")} ABORT: MemAvailable {gb:.2f} GB < {thr} GB -> POST /abort_request\n')
  19. try:
  20. req = urllib.request.Request('http://127.0.0.1:8888/abort_request', data=json.dumps({'abort_all': True}).encode(), headers={'Content-Type': 'application/json'})
  21. urllib.request.urlopen(req, timeout=5).read()
  22. log.write('abort_request sent\n')
  23. except Exception as e:
  24. log.write(f'abort_request failed: {e}\n')
  25. time.sleep(1)