From 241a19943b7321aa1f2e2ece86b5ad68997390fe Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sun, 24 Oct 2021 11:17:49 +0700 Subject: T3937: rewrite the "show system memory" script in Python --- op-mode-definitions/show-system.xml.in | 2 +- python/vyos/util.py | 34 ++++++++++++++++++ src/op_mode/show_ram.py | 64 ++++++++++++++++++++++++++++++++++ src/op_mode/show_ram.sh | 33 ------------------ 4 files changed, 99 insertions(+), 34 deletions(-) create mode 100755 src/op_mode/show_ram.py delete mode 100755 src/op_mode/show_ram.sh diff --git a/op-mode-definitions/show-system.xml.in b/op-mode-definitions/show-system.xml.in index 18a28868d..b32aee0c2 100644 --- a/op-mode-definitions/show-system.xml.in +++ b/op-mode-definitions/show-system.xml.in @@ -104,7 +104,7 @@ Show system memory usage - ${vyos_op_scripts_dir}/show_ram.sh + ${vyos_op_scripts_dir}/show_ram.py diff --git a/python/vyos/util.py b/python/vyos/util.py index 849b27d3b..2c4051a7a 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -489,6 +489,40 @@ def seconds_to_human(s, separator=""): return result +def bytes_to_human(bytes, initial_exponent=0): + """ Converts a value in bytes to a human-readable size string like 640 KB + + The initial_exponent parameter is the exponent of 2, + e.g. 10 (1024) for kilobytes, 20 (1024 * 1024) for megabytes. + """ + + from math import log2 + + bytes = bytes * (2**initial_exponent) + + # log2 is a float, while range checking requires an int + exponent = int(log2(bytes)) + + if exponent < 10: + value = bytes + suffix = "B" + elif exponent in range(10, 20): + value = bytes / 1024 + suffix = "KB" + elif exponent in range(20, 30): + value = bytes / 1024**2 + suffix = "MB" + elif exponent in range(30, 40): + value = bytes / 1024**3 + suffix = "GB" + else: + value = bytes / 1024**4 + suffix = "TB" + # Add a new case when the first machine with petabyte RAM + # hits the market. + + size_string = "{0:.2f} {1}".format(value, suffix) + return size_string def get_cfg_group_id(): from grp import getgrnam diff --git a/src/op_mode/show_ram.py b/src/op_mode/show_ram.py new file mode 100755 index 000000000..5818ec132 --- /dev/null +++ b/src/op_mode/show_ram.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2021 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +def get_system_memory(): + from re import search as re_search + + def find_value(keyword, mem_data): + regex = keyword + ':\s+(\d+)' + res = re_search(regex, mem_data).group(1) + return int(res) + + with open("/proc/meminfo", "r") as f: + mem_data = f.read() + + total = find_value('MemTotal', mem_data) + available = find_value('MemAvailable', mem_data) + buffers = find_value('Buffers', mem_data) + cached = find_value('Cached', mem_data) + + used = total - available + + res = { + "total": total, + "free": available, + "used": used, + "buffers": buffers, + "cached": cached + } + + return res + +def get_system_memory_human(): + from vyos.util import bytes_to_human + + mem = get_system_memory() + + for key in mem: + # The Linux kernel exposes memory values in kilobytes, + # so we need to normalize them + mem[key] = bytes_to_human(mem[key], initial_exponent=10) + + return mem + +if __name__ == '__main__': + mem = get_system_memory_human() + + print("Total: {}".format(mem["total"])) + print("Free: {}".format(mem["free"])) + print("Used: {}".format(mem["used"])) + diff --git a/src/op_mode/show_ram.sh b/src/op_mode/show_ram.sh deleted file mode 100755 index b013e16f8..000000000 --- a/src/op_mode/show_ram.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -# -# Module: vyos-show-ram.sh -# Displays memory usage information in minimalistic format -# -# Copyright (C) 2019 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -MB_DIVISOR=1024 - -TOTAL=$(cat /proc/meminfo | grep -E "^MemTotal:" | awk -F ' ' '{print $2}') -FREE=$(cat /proc/meminfo | grep -E "^MemFree:" | awk -F ' ' '{print $2}') -BUFFERS=$(cat /proc/meminfo | grep -E "^Buffers:" | awk -F ' ' '{print $2}') -CACHED=$(cat /proc/meminfo | grep -E "^Cached:" | awk -F ' ' '{print $2}') - -DISPLAY_FREE=$(( ($FREE + $BUFFERS + $CACHED) / $MB_DIVISOR )) -DISPLAY_TOTAL=$(( $TOTAL / $MB_DIVISOR )) -DISPLAY_USED=$(( $DISPLAY_TOTAL - $DISPLAY_FREE )) - -echo "Total: $DISPLAY_TOTAL" -echo "Free: $DISPLAY_FREE" -echo "Used: $DISPLAY_USED" -- cgit v1.2.3