diff options
| author | Benedikt Heine <bebe@bebehei.de> | 2018-04-16 18:18:50 +0200 | 
|---|---|---|
| committer | Felix Buehler <account@buehler.rocks> | 2018-05-04 18:46:59 +0200 | 
| commit | cba8f559384008f187e7388186b9885343be0678 (patch) | |
| tree | 66405b5d049954dad3fc35ac123ec0107bd785b6 | |
| parent | 7839e93c9b9ef9635109a9130edf012a80335897 (diff) | |
Simplify the memory thresholds
| -rw-r--r-- | i3status.c | 13 | ||||
| -rw-r--r-- | i3status.conf | 7 | ||||
| -rw-r--r-- | include/i3status.h | 2 | ||||
| -rw-r--r-- | man/i3status.man | 63 | ||||
| -rw-r--r-- | src/print_mem.c | 88 | 
5 files changed, 96 insertions, 77 deletions
| @@ -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;              } diff --git a/i3status.conf b/i3status.conf index 7f37964..07ffb74 100644 --- a/i3status.conf +++ b/i3status.conf @@ -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"  } diff --git a/include/i3status.h b/include/i3status.h index 2aa4317..fe9206e 100644 --- a/include/i3status.h +++ b/include/i3status.h @@ -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); diff --git a/man/i3status.man b/man/i3status.man index ec02ce1..f8ce219 100644 --- a/man/i3status.man +++ b/man/i3status.man @@ -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 "`&`", "`<`",  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 diff --git a/src/print_mem.c b/src/print_mem.c index fe93d0b..46523d6 100644 --- a/src/print_mem.c +++ b/src/print_mem.c @@ -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'; | 
