Make systat(1) more human readable

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Make systat(1) more human readable

Martijn van Duren-5
Hello tech@,

Since my brain is incapable of quickly processing numbers larger than a
million (even with the thousand separators enabled), I would like to
introduce the -h flag to systat.
In order not to loose too much information I do the rollover at values  
from 10.0000 up.
I didn't use fmt_scaled, because it's intended for bytecounts and it's
inside libutil, which isn't linked to systat.

It's possible to toggle it at runtime via the "human" command, but I
didn't add a single letter switch, since that space is already quite
crammed.

OK?

martijn@

Index: engine.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.c,v
retrieving revision 1.22
diff -u -p -r1.22 engine.c
--- engine.c 8 Feb 2018 07:00:33 -0000 1.22
+++ engine.c 11 Feb 2018 11:28:15 -0000
@@ -52,6 +52,7 @@ struct view_ent {
 
 useconds_t udelay = 5000000;
 int dispstart = 0;
+int humanreadable = 0;
 int interactive = 1;
 int averageonly = 0;
 int maxprint = 0;
@@ -717,6 +718,8 @@ void
 print_fld_sdiv(field_def *fld, u_int64_t size, int d)
 {
  int len;
+ char *mult = "KMGTPE";
+ int i = -1;
 
  if (fld == NULL)
  return;
@@ -726,35 +729,21 @@ print_fld_sdiv(field_def *fld, u_int64_t
  return;
 
  tb_start();
- if (tbprintft("%llu", size) <= len)
- goto ok;
-
- tb_start();
- size /= d;
- if (tbprintft("%lluK", size) <= len)
- goto ok;
- if (size == 0)
- goto err;
-
- tb_start();
- size /= d;
- if (tbprintft("%lluM", size) <= len)
- goto ok;
- if (size == 0)
- goto err;
-
- tb_start();
- size /= d;
- if (tbprintft("%lluG", size) <= len)
- goto ok;
- if (size == 0)
- goto err;
-
- tb_start();
- size /= d;
- if (tbprintft("%lluT", size) <= len)
- goto ok;
-
+ if (humanreadable) {
+ while (size >= 10000 && sizeof(mult) >= i + 1) {
+ i++;
+ size /= d;
+ }
+ if (tbprintft("%llu%.1s", size, i == -1 ? "" : mult + i) <= len)
+ goto ok;
+ }
+ while (size != 0 && sizeof(mult) >= i + 1) {
+ tb_start();
+ if (tbprintft("%llu%.1s", size, i == -1 ? "" : mult + i) <= len)
+ goto ok;
+ i++;
+ size /= d;
+ }
 err:
  print_fld_str(fld, "*");
  tb_end();
Index: engine.h
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.h,v
retrieving revision 1.9
diff -u -p -r1.9 engine.h
--- engine.h 8 Feb 2018 07:00:33 -0000 1.9
+++ engine.h 11 Feb 2018 11:28:15 -0000
@@ -148,6 +148,7 @@ void foreach_view(void (*callback)(field
 extern int sortdir;
 extern useconds_t udelay;
 extern int dispstart;
+extern int humanreadable;
 extern int interactive;
 extern int averageonly;
 extern int maxprint;
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.67
diff -u -p -r1.67 main.c
--- main.c 8 Feb 2018 07:00:33 -0000 1.67
+++ main.c 11 Feb 2018 11:28:15 -0000
@@ -305,6 +305,10 @@ cmd_compat(const char *buf)
  need_update = 1;
  return;
  }
+ if (strncasecmp(buf, "human", 5) == 0) {
+ humanreadable = !humanreadable;
+ return;
+ }
 
  for (s = buf; *s && strchr("0123456789+-.eE", *s) != NULL; s++)
  ;
@@ -437,7 +441,7 @@ main(int argc, char *argv[])
  if (setresgid(gid, gid, gid) == -1)
  err(1, "setresgid");
 
- while ((ch = getopt(argc, argv, "BNabd:ins:w:")) != -1) {
+ while ((ch = getopt(argc, argv, "BNabd:hins:w:")) != -1) {
  switch (ch) {
  case 'a':
  maxlines = -1;
@@ -455,6 +459,9 @@ main(int argc, char *argv[])
  countmax = strtonum(optarg, 1, INT_MAX, &errstr);
  if (errstr)
  errx(1, "-d %s: %s", optarg, errstr);
+ break;
+ case 'h':
+ humanreadable = 1;
  break;
  case 'i':
  interactive = 1;
Index: systat.1
===================================================================
RCS file: /cvs/src/usr.bin/systat/systat.1,v
retrieving revision 1.103
diff -u -p -r1.103 systat.1
--- systat.1 8 Feb 2018 07:00:33 -0000 1.103
+++ systat.1 11 Feb 2018 11:28:15 -0000
@@ -38,7 +38,7 @@
 .Nd display system statistics
 .Sh SYNOPSIS
 .Nm systat
-.Op Fl aBbiNn
+.Op Fl aBbhiNn
 .Op Fl d Ar count
 .Op Fl s Ar delay
 .Op Fl w Ar width
@@ -103,6 +103,8 @@ Exit after
 screen updates.
 .It Fl i
 Interactive mode.
+.It Fl h
+Human readable mode.
 .It Fl N
 Resolve network addresses to names.
 This is the opposite of the
@@ -219,6 +221,8 @@ command interpreter.
 .Bl -tag -width Fl
 .It Ic help
 Print the names of the available views on the command line.
+.It Ic human
+Toggle human readable mode.
 .It Ic order
 Print the names of the available orderings on the command line.
 .It Ic quit

Reply | Threaded
Open this post in threaded view
|

Re: Make systat(1) more human readable

Martijn van Duren-5
Some documentation nits found by jmc.

On 02/11/18 12:31, Martijn van Duren wrote:

> Hello tech@,
>
> Since my brain is incapable of quickly processing numbers larger than a
> million (even with the thousand separators enabled), I would like to
> introduce the -h flag to systat.
> In order not to loose too much information I do the rollover at values  
> from 10.0000 up.
> I didn't use fmt_scaled, because it's intended for bytecounts and it's
> inside libutil, which isn't linked to systat.
>
> It's possible to toggle it at runtime via the "human" command, but I
> didn't add a single letter switch, since that space is already quite
> crammed.
>
> OK?
>
> martijn@
>

Index: engine.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.c,v
retrieving revision 1.22
diff -u -p -r1.22 engine.c
--- engine.c 8 Feb 2018 07:00:33 -0000 1.22
+++ engine.c 11 Feb 2018 12:46:19 -0000
@@ -52,6 +52,7 @@ struct view_ent {
 
 useconds_t udelay = 5000000;
 int dispstart = 0;
+int humanreadable = 0;
 int interactive = 1;
 int averageonly = 0;
 int maxprint = 0;
@@ -717,6 +718,8 @@ void
 print_fld_sdiv(field_def *fld, u_int64_t size, int d)
 {
  int len;
+ char *mult = "KMGTPE";
+ int i = -1;
 
  if (fld == NULL)
  return;
@@ -726,35 +729,21 @@ print_fld_sdiv(field_def *fld, u_int64_t
  return;
 
  tb_start();
- if (tbprintft("%llu", size) <= len)
- goto ok;
-
- tb_start();
- size /= d;
- if (tbprintft("%lluK", size) <= len)
- goto ok;
- if (size == 0)
- goto err;
-
- tb_start();
- size /= d;
- if (tbprintft("%lluM", size) <= len)
- goto ok;
- if (size == 0)
- goto err;
-
- tb_start();
- size /= d;
- if (tbprintft("%lluG", size) <= len)
- goto ok;
- if (size == 0)
- goto err;
-
- tb_start();
- size /= d;
- if (tbprintft("%lluT", size) <= len)
- goto ok;
-
+ if (humanreadable) {
+ while (size >= 10000 && sizeof(mult) >= i + 1) {
+ i++;
+ size /= d;
+ }
+ if (tbprintft("%llu%.1s", size, i == -1 ? "" : mult + i) <= len)
+ goto ok;
+ }
+ while (size != 0 && sizeof(mult) >= i + 1) {
+ tb_start();
+ if (tbprintft("%llu%.1s", size, i == -1 ? "" : mult + i) <= len)
+ goto ok;
+ i++;
+ size /= d;
+ }
 err:
  print_fld_str(fld, "*");
  tb_end();
Index: engine.h
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.h,v
retrieving revision 1.9
diff -u -p -r1.9 engine.h
--- engine.h 8 Feb 2018 07:00:33 -0000 1.9
+++ engine.h 11 Feb 2018 12:46:19 -0000
@@ -148,6 +148,7 @@ void foreach_view(void (*callback)(field
 extern int sortdir;
 extern useconds_t udelay;
 extern int dispstart;
+extern int humanreadable;
 extern int interactive;
 extern int averageonly;
 extern int maxprint;
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.67
diff -u -p -r1.67 main.c
--- main.c 8 Feb 2018 07:00:33 -0000 1.67
+++ main.c 11 Feb 2018 12:46:19 -0000
@@ -212,7 +212,7 @@ void
 usage(void)
 {
  extern char *__progname;
- fprintf(stderr, "usage: %s [-aBbiNn] [-d count] "
+ fprintf(stderr, "usage: %s [-aBbhiNn] [-d count] "
     "[-s delay] [-w width] [view] [delay]\n", __progname);
  exit(1);
 }
@@ -305,6 +305,10 @@ cmd_compat(const char *buf)
  need_update = 1;
  return;
  }
+ if (strncasecmp(buf, "human", 5) == 0) {
+ humanreadable = !humanreadable;
+ return;
+ }
 
  for (s = buf; *s && strchr("0123456789+-.eE", *s) != NULL; s++)
  ;
@@ -437,7 +441,7 @@ main(int argc, char *argv[])
  if (setresgid(gid, gid, gid) == -1)
  err(1, "setresgid");
 
- while ((ch = getopt(argc, argv, "BNabd:ins:w:")) != -1) {
+ while ((ch = getopt(argc, argv, "BNabd:hins:w:")) != -1) {
  switch (ch) {
  case 'a':
  maxlines = -1;
@@ -455,6 +459,9 @@ main(int argc, char *argv[])
  countmax = strtonum(optarg, 1, INT_MAX, &errstr);
  if (errstr)
  errx(1, "-d %s: %s", optarg, errstr);
+ break;
+ case 'h':
+ humanreadable = 1;
  break;
  case 'i':
  interactive = 1;
Index: systat.1
===================================================================
RCS file: /cvs/src/usr.bin/systat/systat.1,v
retrieving revision 1.103
diff -u -p -r1.103 systat.1
--- systat.1 8 Feb 2018 07:00:33 -0000 1.103
+++ systat.1 11 Feb 2018 12:46:19 -0000
@@ -38,7 +38,7 @@
 .Nd display system statistics
 .Sh SYNOPSIS
 .Nm systat
-.Op Fl aBbiNn
+.Op Fl aBbhiNn
 .Op Fl d Ar count
 .Op Fl s Ar delay
 .Op Fl w Ar width
@@ -101,6 +101,8 @@ with statistics displayed every update.
 Exit after
 .Ar count
 screen updates.
+.It Fl h
+Human readable mode.
 .It Fl i
 Interactive mode.
 .It Fl N
@@ -219,6 +221,8 @@ command interpreter.
 .Bl -tag -width Fl
 .It Ic help
 Print the names of the available views on the command line.
+.It Ic human
+Toggle human readable mode.
 .It Ic order
 Print the names of the available orderings on the command line.
 .It Ic quit