mirror of https://github.com/aristocratos/bpytop
Added option to show memory in bytes for processes, enabled by default
parent
99f9b0828b
commit
d38d74d92f
44
bpytop.py
44
bpytop.py
|
@ -120,6 +120,9 @@ proc_gradient=$proc_gradient
|
||||||
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
|
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power.
|
||||||
proc_per_core=$proc_per_core
|
proc_per_core=$proc_per_core
|
||||||
|
|
||||||
|
#* Show process memory as bytes instead of percent
|
||||||
|
proc_mem_bytes=$proc_mem_bytes
|
||||||
|
|
||||||
#* Check cpu temperature, needs "vcgencmd" on Raspberry Pi and "osx-cpu-temp" on MacOS X.
|
#* Check cpu temperature, needs "vcgencmd" on Raspberry Pi and "osx-cpu-temp" on MacOS X.
|
||||||
check_temp=$check_temp
|
check_temp=$check_temp
|
||||||
|
|
||||||
|
@ -320,7 +323,8 @@ def timeit_decorator(func):
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
'''Holds all config variables and functions for loading from and saving to disk'''
|
'''Holds all config variables and functions for loading from and saving to disk'''
|
||||||
keys: List[str] = ["color_theme", "update_ms", "proc_sorting", "proc_reversed", "proc_tree", "check_temp", "draw_clock", "background_update", "custom_cpu_name", "proc_colors", "proc_gradient", "proc_per_core", "disks_filter", "update_check", "log_level", "mem_graphs", "show_swap", "swap_disk", "show_disks", "show_init", "mini_mode"]
|
keys: List[str] = ["color_theme", "update_ms", "proc_sorting", "proc_reversed", "proc_tree", "check_temp", "draw_clock", "background_update", "custom_cpu_name", "proc_colors", "proc_gradient", "proc_per_core", "proc_mem_bytes",
|
||||||
|
"disks_filter", "update_check", "log_level", "mem_graphs", "show_swap", "swap_disk", "show_disks", "show_init", "mini_mode"]
|
||||||
conf_dict: Dict[str, Union[str, int, bool]] = {}
|
conf_dict: Dict[str, Union[str, int, bool]] = {}
|
||||||
color_theme: str = "Default"
|
color_theme: str = "Default"
|
||||||
update_ms: int = 2000
|
update_ms: int = 2000
|
||||||
|
@ -330,6 +334,7 @@ class Config:
|
||||||
proc_colors: bool = True
|
proc_colors: bool = True
|
||||||
proc_gradient: bool = True
|
proc_gradient: bool = True
|
||||||
proc_per_core: bool = False
|
proc_per_core: bool = False
|
||||||
|
proc_mem_bytes: bool = True
|
||||||
check_temp: bool = True
|
check_temp: bool = True
|
||||||
draw_clock: str = "%X"
|
draw_clock: str = "%X"
|
||||||
background_update: bool = True
|
background_update: bool = True
|
||||||
|
@ -1558,7 +1563,7 @@ class CpuBox(Box, SubBox):
|
||||||
if cy < bh - 1: cy = bh - 1
|
if cy < bh - 1: cy = bh - 1
|
||||||
|
|
||||||
if cls.column_size == 2 and cpu.got_sensors:
|
if cls.column_size == 2 and cpu.got_sensors:
|
||||||
lavg = f' Load AVG: {" ".join(str(l) for l in cpu.load_avg):^18.18}'
|
lavg = f' Load AVG: {" ".join(str(l) for l in cpu.load_avg):^19.19}'
|
||||||
elif cls.column_size == 2 or (cls.column_size == 1 and cpu.got_sensors):
|
elif cls.column_size == 2 or (cls.column_size == 1 and cpu.got_sensors):
|
||||||
lavg = f'LAV: {" ".join(str(l) for l in cpu.load_avg):^14.14}'
|
lavg = f'LAV: {" ".join(str(l) for l in cpu.load_avg):^14.14}'
|
||||||
elif cls.column_size == 1 or (cls.column_size == 0 and cpu.got_sensors):
|
elif cls.column_size == 1 or (cls.column_size == 0 and cpu.got_sensors):
|
||||||
|
@ -2130,7 +2135,9 @@ class ProcBox(Box):
|
||||||
(" " if proc.num_procs > cls.select_max else ""))
|
(" " if proc.num_procs > cls.select_max else ""))
|
||||||
if selected == "program" and prog_len <= 8: selected = "prg"
|
if selected == "program" and prog_len <= 8: selected = "prg"
|
||||||
selected = selected.split(" ")[0].capitalize()
|
selected = selected.split(" ")[0].capitalize()
|
||||||
out_misc += label.replace(selected, f'{Fx.u}{selected}{Fx.uu}')
|
if CONFIG.proc_mem_bytes: label = label.replace("Mem%", "MemB")
|
||||||
|
label = label.replace(selected, f'{Fx.u}{selected}{Fx.uu}')
|
||||||
|
out_misc += label
|
||||||
|
|
||||||
Draw.buffer("proc_misc", out_misc, only_save=True)
|
Draw.buffer("proc_misc", out_misc, only_save=True)
|
||||||
|
|
||||||
|
@ -2184,7 +2191,7 @@ class ProcBox(Box):
|
||||||
cls.selected_pid = pid
|
cls.selected_pid = pid
|
||||||
else: is_selected = False
|
else: is_selected = False
|
||||||
|
|
||||||
indent, name, cmd, threads, username, mem, cpu = [items.get(v, d) for v, d in [("indent", ""), ("name", ""), ("cmd", ""), ("threads", 0), ("username", "?"), ("mem", 0.0), ("cpu", 0.0)]]
|
indent, name, cmd, threads, username, mem, mem_b, cpu = [items.get(v, d) for v, d in [("indent", ""), ("name", ""), ("cmd", ""), ("threads", 0), ("username", "?"), ("mem", 0.0), ("mem_b", 0), ("cpu", 0.0)]]
|
||||||
|
|
||||||
if CONFIG.proc_tree:
|
if CONFIG.proc_tree:
|
||||||
offset = tree_len - len(f'{indent}{pid}')
|
offset = tree_len - len(f'{indent}{pid}')
|
||||||
|
@ -2230,7 +2237,7 @@ class ProcBox(Box):
|
||||||
(f'{g_color}{cmd:<{arg_len}.{arg_len-1}}' if arg_len else "") +
|
(f'{g_color}{cmd:<{arg_len}.{arg_len-1}}' if arg_len else "") +
|
||||||
t_color + (f'{threads:>4} ' if threads < 1000 else "999> ") + end +
|
t_color + (f'{threads:>4} ' if threads < 1000 else "999> ") + end +
|
||||||
g_color + (f'{username:<9.9}' if len(username) < 10 else f'{username[:8]:<8}+') +
|
g_color + (f'{username:<9.9}' if len(username) < 10 else f'{username[:8]:<8}+') +
|
||||||
m_color + (f'{mem:>4.1f}' if mem < 100 else f'{mem:>4.0f} ') + end +
|
m_color + ((f'{mem:>4.1f}' if mem < 100 else f'{mem:>4.0f} ') if not CONFIG.proc_mem_bytes else f'{floating_humanizer(mem_b, short=True):>4.4}') + end +
|
||||||
f' {THEME.inactive_fg}{"⡀"*5}{THEME.main_fg}{g_color}{c_color}' + (f' {cpu:>4.1f} ' if cpu < 100 else f'{cpu:>5.0f} ') + end +
|
f' {THEME.inactive_fg}{"⡀"*5}{THEME.main_fg}{g_color}{c_color}' + (f' {cpu:>4.1f} ' if cpu < 100 else f'{cpu:>5.0f} ') + end +
|
||||||
(" " if proc.num_procs > cls.select_max else ""))
|
(" " if proc.num_procs > cls.select_max else ""))
|
||||||
|
|
||||||
|
@ -2905,7 +2912,7 @@ class ProcCollector(Collector): #! add interrupt on _collect and _draw
|
||||||
if CONFIG.proc_tree:
|
if CONFIG.proc_tree:
|
||||||
cls._tree(sort_cmd=sort_cmd, reverse=reverse, proc_per_cpu=proc_per_cpu, search=search)
|
cls._tree(sort_cmd=sort_cmd, reverse=reverse, proc_per_cpu=proc_per_cpu, search=search)
|
||||||
else:
|
else:
|
||||||
for p in sorted(psutil.process_iter(cls.p_values, err), key=lambda p: eval(sort_cmd), reverse=reverse):
|
for p in sorted(psutil.process_iter(cls.p_values + ["memory_info"] if CONFIG.proc_mem_bytes else [], err), key=lambda p: eval(sort_cmd), reverse=reverse):
|
||||||
if cls.collect_interrupt or cls.proc_interrupt:
|
if cls.collect_interrupt or cls.proc_interrupt:
|
||||||
return
|
return
|
||||||
if p.info["name"] == "idle" or p.info["name"] == err or p.info["pid"] == err:
|
if p.info["name"] == "idle" or p.info["name"] == err or p.info["pid"] == err:
|
||||||
|
@ -2929,6 +2936,10 @@ class ProcCollector(Collector): #! add interrupt on _collect and _draw
|
||||||
|
|
||||||
cpu = p.info["cpu_percent"] if proc_per_cpu else (p.info["cpu_percent"] / psutil.cpu_count())
|
cpu = p.info["cpu_percent"] if proc_per_cpu else (p.info["cpu_percent"] / psutil.cpu_count())
|
||||||
mem = p.info["memory_percent"]
|
mem = p.info["memory_percent"]
|
||||||
|
if CONFIG.proc_mem_bytes and hasattr(p.info["memory_info"], "rss"):
|
||||||
|
mem_b = p.info["memory_info"].rss
|
||||||
|
else:
|
||||||
|
mem_b = 0
|
||||||
|
|
||||||
cmd = " ".join(p.info["cmdline"]) or "[" + p.info["name"] + "]"
|
cmd = " ".join(p.info["cmdline"]) or "[" + p.info["name"] + "]"
|
||||||
|
|
||||||
|
@ -2938,6 +2949,7 @@ class ProcCollector(Collector): #! add interrupt on _collect and _draw
|
||||||
"threads" : p.info["num_threads"],
|
"threads" : p.info["num_threads"],
|
||||||
"username" : p.info["username"],
|
"username" : p.info["username"],
|
||||||
"mem" : mem,
|
"mem" : mem,
|
||||||
|
"mem_b" : mem_b,
|
||||||
"cpu" : cpu }
|
"cpu" : cpu }
|
||||||
|
|
||||||
n += 1
|
n += 1
|
||||||
|
@ -3036,7 +3048,7 @@ class ProcCollector(Collector): #! add interrupt on _collect and _draw
|
||||||
infolist: Dict = {}
|
infolist: Dict = {}
|
||||||
tree = defaultdict(list)
|
tree = defaultdict(list)
|
||||||
n: int = 0
|
n: int = 0
|
||||||
for p in sorted(psutil.process_iter(cls.p_values, err), key=lambda p: eval(sort_cmd), reverse=reverse):
|
for p in sorted(psutil.process_iter(cls.p_values + ["memory_info"] if CONFIG.proc_mem_bytes else [], err), key=lambda p: eval(sort_cmd), reverse=reverse):
|
||||||
if cls.collect_interrupt: return
|
if cls.collect_interrupt: return
|
||||||
try:
|
try:
|
||||||
tree[p.ppid()].append(p.pid)
|
tree[p.ppid()].append(p.pid)
|
||||||
|
@ -3087,8 +3099,12 @@ class ProcCollector(Collector): #! add interrupt on _collect and _draw
|
||||||
mem = getinfo["memory_percent"]
|
mem = getinfo["memory_percent"]
|
||||||
if getinfo["cmdline"] == err: cmd = ""
|
if getinfo["cmdline"] == err: cmd = ""
|
||||||
else: cmd = " ".join(getinfo["cmdline"]) or "[" + getinfo["name"] + "]"
|
else: cmd = " ".join(getinfo["cmdline"]) or "[" + getinfo["name"] + "]"
|
||||||
|
if CONFIG.proc_mem_bytes and hasattr(getinfo["memory_info"], "rss"):
|
||||||
|
mem_b = getinfo["memory_info"].rss
|
||||||
|
else:
|
||||||
|
mem_b = 0
|
||||||
else:
|
else:
|
||||||
threads = 0
|
threads = mem_b = 0
|
||||||
username = ""
|
username = ""
|
||||||
mem = cpu = 0.0
|
mem = cpu = 0.0
|
||||||
|
|
||||||
|
@ -3099,6 +3115,7 @@ class ProcCollector(Collector): #! add interrupt on _collect and _draw
|
||||||
"threads" : threads,
|
"threads" : threads,
|
||||||
"username" : username,
|
"username" : username,
|
||||||
"mem" : mem,
|
"mem" : mem,
|
||||||
|
"mem_b" : mem_b,
|
||||||
"cpu" : cpu }
|
"cpu" : cpu }
|
||||||
|
|
||||||
if pid not in tree:
|
if pid not in tree:
|
||||||
|
@ -3453,6 +3470,11 @@ class Menu:
|
||||||
'',
|
'',
|
||||||
'If true and process is multithreaded',
|
'If true and process is multithreaded',
|
||||||
'cpu usage can reach over 100%.'],
|
'cpu usage can reach over 100%.'],
|
||||||
|
"proc_mem_bytes" : [
|
||||||
|
'Show memory as bytes in process list.',
|
||||||
|
' ',
|
||||||
|
'True or False.'
|
||||||
|
],
|
||||||
"check_temp" : [
|
"check_temp" : [
|
||||||
'Enable cpu temperature reporting.',
|
'Enable cpu temperature reporting.',
|
||||||
'',
|
'',
|
||||||
|
@ -3926,7 +3948,11 @@ def floating_humanizer(value: Union[float, int], bit: bool = False, per_second:
|
||||||
out = f'{value}'
|
out = f'{value}'
|
||||||
|
|
||||||
|
|
||||||
if short: out = out.split(".")[0]
|
if short:
|
||||||
|
out = out.split(".")[0]
|
||||||
|
if len(out) > 3:
|
||||||
|
out = f'{int(out[0]) + 1}'
|
||||||
|
selector += 1
|
||||||
out += f'{"" if short else " "}{unit[selector][0] if short else unit[selector]}'
|
out += f'{"" if short else " "}{unit[selector][0] if short else unit[selector]}'
|
||||||
if per_second: out += "ps" if bit else "/s"
|
if per_second: out += "ps" if bit else "/s"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue