From b5a3ebe28c4a3599106e60b5febee6cc83f07eee Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Thu, 10 May 2018 14:23:22 +0200 Subject: [PATCH] Allow user to select number of decimal places Add new option: "--dec={0|1|2}" which can be used to specify the number of decimal places. This option can be used with sar, mpstat, iostat, pidstat and cifsiostat. Sample output: $ sar -b Linux 4.4.14-200.fc22.x86_64 (home) 05/10/18 _x86_64_ (8 CPU) 10:58:14 LINUX RESTART (8 CPU) 11:00:01 tps rtps wtps bread/s bwrtn/s 11:05:10 25.20 21.22 3.97 1884.87 644.03 11:10:10 10.02 8.60 1.42 633.84 33.87 11:15:10 0.89 0.16 0.73 2.11 73.44 11:20:04 5.65 3.27 2.37 102.24 104.44 [...] $ sar -b --dec=1 Linux 4.4.14-200.fc22.x86_64 (home) 05/10/18 _x86_64_ (8 CPU) 10:58:14 LINUX RESTART (8 CPU) 11:00:01 tps rtps wtps bread/s bwrtn/s 11:05:10 25.2 21.2 4.0 1884.9 644.0 11:10:10 10.0 8.6 1.4 633.8 33.9 11:15:10 0.9 0.2 0.7 2.1 73.4 11:20:04 5.6 3.3 2.4 102.2 104.4 [...] $ sar -b --dec=0 Linux 4.4.14-200.fc22.x86_64 (home) 05/10/18 _x86_64_ (8 CPU) 10:58:14 LINUX RESTART (8 CPU) 11:00:01 tps rtps wtps bread/s bwrtn/s 11:05:10 25 21 4 1885 644 11:10:10 10 9 1 634 34 11:15:10 1 0 1 2 73 11:20:04 6 3 2 102 104 [...] Signed-off-by: Sebastien GODARD --- cifsiostat.c | 14 ++++++++++++-- common.c | 47 ++++++++++++++++++++++++++++++++++++++--------- iostat.c | 17 +++++++++++++++-- mpstat.c | 17 ++++++++++++++--- pidstat.c | 16 ++++++++++++++-- sadf.c | 2 ++ sar.c | 14 +++++++++++++- tapestat.c | 3 +++ 8 files changed, 111 insertions(+), 19 deletions(-) diff --git a/cifsiostat.c b/cifsiostat.c index fc95437..dd5e220 100644 --- a/cifsiostat.c +++ b/cifsiostat.c @@ -53,6 +53,7 @@ struct io_hdr_stats *st_hdr_cifs; int cifs_nr = 0; /* Nb of CIFS mounted directories found */ int cpu_nr = 0; /* Nb of processors on the machine */ int flags = 0; /* Flag for common options and system state */ +int dplaces_nr = -1; /* Number of decimal places */ long interval = 0; char timestamp[TIMESTAMP_LEN]; @@ -74,10 +75,10 @@ void usage(char *progname) #ifdef DEBUG fprintf(stderr, _("Options are:\n" - "[ --human ] [ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ]\n")); + "[ --dec={ 0 | 1 | 2 } ] [ --human ] [ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ]\n")); #else fprintf(stderr, _("Options are:\n" - "[ --human ] [ -h ] [ -k | -m ] [ -t ] [ -V ]\n")); + "[ --dec={ 0 | 1 | 2 } ] [ --human ] [ -h ] [ -k | -m ] [ -t ] [ -V ]\n")); #endif exit(1); } @@ -609,6 +610,15 @@ int main(int argc, char **argv) opt++; } + else if (!strncmp(argv[opt], "--dec=", 6) && (strlen(argv[opt]) == 7)) { + /* Get number of decimal places */ + dplaces_nr = atoi(argv[opt] + 6); + if ((dplaces_nr < 0) || (dplaces_nr > 2)) { + usage(argv[0]); + } + opt++; + } + else if (!strncmp(argv[opt], "-", 1)) { for (i = 1; *(argv[opt] + i); i++) { diff --git a/common.c b/common.c index fb3d2e2..558daf4 100644 --- a/common.c +++ b/common.c @@ -44,6 +44,9 @@ #define _(string) (string) #endif +/* Number of decimal places */ +extern int dplaces_nr; + /* Units (sectors, Bytes, kilobytes, etc.) */ char units[] = {'s', 'B', 'k', 'M', 'G', 'T', 'P', '?'}; @@ -1067,7 +1070,7 @@ void cprintf_unit(int unit, int wi, double dval) dval /= 1024; unit++; } - printf(" %*.*f", wi - 1, 1, dval); + printf(" %*.*f", wi - 1, dplaces_nr ? 1 : 0, dval); printf("%s", sc_normal); /* Display unit */ @@ -1157,15 +1160,28 @@ void cprintf_x(int num, int wi, ...) void cprintf_f(int unit, int num, int wi, int wd, ...) { int i; - double val; + double val, lim = 0.005;; va_list args; + /* + * If there are decimal places then get the value + * entered on the command line (if existing). + */ + if ((wd > 0) && (dplaces_nr >= 0)) { + wd = dplaces_nr; + } + + /* Update limit value according to number of decimal places */ + if (wd == 1) { + lim = 0.05; + } + va_start(args, wd); for (i = 0; i < num; i++) { val = va_arg(args, double); - if (((val < 0.005) && (val > -0.005)) || - ((wd == 0) && (val < 0.5))) { + if (((wd > 0) && (val < lim) && (val > (lim * -1))) || + ((wd == 0) && (val <= 0.5) && (val >= -0.5))) { /* "Round half to even" law */ printf("%s", sc_zero_int_stat); } else { @@ -1203,22 +1219,34 @@ void cprintf_pc(int human, int num, int wi, int wd, ...) va_list args; /* - * If a percent sign is to be displayed, then there will be only one decimal place. - * In this case, a value smaller than 0.05 shall be considered as 0. + * If there are decimal places then get the value + * entered on the command line (if existing). + */ + if ((wd > 0) && (dplaces_nr >= 0)) { + wd = dplaces_nr; + } + + /* + * If a percent sign is to be displayed, then there will be + * zero (or one) decimal place. */ if (human > 0) { - lim = 0.05; if (wi < 4) { /* E.g., 100% */ wi = 4; } /* Keep one place for the percent sign */ wi -= 1; - if (wd > 0) { + if (wd > 1) { wd -= 1; } } + /* Update limit value according to number of decimal places */ + if (wd == 1) { + lim = 0.05; + } + va_start(args, wd); for (i = 0; i < num; i++) { @@ -1229,7 +1257,8 @@ void cprintf_pc(int human, int num, int wi, int wd, ...) else if (val >= PERCENT_LIMIT_LOW) { printf("%s", sc_percent_low); } - else if (val < lim) { + else if (((wd > 0) && (val < lim)) || + ((wd == 0) && (val <= 0.5))) { /* "Round half to even" law */ printf("%s", sc_zero_int_stat); } else { diff --git a/iostat.c b/iostat.c index 9f51d8f..9fa4b54 100644 --- a/iostat.c +++ b/iostat.c @@ -61,6 +61,8 @@ struct io_dlist *st_dev_list; /* Last group name entered on the command line */ char group_name[MAX_NAME_LEN]; +/* Number of decimal places */ +int dplaces_nr = -1; int iodev_nr = 0; /* Nb of devices and partitions found. Includes nb of device groups */ int group_nr = 0; /* Nb of device groups */ @@ -89,13 +91,15 @@ void usage(char *progname) #ifdef DEBUG fprintf(stderr, _("Options are:\n" "[ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -s ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]\n" - "[ -j { ID | LABEL | PATH | UUID | ... } ] [ --human ] [ -o JSON ]\n" + "[ -j { ID | LABEL | PATH | UUID | ... } ]\n" + "[ --dec={ 0 | 1 | 2 } ] [ --human ] [ -o JSON ]\n" "[ [ -H ] -g ] [ -p [ [,...] | ALL ] ]\n" "[ [...] | ALL ] [ --debuginfo ]\n")); #else fprintf(stderr, _("Options are:\n" "[ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -s ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]\n" - "[ -j { ID | LABEL | PATH | UUID | ... } ] [ --human ] [ -o JSON ]\n" + "[ -j { ID | LABEL | PATH | UUID | ... } ]\n" + "[ --dec={ 0 | 1 | 2 } ] [ --human ] [ -o JSON ]\n" "[ [ -H ] -g ] [ -p [ [,...] | ALL ] ]\n" "[ [...] | ALL ]\n")); #endif @@ -1804,6 +1808,15 @@ int main(int argc, char **argv) opt++; } + else if (!strncmp(argv[opt], "--dec=", 6) && (strlen(argv[opt]) == 7)) { + /* Get number of decimal places */ + dplaces_nr = atoi(argv[opt] + 6); + if ((dplaces_nr < 0) || (dplaces_nr > 2)) { + usage(argv[0]); + } + opt++; + } + else if (!strcmp(argv[opt], "-j")) { if (!argv[++opt]) { usage(argv[0]); diff --git a/mpstat.c b/mpstat.c index d0e3059..b32510b 100644 --- a/mpstat.c +++ b/mpstat.c @@ -94,6 +94,8 @@ unsigned int flags = 0; /* Interval and count parameters */ long interval = -1, count = 0; +/* Number of decimal places */ +int dplaces_nr = -1; /* * Nb of processors on the machine. @@ -131,8 +133,9 @@ void usage(char *progname) progname); fprintf(stderr, _("Options are:\n" - "[ -A ] [ -n ] [ -u ] [ -V ] [ -I { SUM | CPU | SCPU | ALL } ]\n" - "[ -N { | ALL } ] [ -o JSON ] [ -P { | ALL } ]\n")); + "[ -A ] [ -n ] [ -u ] [ -V ]\n" + "[ -I { SUM | CPU | SCPU | ALL } ] [ -N { | ALL } ]\n" + "[ --dec={ 0 | 1 | 2 } ] [ -o JSON ] [ -P { | ALL } ]\n")); exit(1); } @@ -2000,7 +2003,15 @@ int main(int argc, char **argv) while (++opt < argc) { - if (!strcmp(argv[opt], "-I")) { + if (!strncmp(argv[opt], "--dec=", 6) && (strlen(argv[opt]) == 7)) { + /* Get number of decimal places */ + dplaces_nr = atoi(argv[opt] + 6); + if ((dplaces_nr < 0) || (dplaces_nr > 2)) { + usage(argv[0]); + } + } + + else if (!strcmp(argv[opt], "-I")) { if (!argv[++opt]) { usage(argv[0]); } diff --git a/pidstat.c b/pidstat.c index a51726f..73fcb4c 100644 --- a/pidstat.c +++ b/pidstat.c @@ -76,6 +76,8 @@ unsigned int actflag = 0; /* Activity flag */ struct sigaction alrm_act, int_act, chld_act; int signal_caught = 0; +int dplaces_nr = -1; /* Number of decimal places */ + /* *************************************************************************** * Print usage and exit. @@ -91,8 +93,9 @@ void usage(char *progname) fprintf(stderr, _("Options are:\n" "[ -d ] [ -H ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ ] ]\n" - "[ -u ] [ -V ] [ -v ] [ -w ] [ -C ] [ -G ] [ --human ]\n" - "[ -p { [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n")); + "[ -u ] [ -V ] [ -v ] [ -w ] [ -C ] [ -G ]\n" + "[ -p { [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n" + "[ --dec={ 0 | 1 | 2 } ] [ --human ]\n")); exit(1); } @@ -2723,6 +2726,15 @@ int main(int argc, char **argv) opt++; } + else if (!strncmp(argv[opt], "--dec=", 6) && (strlen(argv[opt]) == 7)) { + /* Get number of decimal places */ + dplaces_nr = atoi(argv[opt] + 6); + if ((dplaces_nr < 0) || (dplaces_nr > 2)) { + usage(argv[0]); + } + opt++; + } + else if (!strcmp(argv[opt], "-T")) { if (!argv[++opt]) { usage(argv[0]); diff --git a/sadf.c b/sadf.c index 2d2c39c..158a648 100644 --- a/sadf.c +++ b/sadf.c @@ -49,6 +49,8 @@ long interval = -1, count = 0; int endian_mismatch = FALSE; /* TRUE if file's data come from a 64 bit machine */ int arch_64 = FALSE; +/* Number of decimal places */ +int dplaces_nr = -1; unsigned int flags = 0; unsigned int dm_major; /* Device-mapper major number */ diff --git a/sar.c b/sar.c index c0c85ab..6bd9396 100644 --- a/sar.c +++ b/sar.c @@ -53,6 +53,8 @@ int dis = TRUE; int endian_mismatch = FALSE; /* TRUE if file's data come from a 64 bit machine */ int arch_64 = FALSE; +/* Number of decimal places */ +int dplaces_nr = -1; unsigned int flags = 0; unsigned int dm_major; /* Device-mapper major number */ @@ -115,7 +117,8 @@ void usage(char *progname) fprintf(stderr, _("Options are:\n" "[ -A ] [ -B ] [ -b ] [ -C ] [ -D ] [ -d ] [ -F [ MOUNT ] ] [ -H ] [ -h ]\n" "[ -p ] [ -q ] [ -r [ ALL ] ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ]\n" - "[ -v ] [ -W ] [ -w ] [ -y ] [ -z ] [ --help ] [ --human ] [ --sadc ]\n" + "[ -v ] [ -W ] [ -w ] [ -y ] [ -z ]\n" + "[ --dec={ 0 | 1 | 2 } ] [ --help ] [ --human ] [ --sadc ]\n" "[ -I { | SUM | ALL } ] [ -P { | ALL } ]\n" "[ -m { [,...] | ALL } ] [ -n { [,...] | ALL } ]\n" "[ -j { ID | LABEL | PATH | UUID | ... } ]\n" @@ -1279,6 +1282,15 @@ int main(int argc, char **argv) opt++; } + else if (!strncmp(argv[opt], "--dec=", 6) && (strlen(argv[opt]) == 7)) { + /* Get number of decimal places */ + dplaces_nr = atoi(argv[opt] + 6); + if ((dplaces_nr < 0) || (dplaces_nr > 2)) { + usage(argv[0]); + } + opt++; + } + else if (!strcmp(argv[opt], "-I")) { /* Parse -I option */ if (parse_sar_I_opt(argv, &opt, act)) { diff --git a/tapestat.c b/tapestat.c index a57beff..a8ea460 100644 --- a/tapestat.c +++ b/tapestat.c @@ -72,6 +72,9 @@ char timestamp[TIMESTAMP_LEN]; struct sigaction alrm_act; +/* Number of decimal places */ +int dplaces_nr = -1; + /* * For tape stats - it would be extremely rare for there to be a very large * number of tape drives attached to a system. I wouldn't expect to see more -- 2.40.0