[+] 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 prompt_toolkit.styles import Style
|
||||||
|
|
||||||
from typing import (TypedDict,)
|
from typing import (TypedDict,)
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -64,34 +65,59 @@ class get_firefox_procs_ps_t:
|
|||||||
cmd: str
|
cmd: str
|
||||||
|
|
||||||
def get_firefox_procs_ps(slice_name=None) -> list[get_firefox_procs_ps_t.res_t.entry_t]:
|
def get_firefox_procs_ps(slice_name=None) -> list[get_firefox_procs_ps_t.res_t.entry_t]:
|
||||||
|
entries : dict[int, dict[str, Any]] = dict()
|
||||||
|
|
||||||
|
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([
|
lines = subprocess.check_output([
|
||||||
'ps', '-ax', '-o', 'rss,pid,ppid,cgroup,cmd'
|
'ps', '-ax', '-o', ','.join(columns.keys()),
|
||||||
]).decode('utf-8').splitlines()[1:]
|
]).decode('utf-8').splitlines()[1:]
|
||||||
|
|
||||||
entries : list[dict[str, str]] = []
|
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
r = re.compile(r'^\s*(\d+)\s+(\d+)\s+(\d+)\s+([^\s]+)\s+(.*)$')
|
r = re.compile(regex)
|
||||||
# print([r, line])
|
# print([r, line])
|
||||||
match = r.match(line)
|
match = r.match(line)
|
||||||
|
|
||||||
assert match
|
assert match
|
||||||
|
|
||||||
entry = dict(
|
entry = {
|
||||||
rss=int(match[1]),
|
k : v(match)
|
||||||
pid=int(match[2]),
|
for k, v in columns.items()
|
||||||
ppid=int(match[3]),
|
}
|
||||||
cgroup=match[4],
|
|
||||||
cmd=match[5],
|
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 is None:
|
||||||
if not slice_name in entry['cgroup']:
|
if not slice_name in entry['cgroup']:
|
||||||
continue
|
continue
|
||||||
|
filtered_entries.append(entry)
|
||||||
|
|
||||||
entries.append(entry)
|
return filtered_entries
|
||||||
|
|
||||||
return entries
|
|
||||||
|
|
||||||
def get_firefox_procs(slice_name=None):
|
def get_firefox_procs(slice_name=None):
|
||||||
procs = []
|
procs = []
|
||||||
@ -126,8 +152,10 @@ def total_rss_mb(procs: list['get_firefox_procs_ps_t.res_t.entry_t']):
|
|||||||
def is_main_firefox(p):
|
def is_main_firefox(p):
|
||||||
try:
|
try:
|
||||||
# for arg in p.cmdline():
|
# for arg in p.cmdline():
|
||||||
for arg in p['cmd'].split():
|
#for arg in p['cmd'].split():
|
||||||
if "contentproc" in arg:
|
# if "contentproc" in arg:
|
||||||
|
# return False
|
||||||
|
if 'contentproc' in p['cmd']:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -203,8 +231,6 @@ def main():
|
|||||||
help="MemorySwapMax (MB) for the systemd scope")
|
help="MemorySwapMax (MB) for the systemd scope")
|
||||||
parser.add_argument("--interval", type=float, default=1.0,
|
parser.add_argument("--interval", type=float, default=1.0,
|
||||||
help="Monitoring interval in seconds")
|
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",
|
parser.add_argument("--unit-name", type=str, default="firefox-limited",
|
||||||
help="Name for systemd transient unit")
|
help="Name for systemd transient unit")
|
||||||
parser.add_argument("--firefox-extra", action="append", default=[],
|
parser.add_argument("--firefox-extra", action="append", default=[],
|
||||||
@ -225,6 +251,7 @@ def main():
|
|||||||
|
|
||||||
def terminate():
|
def terminate():
|
||||||
terminate_flag.set()
|
terminate_flag.set()
|
||||||
|
app.exit()
|
||||||
|
|
||||||
def stop():
|
def stop():
|
||||||
with lock:
|
with lock:
|
||||||
@ -248,13 +275,13 @@ def main():
|
|||||||
nonlocal firefox_proc
|
nonlocal firefox_proc
|
||||||
|
|
||||||
with lock:
|
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)
|
total = total_rss_mb(procs)
|
||||||
limit = args.max_mb
|
limit = args.max_mb
|
||||||
kill_to = args.kill_percent / 100.0 * limit
|
kill_to = args.kill_percent / 100.0 * limit
|
||||||
|
|
||||||
lines = [
|
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"Threshold (max): {limit:.1f} MB",
|
||||||
f"Kill‑to target: {kill_to:.1f} MB ({args.kill_percent}%)",
|
f"Kill‑to target: {kill_to:.1f} MB ({args.kill_percent}%)",
|
||||||
f"Low‑priority PIDs: {sorted(low_priority_pids)}"
|
f"Low‑priority PIDs: {sorted(low_priority_pids)}"
|
||||||
@ -350,7 +377,7 @@ def main():
|
|||||||
open_message("Settings",
|
open_message("Settings",
|
||||||
f"max_mb = {args.max_mb}\n"
|
f"max_mb = {args.max_mb}\n"
|
||||||
f"kill_percent = {args.kill_percent}\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"swap_max_mb = {args.swap_max_mb}\n"
|
||||||
f"extra firefox args = {args.firefox_extra}")
|
f"extra firefox args = {args.firefox_extra}")
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user