[+] update oom_firefox
1. fix rss being in KiB;
2. get rid of --slice, use --unit-name;
3. fix columns strings being cut,
use two calls to ps,
to get full cmd and cgroup;
4. tested manually that it works;
This commit is contained in:
parent
7d5868345b
commit
a8d0f64419
@ -19,6 +19,7 @@ from prompt_toolkit.widgets import TextArea, Frame, Dialog, Button, Label
|
||||
from prompt_toolkit.styles import Style
|
||||
|
||||
from typing import (TypedDict,)
|
||||
from collections import OrderedDict
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -64,34 +65,59 @@ class get_firefox_procs_ps_t:
|
||||
cmd: str
|
||||
|
||||
def get_firefox_procs_ps(slice_name=None) -> list[get_firefox_procs_ps_t.res_t.entry_t]:
|
||||
lines = subprocess.check_output([
|
||||
'ps', '-ax', '-o', 'rss,pid,ppid,cgroup,cmd'
|
||||
]).decode('utf-8').splitlines()[1:]
|
||||
entries : dict[int, dict[str, Any]] = dict()
|
||||
|
||||
entries : list[dict[str, str]] = []
|
||||
for regex, columns in [
|
||||
(
|
||||
re.compile(r'^\s*(\d+)\s+(\d+)\s+(\d+)\s+(.*)$'),
|
||||
OrderedDict(
|
||||
pid=lambda x: int(x[1]),
|
||||
rss=lambda x: int(x[2]) * 1024,
|
||||
ppid=lambda x: int(x[3]),
|
||||
cmd=lambda x: x[4],
|
||||
),
|
||||
),
|
||||
(
|
||||
re.compile(r'^\s*(\d+)\s+(.*)$'),
|
||||
OrderedDict(
|
||||
pid=lambda x: int(x[1]),
|
||||
cgroup=lambda x: x[2],
|
||||
),
|
||||
),
|
||||
]:
|
||||
lines = subprocess.check_output([
|
||||
'ps', '-ax', '-o', ','.join(columns.keys()),
|
||||
]).decode('utf-8').splitlines()[1:]
|
||||
|
||||
for line in lines:
|
||||
r = re.compile(r'^\s*(\d+)\s+(\d+)\s+(\d+)\s+([^\s]+)\s+(.*)$')
|
||||
# print([r, line])
|
||||
match = r.match(line)
|
||||
for line in lines:
|
||||
r = re.compile(regex)
|
||||
# print([r, line])
|
||||
match = r.match(line)
|
||||
|
||||
assert match
|
||||
assert match
|
||||
|
||||
entry = dict(
|
||||
rss=int(match[1]),
|
||||
pid=int(match[2]),
|
||||
ppid=int(match[3]),
|
||||
cgroup=match[4],
|
||||
cmd=match[5],
|
||||
)
|
||||
entry = {
|
||||
k : v(match)
|
||||
for k, v in columns.items()
|
||||
}
|
||||
|
||||
if not entry['pid'] in entries:
|
||||
entries[entry['pid']] = dict()
|
||||
|
||||
entries[entry['pid']].update(entry)
|
||||
|
||||
filtered_entries : list[dict[str, Any]] = []
|
||||
|
||||
for entry in entries.values():
|
||||
if not 'cgroup' in entry or not 'rss' in entry:
|
||||
continue
|
||||
|
||||
if not slice_name is None:
|
||||
if not slice_name in entry['cgroup']:
|
||||
continue
|
||||
filtered_entries.append(entry)
|
||||
|
||||
entries.append(entry)
|
||||
|
||||
return entries
|
||||
return filtered_entries
|
||||
|
||||
def get_firefox_procs(slice_name=None):
|
||||
procs = []
|
||||
@ -126,9 +152,11 @@ def total_rss_mb(procs: list['get_firefox_procs_ps_t.res_t.entry_t']):
|
||||
def is_main_firefox(p):
|
||||
try:
|
||||
# for arg in p.cmdline():
|
||||
for arg in p['cmd'].split():
|
||||
if "contentproc" in arg:
|
||||
return False
|
||||
#for arg in p['cmd'].split():
|
||||
# if "contentproc" in arg:
|
||||
# return False
|
||||
if 'contentproc' in p['cmd']:
|
||||
return False
|
||||
return True
|
||||
except Exception:
|
||||
logger.exception('')
|
||||
@ -203,8 +231,6 @@ def main():
|
||||
help="MemorySwapMax (MB) for the systemd scope")
|
||||
parser.add_argument("--interval", type=float, default=1.0,
|
||||
help="Monitoring interval in seconds")
|
||||
parser.add_argument("--slice", type=str, default=None,
|
||||
help="Only monitor Firefox processes in this systemd slice")
|
||||
parser.add_argument("--unit-name", type=str, default="firefox-limited",
|
||||
help="Name for systemd transient unit")
|
||||
parser.add_argument("--firefox-extra", action="append", default=[],
|
||||
@ -225,6 +251,7 @@ def main():
|
||||
|
||||
def terminate():
|
||||
terminate_flag.set()
|
||||
app.exit()
|
||||
|
||||
def stop():
|
||||
with lock:
|
||||
@ -248,13 +275,13 @@ def main():
|
||||
nonlocal firefox_proc
|
||||
|
||||
with lock:
|
||||
procs = get_firefox_procs_ps(slice_name=args.slice)
|
||||
procs = get_firefox_procs_ps(slice_name=args.unit_name)
|
||||
total = total_rss_mb(procs)
|
||||
limit = args.max_mb
|
||||
kill_to = args.kill_percent / 100.0 * limit
|
||||
|
||||
lines = [
|
||||
f"Firefox RSS (slice={args.slice}): {total:.1f} MB",
|
||||
f"Firefox RSS (slice={args.unit_name}): {total:.1f} MB",
|
||||
f"Threshold (max): {limit:.1f} MB",
|
||||
f"Kill‑to target: {kill_to:.1f} MB ({args.kill_percent}%)",
|
||||
f"Low‑priority PIDs: {sorted(low_priority_pids)}"
|
||||
@ -350,7 +377,7 @@ def main():
|
||||
open_message("Settings",
|
||||
f"max_mb = {args.max_mb}\n"
|
||||
f"kill_percent = {args.kill_percent}\n"
|
||||
f"slice = {args.slice}\n"
|
||||
f"slice = {args.unit_name}\n"
|
||||
f"swap_max_mb = {args.swap_max_mb}\n"
|
||||
f"extra firefox args = {args.firefox_extra}")
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user