Gracefully degrade under load, fixes #2

This commit is contained in:
Martinez 2016-10-06 11:42:15 +02:00
parent 79b47e1130
commit 3358c807a0

View file

@ -268,14 +268,15 @@ class PathPart(Part):
"""
/path/to/cwd
Contructs a list of Dirs from the root to CWD. When fit is called, some Dirs may be shortened.
Contructs a list of Dirs from the root to CWD. When shrink_fit is called, some Dirs may be shortened.
"""
def __init__(self, settings):
def __init__(self, settings, overloaded):
Part.__init__(self)
self.term_width = settings.term_width
self.dirs = []
homes = dict(list_homes())
homes = {} if overloaded else dict(list_homes())
dirs = settings.cwd.split("/")[1:]
path = ""
@ -490,126 +491,135 @@ class StatsPart(Part):
# tasks
self.fragments.append("%d " %(sysload.tasks_total))
# memory (and swap, if used)
mem_total = 0
mem_free = 0
swap_total = 0
swap_free = 0
# MemAvailable is not available on <linux-3.14 and we'll bitch about that
old_linux = True
with open("/proc/meminfo") as f:
for line in f:
if line.startswith("MemTotal"):
mem_total = int(line.split()[1]) * 1024
elif line.startswith("MemAvailable"):
mem_free = int(line.split()[1]) * 1024
old_linux = False
elif line.startswith("SwapTotal"):
swap_total = int(line.split()[1]) * 1024
elif line.startswith("SwapFree"):
swap_free = int(line.split()[1]) * 1024
if old_linux:
if sysload.load1 >= settings.load_error:
self.fragments.append(" | ")
self.fragments.append(style_color(COLOR_ERROR))
self.fragments.append(style_bold())
self.fragments.append("❌ <linux-3.14 ❌")
else:
self.fragments.append(style_color(COLOR_MEMSWAP))
self.fragments.append("m")
self.fragments.append(style_bold())
self.fragments.append(style_color(settings.get_space_color(mem_free, mem_total)))
mem_free_si = si_number(mem_free)
self.fragments.append(space_string(mem_free) %(mem_free_si[0], mem_free_si[1]))
self.fragments.append(style_reset())
if swap_total - swap_free > 2**20:
self.fragments.append(style_color(COLOR_MEMSWAP))
self.fragments.append(" s")
self.fragments.append(style_bold())
self.fragments.append(style_color(settings.get_space_color(swap_free, swap_total)))
swap_free_si = si_number(swap_free)
self.fragments.append(space_string(swap_free) %(swap_free_si[0], swap_free_si[1]))
self.fragments.append("⚠ OVERLOAD ⚠ ")
self.fragments.append(style_reset())
# mountpoints
names = []
first_mountpoint = True
with open("/proc/self/mounts") as f:
for line in f:
_, dir, type, options, *rest = line.split()
# skip non-storage mounts
if type in MOUNT_IGNORE_FS:
continue
if any([dir.startswith(d) for d in MOUNT_IGNORE_DIR]):
continue
if "rw" not in options.split(","):
continue
# /proc/self/mounts uses a literal \040 string to escape spaces
dir = dir.replace("\\040", " ")
basename = os.path.basename(dir)
if basename:
short_name = " "
else:
# memory (and swap, if used)
mem_total = 0
mem_free = 0
swap_total = 0
swap_free = 0
# MemAvailable is not available on <linux-3.14 and we'll bitch about that
old_linux = True
with open("/proc/meminfo") as f:
for line in f:
if line.startswith("MemTotal"):
mem_total = int(line.split()[1]) * 1024
elif line.startswith("MemAvailable"):
mem_free = int(line.split()[1]) * 1024
old_linux = False
elif line.startswith("SwapTotal"):
swap_total = int(line.split()[1]) * 1024
elif line.startswith("SwapFree"):
swap_free = int(line.split()[1]) * 1024
if old_linux:
self.fragments.append(style_color(COLOR_ERROR))
self.fragments.append(style_bold())
self.fragments.append("⚠ <linux-3.14 ⚠")
else:
self.fragments.append(style_color(COLOR_MEMSWAP))
self.fragments.append("m")
self.fragments.append(style_bold())
self.fragments.append(style_color(settings.get_space_color(mem_free, mem_total)))
mem_free_si = si_number(mem_free)
self.fragments.append(space_string(mem_free) %(mem_free_si[0], mem_free_si[1]))
self.fragments.append(style_reset())
if swap_total - swap_free > 2**20:
self.fragments.append(style_color(COLOR_MEMSWAP))
self.fragments.append(" s")
self.fragments.append(style_bold())
self.fragments.append(style_color(settings.get_space_color(swap_free, swap_total)))
swap_free_si = si_number(swap_free)
self.fragments.append(space_string(swap_free) %(swap_free_si[0], swap_free_si[1]))
self.fragments.append(style_reset())
# mountpoints
names = []
first_mountpoint = True
with open("/proc/self/mounts") as f:
for line in f:
_, dir, type, options, *rest = line.split()
for c in basename:
short_name += c
if short_name not in names:
break
else:
short_name = " /"
# handle btrfs separately
if type == "btrfs":
btrfs_raw = command(["/sbin/btrfs", "fi", "usage", "-b", dir])
for line in btrfs_raw.split("\n"):
if "Device size" in line:
stor_total = int(line.split()[-1])
elif "Free" in line:
stor_free = int(line.split()[-3])
break
else:
try:
stat = os.statvfs(dir)
except PermissionError:
# skip non-storage mounts
if type in MOUNT_IGNORE_FS:
continue
stor_total = stat.f_blocks * stat.f_bsize
stor_free = stat.f_bavail * stat.f_bsize
# ignore virtual filesystems
if stor_total == 0:
continue
if first_mountpoint:
self.fragments.append(" |")
first_mountpoint = False
self.fragments.append(short_name)
self.fragments.append(style_bold())
self.fragments.append(style_color(settings.get_space_color(stor_free, stor_total)))
stor_free_si = si_number(stor_free)
self.fragments.append(space_string(stor_free) %(stor_free_si[0], stor_free_si[1]))
self.fragments.append(style_reset())
if any([dir.startswith(d) for d in MOUNT_IGNORE_DIR]):
continue
if "rw" not in options.split(","):
continue
# /proc/self/mounts uses a literal \040 string to escape spaces
dir = dir.replace("\\040", " ")
basename = os.path.basename(dir)
if basename:
short_name = " "
for c in basename:
short_name += c
if short_name not in names:
break
else:
short_name = " /"
# handle btrfs separately
if type == "btrfs":
btrfs_raw = command(["/sbin/btrfs", "fi", "usage", "-b", dir])
for line in btrfs_raw.split("\n"):
if "Device size" in line:
stor_total = int(line.split()[-1])
elif "Free" in line:
stor_free = int(line.split()[-3])
break
else:
try:
stat = os.statvfs(dir)
except PermissionError:
continue
stor_total = stat.f_blocks * stat.f_bsize
stor_free = stat.f_bavail * stat.f_bsize
# ignore virtual filesystems
if stor_total == 0:
continue
if first_mountpoint:
self.fragments.append(" |")
first_mountpoint = False
self.fragments.append(short_name)
self.fragments.append(style_bold())
self.fragments.append(style_color(settings.get_space_color(stor_free, stor_total)))
stor_free_si = si_number(stor_free)
self.fragments.append(space_string(stor_free) %(stor_free_si[0], stor_free_si[1]))
self.fragments.append(style_reset())
if __name__ == "__main__":
settings = Settings(sys.argv)
sysload = Sysload()
overloaded = sysload.load1 >= settings.load_error
lp = LoginPart(settings, sysload)
pp = PathPart(settings)
gp = GitPart()
pp = PathPart(settings, overloaded)
gp = "" if overloaded else GitPart()
vp = VirtualEnvPart()
wp = WineprefixPart()
pad = Padding(settings.term_width)