]> git.sur5r.net Git - i3/i3status/commitdiff
Simplify the memory thresholds 270/head
authorBenedikt Heine <bebe@bebehei.de>
Mon, 16 Apr 2018 16:18:50 +0000 (18:18 +0200)
committerFelix Buehler <account@buehler.rocks>
Fri, 4 May 2018 16:46:59 +0000 (18:46 +0200)
i3status.c
i3status.conf
include/i3status.h
man/i3status.man
src/print_mem.c

index 62328084704d9cd89e6e1f2fe3437528df495801..6461d6b3ca7b271cde153b57d2485126c4d22ccf 100644 (file)
@@ -423,13 +423,10 @@ int main(int argc, char *argv[]) {
 
     cfg_opt_t memory_opts[] = {
         CFG_STR("format", "%used %free %available", CFGF_NONE),
-        CFG_STR("degraded_format_below_threshold", NULL, CFGF_NONE),
-        CFG_STR("degraded_threshold_type", "percentage_avail", CFGF_NONE),
-        CFG_FLOAT("degraded_low_threshold", 0, CFGF_NONE),
-        CFG_STR("critical_format_below_threshold", NULL, CFGF_NONE),
-        CFG_STR("critical_threshold_type", "percentage_avail", CFGF_NONE),
-        CFG_FLOAT("critical_low_threshold", 0, CFGF_NONE),
-        CFG_BOOL("use_available_memory", true, CFGF_NONE),
+        CFG_STR("format_degraded", NULL, CFGF_NONE),
+        CFG_STR("threshold_degraded", NULL, CFGF_NONE),
+        CFG_STR("threshold_critical", NULL, CFGF_NONE),
+        CFG_STR("memory_used_method", "classical", CFGF_NONE),
         CFG_CUSTOM_ALIGN_OPT,
         CFG_CUSTOM_COLOR_OPTS,
         CFG_CUSTOM_MIN_WIDTH_OPT,
@@ -743,7 +740,7 @@ int main(int argc, char *argv[]) {
 
             CASE_SEC("memory") {
                 SEC_OPEN_MAP("memory");
-                print_memory(json_gen, buffer, cfg_getstr(sec, "format"), cfg_getstr(sec, "degraded_format_below_threshold"), cfg_getstr(sec, "degraded_threshold_type"), cfg_getfloat(sec, "degraded_low_threshold"), cfg_getstr(sec, "critical_format_below_threshold"), cfg_getstr(sec, "critical_threshold_type"), cfg_getfloat(sec, "critical_low_threshold"), cfg_getbool(sec, "use_available_memory"));
+                print_memory(json_gen, buffer, cfg_getstr(sec, "format"), cfg_getstr(sec, "format_degraded"), cfg_getstr(sec, "threshold_degraded"), cfg_getstr(sec, "threshold_critical"), cfg_getstr(sec, "memory_used_method"));
                 SEC_CLOSE_MAP;
             }
 
index 7f37964b9c19a975bfc98df2badb894760932fd1..07ffb7454fdb895bfeb137d4a310d0c2cdc76ff4 100644 (file)
@@ -17,6 +17,7 @@ order += "wireless _first_"
 order += "ethernet _first_"
 order += "battery all"
 order += "load"
+order += "memory"
 order += "tztime local"
 
 wireless _first_ {
@@ -42,6 +43,12 @@ load {
         format = "%1min"
 }
 
+memory {
+        format = "%used | %available"
+        threshold_degraded = "1G"
+        format_degraded = "MEMORY < %available"
+}
+
 disk "/" {
         format = "%avail"
 }
index 2aa43171f8e812edcf220b2b7cc6c09eb19c4f4e..fe9206ea1c19c2b4650015cd5030371896d41b27 100644 (file)
@@ -223,7 +223,7 @@ void print_cpu_temperature_info(yajl_gen json_gen, char *buffer, int zone, const
 void print_cpu_usage(yajl_gen json_gen, char *buffer, const char *format, const char *format_above_threshold, const char *format_above_degraded_threshold, const char *path, const float max_threshold, const float degraded_threshold);
 void print_eth_info(yajl_gen json_gen, char *buffer, const char *interface, const char *format_up, const char *format_down);
 void print_load(yajl_gen json_gen, char *buffer, const char *format, const char *format_above_threshold, const float max_threshold);
-void print_memory(yajl_gen json_gen, char *buffer, const char *format, const char *degraded_format_below_threshold, const char *degraded_threshold_type, const float degraded_low_threshold, const char *critical_format_below_threshold, const char *critical_threshold_type, const float critical_low_threshold, const bool use_available_memory);
+void print_memory(yajl_gen json_gen, char *buffer, const char *format, const char *format_degraded, const char *threshold_degraded, const char *threshold_critical, const char *memory_used_method);
 void print_volume(yajl_gen json_gen, char *buffer, const char *fmt, const char *fmt_muted, const char *device, const char *mixer, int mixer_idx);
 bool process_runs(const char *path);
 int volume_pulseaudio(uint32_t sink_idx, const char *sink_name);
index ec02ce104f92ceaa5d851d69fd743ed677ede39f..f8ce219fba6fd6fd4934debfa90fdfec93f39bd3 100644 (file)
@@ -116,6 +116,8 @@ cpu_temperature 0 {
 
 memory {
         format = "%used"
+        threshold_degraded = "10%"
+        format_degraded = "MEMORY: %free"
 }
 
 disk "/" {
@@ -197,6 +199,7 @@ double-quote (""") characters need to be replaced with "`&amp;`", "`&lt;`",
 for generated content (e.g. wireless ESSID, time).
 
 *Example configuration*:
+
 -------------------------------------------------------------
 general {
     output_format = "xmobar"
@@ -431,46 +434,42 @@ starting from %cpu0. This feature is currently not supported in FreeBSD.
 
 === Memory
 
-Gets the memory usage from system.
-On Linux, the information is taken from +/proc/meminfo+.
-
-These values can also be expressed in percentages with the +percentage_used+,
-+percentage_free+ and +percentage_shared+ formats.
-
-If a +critical_low_threshold+ is defined, the output will be colored using
-+color_bad+. The unit of this threshold is defined by the unit given in
-+critical_threshold_type+, which can be one of "bytes_free", "bytes_avail",
-"percentage_free" and "percentage_avail". Additionally, the former two can be
-prefixed with one of "k", "m", "g" or "t" to change the exact unit.
-For example, setting critical_low_threshold to 2 and threshold_type to "gbytes_avail"
-causes available memory below 2 GiB to be colored with +color_bad+. The
-defaults are "percentage_avail" with a threshold of 0.
-Furthermore, the format used when the threshold is reached can be customized
-using the option +critical_format_below_threshold+.
-Same applies to +degraded_low_threshold+, +degraded_threshold_type+ and
-+degraded_format_below_threshold+ using +color_degraded+.
-
-The most common one is:
-"used memory" = "total memory" - "free memory" - "buffers" - "cache"
-This is the default in i3status. Some other programs use
-"used memory" = "total memory" - "available memory"
-You can disable this behavior using +use_available_memory+.
+Gets the memory usage from system on a Linux system from +/proc/meminfo+. Other
+systems are currently not supported.
 
-*Example order*: +memory+
+As format placeholders, +total+, +used+, +free+, +available+ and +shared+ are
+available. These will print human readable values. It's also possible to prefix
+the placeholders with +percentage_+ to get a value in percent.
+
+It's possible to define a +threshold_degraded+ and a +threshold_critical+ to
+color the status bar output in yellow or red, if the available memory falls
+below the given threshold. Possible values of the threshold can be any integer,
+suffixed with an iec symbol (+T+, +G+, +M+, +K+). Alternatively, the integer
+can be suffixed by a percent sign, which then rets evaluated relatively to
+total memory.
+
+If the +format_degraded+ parameter is given and either the critical or the
+degraded threshold applies, +format_degraded+ will get used as format string.
+It acts equivalently to +format+.
 
-*Example format*: +%free %available (%used)/ %total+
+As Linux' meminfo doesn't expose the overall memory in use, there are multiple
+methods to distinguish the actually used memory. 
 
-*Example format*: +used %percentage_used , free %percentage_free, shared %percentage_shared+
+*Example used_memory_method*: +memavailable+ ("total memory" - "MemAvailable", matches gnome system monitor)
+
+*Example used_memory_method*: +classical+ ("total memory" - "free" - "buffers" - "cache", matches gnome system monitor)
+
+*Example order*: +memory+
 
-*Example degraded_low_threshold*: +10+
+*Example format*: +%free %available (%used) / %total+
 
-*Example degraded_threshold_type*: +percentage_free+
+*Example format*: +%percentage_used used, %percentage_free free, %percentage_shared shared+
 
-*Example critical_low_threshold*: +5+
+*Example threshold_degraded*: +10%+
 
-*Example critical_format_below_threshold*: +Warning: %percentage_free+
+*Example threshold_critical*: +5%+
 
-*Example use_available_memory: +false+
+*Example format_degraded*: +Memory LOW: %free+
 
 === Load
 
index fe93d0b52bb29ffd7d500d24634bb90401d71302..46523d6ce67c48560622eb0d787bd2e798e6feca 100644 (file)
@@ -29,49 +29,57 @@ static int print_bytes_human(char *outwalk, uint64_t bytes) {
 }
 
 /*
- * Determines whether remaining bytes are below given threshold.
+ * Convert a string to its absolute representation based on the total
+ * memory of `mem_total`.
+ *
+ * The string can contain any percentage values, which then return a
+ * the value of `size` in relation to `mem_total`.
+ * Alternatively an absolute value can be given, suffixed with an iec
+ * symbol.
  *
  */
-static bool below_threshold(const long ram_total, const long ram_used, const char *threshold_type, const long low_threshold) {
-    // empty is available or free, based on "use_available_memory"
-    long empty = ram_total - ram_used;
-    if (BEGINS_WITH(threshold_type, "percentage_")) {
-        return 100.0 * empty / ram_total < low_threshold;
-    } else if (strcasecmp(threshold_type, "bytes_free") == 0) {
-        return empty < low_threshold;
-    } else if (threshold_type[0] != '\0' && strncasecmp(threshold_type + 1, "bytes_", strlen("bytes_")) == 0) {
-
-        long factor = 1;
-
-        switch (threshold_type[0]) {
+static long memory_absolute(const long mem_total, const char *size) {
+    long mem_absolute = -1;
+    char *endptr = NULL;
+
+    mem_absolute = strtol(size, &endptr, 10);
+
+    if (endptr) {
+        while (endptr[0] != '\0' && isspace(endptr[0]))
+            endptr++;
+
+        switch (endptr[0]) {
             case 'T':
             case 't':
-                factor *= BINARY_BASE;
+                mem_absolute *= BINARY_BASE;
             case 'G':
             case 'g':
-                factor *= BINARY_BASE;
+                mem_absolute *= BINARY_BASE;
             case 'M':
             case 'm':
-                factor *= BINARY_BASE;
+                mem_absolute *= BINARY_BASE;
             case 'K':
             case 'k':
-                factor *= BINARY_BASE;
+                mem_absolute *= BINARY_BASE;
+                break;
+            case '%':
+                mem_absolute = mem_total * mem_absolute / 100;
                 break;
             default:
-                return false;
+                break;
         }
-        return empty < low_threshold * factor;
     }
-    return false;
+
+    return mem_absolute;
 }
 
-void print_memory(yajl_gen json_gen, char *buffer, const char *format, const char *degraded_format_below_threshold, const char *degraded_threshold_type, const float degraded_low_threshold, const char *critical_format_below_threshold, const char *critical_threshold_type, const float critical_low_threshold, const bool use_available_memory) {
+void print_memory(yajl_gen json_gen, char *buffer, const char *format, const char *format_degraded, const char *threshold_degraded, const char *threshold_critical, const char *memory_used_method) {
     char *outwalk = buffer;
 
 #if defined(linux)
     const char *selected_format = format;
     const char *walk;
-    bool colorful_output = false;
+    const char *output_color = NULL;
 
     long ram_total = -1;
     long ram_free = -1;
@@ -121,26 +129,34 @@ void print_memory(yajl_gen json_gen, char *buffer, const char *format, const cha
     ram_buffers = ram_buffers * BINARY_BASE;
     ram_cached = ram_cached * BINARY_BASE;
     ram_shared = ram_shared * BINARY_BASE;
-    if (use_available_memory) {
+
+    if (BEGINS_WITH(memory_used_method, "memavailable")) {
         ram_used = ram_total - ram_available;
-    } else {
+    } else if (BEGINS_WITH(memory_used_method, "classical")) {
         ram_used = ram_total - ram_free - ram_buffers - ram_cached;
     }
 
-    if (degraded_low_threshold > 0 && below_threshold(ram_total, ram_used, degraded_threshold_type, degraded_low_threshold)) {
-        if (critical_low_threshold > 0 && below_threshold(ram_total, ram_used, critical_threshold_type, critical_low_threshold)) {
-            START_COLOR("color_bad");
-            colorful_output = true;
-            if (critical_format_below_threshold != NULL)
-                selected_format = critical_format_below_threshold;
-        } else {
-            START_COLOR("color_degraded");
-            colorful_output = true;
-            if (degraded_format_below_threshold != NULL)
-                selected_format = degraded_format_below_threshold;
+    if (threshold_degraded) {
+        long abs = memory_absolute(ram_total, threshold_degraded);
+        if (ram_available < abs) {
+            output_color = "color_degraded";
+        }
+    }
+
+    if (threshold_critical) {
+        long abs = memory_absolute(ram_total, threshold_critical);
+        if (ram_available < abs) {
+            output_color = "color_bad";
         }
     }
 
+    if (output_color) {
+        START_COLOR(output_color);
+
+        if (format_degraded)
+            selected_format = format_degraded;
+    }
+
     for (walk = selected_format; *walk != '\0'; walk++) {
         if (*walk != '%') {
             *(outwalk++) = *walk;
@@ -192,7 +208,7 @@ void print_memory(yajl_gen json_gen, char *buffer, const char *format, const cha
         }
     }
 
-    if (colorful_output)
+    if (output_color)
         END_COLOR;
 
     *outwalk = '\0';