]> granicus.if.org Git - sysstat/commitdiff
sar: Add new -z option
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 18 Feb 2018 15:18:58 +0000 (16:18 +0100)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 18 Feb 2018 15:18:58 +0000 (16:18 +0100)
Add new option to sar (-z). This option tells sar to omit output for any
devices for which there was no activity during the sample period.
This option applies for network interfaces, interrupts, block devices,
serial lines, filesystems, CPU (in softnet statistics).
Note: This option already existed for iostat.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
pr_stats.c
rd_stats.h
sa.h
sar.c

index 567d982fa7228d2b8fc0604cad4481b59d4d9aae..90073b2734a4f13f21f7058684ce8981c564d372 100644 (file)
@@ -342,7 +342,7 @@ __print_funct_t print_irq_stats(struct activity *a, int prev, int curr,
        int i;
        struct stats_irq *sic, *sip;
 
-       if (dis) {
+       if (dis || DISPLAY_ZERO_OMIT(flags)) {
                print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
        }
 
@@ -366,6 +366,9 @@ __print_funct_t print_irq_stats(struct activity *a, int prev, int curr,
                /* Should current interrupt (including int "sum") be displayed? */
                if (a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) {
 
+                       if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sip, sic, STATS_IRQ_SIZE))
+                               continue;
+
                        /* Yes: Display it */
                        printf("%-11s", timestamp[curr]);
                        if (!i) {
@@ -950,7 +953,7 @@ __print_funct_t print_serial_stats(struct activity *a, int prev, int curr,
        int i, j, j0, found;
        struct stats_serial *ssc, *ssp;
 
-       if (dis) {
+       if (dis || DISPLAY_ZERO_OMIT(flags)) {
                print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
        }
 
@@ -999,6 +1002,9 @@ __print_funct_t print_serial_stats(struct activity *a, int prev, int curr,
                if (!found)
                        continue;
 
+               if (DISPLAY_ZERO_OMIT(flags) && !memcmp(ssp, ssc, STATS_SERIAL_SIZE))
+                       continue;
+
                printf("%-11s", timestamp[curr]);
                cprintf_in(IS_INT, "       %3d", "", ssc->line);
 
@@ -1040,7 +1046,7 @@ __print_funct_t print_disk_stats(struct activity *a, int prev, int curr,
                unit = UNIT_KILOBYTE;
        }
 
-       if (dis) {
+       if (dis || DISPLAY_ZERO_OMIT(flags)) {
                print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9);
        }
 
@@ -1064,6 +1070,9 @@ __print_funct_t print_disk_stats(struct activity *a, int prev, int curr,
                        sdp = (struct stats_disk *) ((char *) a->buf[prev] + j * a->msize);
                }
 
+               if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sdp, sdc, STATS_DISK_SIZE))
+                       continue;
+
                /* Compute service time, etc. */
                compute_ext_disk_stats(sdc, sdp, itv, &xds);
 
@@ -1140,7 +1149,7 @@ __print_funct_t print_net_dev_stats(struct activity *a, int prev, int curr,
                unit = UNIT_BYTE;
        }
 
-       if (dis) {
+       if (dis || DISPLAY_ZERO_OMIT(flags)) {
                print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9);
        }
 
@@ -1164,6 +1173,9 @@ __print_funct_t print_net_dev_stats(struct activity *a, int prev, int curr,
                        sndp = (struct stats_net_dev *) ((char *) a->buf[prev] + j * a->msize);
                }
 
+               if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sndp, sndc, STATS_NET_DEV_SIZE2CMP))
+                       continue;
+
                printf("%-11s", timestamp[curr]);
 
                if (!DISPLAY_HUMAN_READ(flags)) {
@@ -1210,7 +1222,7 @@ __print_funct_t print_net_edev_stats(struct activity *a, int prev, int curr,
 
        memset(&snedzero, 0, STATS_NET_EDEV_SIZE);
 
-       if (dis) {
+       if (dis || DISPLAY_ZERO_OMIT(flags)) {
                print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9);
        }
 
@@ -1234,6 +1246,9 @@ __print_funct_t print_net_edev_stats(struct activity *a, int prev, int curr,
                        snedp = (struct stats_net_edev *) ((char *) a->buf[prev] + j * a->msize);
                }
 
+               if (DISPLAY_ZERO_OMIT(flags) && !memcmp(snedp, snedc, STATS_NET_EDEV_SIZE2CMP))
+                       continue;
+
                printf("%-11s", timestamp[curr]);
 
                if (!DISPLAY_HUMAN_READ(flags)) {
@@ -2708,14 +2723,15 @@ __print_funct_t print_avg_pwr_usb_stats(struct activity *a, int prev, int curr,
  *
  * IN:
  * @a          Activity structure with statistics.
+ * @prev       Index in array where stats used as reference are.
  * @curr       Index in array for current sample statistics.
  * @dispavg    TRUE if displaying average statistics.
  ***************************************************************************
  */
-__print_funct_t stub_print_filesystem_stats(struct activity *a, int curr, int dispavg)
+__print_funct_t stub_print_filesystem_stats(struct activity *a, int prev, int curr, int dispavg)
 {
-       int i, j;
-       struct stats_filesystem *sfc, *sfm;
+       int i, j, j0, found;
+       struct stats_filesystem *sfc, *sfp, *sfm;
        int unit = NO_UNIT;
 
        if (DISPLAY_UNIT(flags)) {
@@ -2723,7 +2739,7 @@ __print_funct_t stub_print_filesystem_stats(struct activity *a, int curr, int di
                unit = UNIT_BYTE;
        }
 
-       if (dis) {
+       if (dis || DISPLAY_ZERO_OMIT(flags)) {
                print_hdr_line((dispavg ? _("Summary:") : timestamp[!curr]),
                               a, FIRST + DISPLAY_MOUNT(a->opt_flags), -1, 9);
        }
@@ -2731,25 +2747,56 @@ __print_funct_t stub_print_filesystem_stats(struct activity *a, int curr, int di
        for (i = 0; i < a->nr[curr]; i++) {
                sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
 
-               printf("%-11s", (dispavg ? _("Summary:") : timestamp[curr]));
-               cprintf_f(unit, 2, 9, 0,
-                         unit < 0 ? (double) sfc->f_bfree / 1024 / 1024 : (double) sfc->f_bfree,
-                         unit < 0 ? (double) (sfc->f_blocks - sfc->f_bfree) / 1024 / 1024 :
-                                    (double) (sfc->f_blocks - sfc->f_bfree));
-               cprintf_pc(DISPLAY_UNIT(flags), 2, 9, 2,
-                          /* f_blocks is not zero. But test it anyway ;-) */
-                          sfc->f_blocks ? SP_VALUE(sfc->f_bfree, sfc->f_blocks, sfc->f_blocks)
-                          : 0.0,
-                          sfc->f_blocks ? SP_VALUE(sfc->f_bavail, sfc->f_blocks, sfc->f_blocks)
-                          : 0.0);
-               cprintf_u64(NO_UNIT, 2, 9,
-                           (unsigned long long) sfc->f_ffree,
-                           (unsigned long long) (sfc->f_files - sfc->f_ffree));
-               cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
-                          sfc->f_files ? SP_VALUE(sfc->f_ffree, sfc->f_files, sfc->f_files)
-                          : 0.0);
-               cprintf_in(IS_STR, " %s\n",
-                          DISPLAY_MOUNT(a->opt_flags) ? sfc->mountp : sfc->fs_name, 0);
+               found = FALSE;
+               if (DISPLAY_ZERO_OMIT(flags) && !dispavg) {
+
+                       if (a->nr[prev] > 0) {
+                               /* Look for corresponding fs in previous iteration */
+                               j = i;
+
+                               if (j >= a->nr[prev]) {
+                                       j = a->nr[prev] - 1;
+                               }
+
+                               j0 = j;
+
+                               do {
+                                       sfp = (struct stats_filesystem *) ((char *) a->buf[prev] + j * a->msize);
+                                       if (!strcmp(sfp->fs_name, sfc->fs_name)) {
+                                               found = TRUE;
+                                               break;
+                                       }
+                                       if (++j >= a->nr[prev]) {
+                                               j = 0;
+                                       }
+                               }
+                               while (j != j0);
+                       }
+               }
+
+               if (!DISPLAY_ZERO_OMIT(flags) || dispavg || WANT_SINCE_BOOT(flags) || !found ||
+                   (found && memcmp(sfp, sfc, STATS_FILESYSTEM_SIZE2CMP))) {
+
+                       printf("%-11s", (dispavg ? _("Summary:") : timestamp[curr]));
+                       cprintf_f(unit, 2, 9, 0,
+                                 unit < 0 ? (double) sfc->f_bfree / 1024 / 1024 : (double) sfc->f_bfree,
+                                 unit < 0 ? (double) (sfc->f_blocks - sfc->f_bfree) / 1024 / 1024 :
+                                            (double) (sfc->f_blocks - sfc->f_bfree));
+                       cprintf_pc(DISPLAY_UNIT(flags), 2, 9, 2,
+                                  /* f_blocks is not zero. But test it anyway ;-) */
+                                  sfc->f_blocks ? SP_VALUE(sfc->f_bfree, sfc->f_blocks, sfc->f_blocks)
+                                  : 0.0,
+                                  sfc->f_blocks ? SP_VALUE(sfc->f_bavail, sfc->f_blocks, sfc->f_blocks)
+                                  : 0.0);
+                       cprintf_u64(NO_UNIT, 2, 9,
+                                   (unsigned long long) sfc->f_ffree,
+                                   (unsigned long long) (sfc->f_files - sfc->f_ffree));
+                       cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
+                                  sfc->f_files ? SP_VALUE(sfc->f_ffree, sfc->f_files, sfc->f_files)
+                                  : 0.0);
+                       cprintf_in(IS_STR, " %s\n",
+                                  DISPLAY_MOUNT(a->opt_flags) ? sfc->mountp : sfc->fs_name, 0);
+               }
 
                if (!dispavg) {
                        /* Save current filesystem in summary list */
@@ -2797,7 +2844,7 @@ __print_funct_t stub_print_filesystem_stats(struct activity *a, int curr, int di
 __print_funct_t print_filesystem_stats(struct activity *a, int prev, int curr,
                                       unsigned long long itv)
 {
-       stub_print_filesystem_stats(a, curr, FALSE);
+       stub_print_filesystem_stats(a, prev, curr, FALSE);
 }
 
 /*
@@ -2814,7 +2861,7 @@ __print_funct_t print_filesystem_stats(struct activity *a, int prev, int curr,
 __print_funct_t print_avg_filesystem_stats(struct activity *a, int prev, int curr,
                                           unsigned long long itv)
 {
-       stub_print_filesystem_stats(a, 2, TRUE);
+       stub_print_filesystem_stats(a, prev, 2, TRUE);
 }
 
 /*
@@ -2905,7 +2952,7 @@ __print_funct_t print_softnet_stats(struct activity *a, int prev, int curr,
                *ssnp = (struct stats_softnet *) a->buf[prev];
        int i;
 
-       if (dis) {
+       if (dis || DISPLAY_ZERO_OMIT(flags)) {
                print_hdr_line(timestamp[!curr], a, FIRST, 7, 9);
        }
 
@@ -2933,6 +2980,9 @@ __print_funct_t print_softnet_stats(struct activity *a, int prev, int curr,
                        /* No */
                        continue;
 
+               if (DISPLAY_ZERO_OMIT(flags) && !memcmp(ssnp, ssnc,STATS_SOFTNET_SIZE))
+                       continue;
+
                printf("%-11s", timestamp[curr]);
 
                if (!i) {
index 9602780a0f9d8b5b5824f070afd5224952daccae..909a46b37fa1338f4fc7692c614b44f21acbd995 100644 (file)
@@ -287,6 +287,7 @@ struct stats_net_dev {
 };
 
 #define STATS_NET_DEV_SIZE     (sizeof(struct stats_net_dev))
+#define STATS_NET_DEV_SIZE2CMP (STATS_NET_DEV_SIZE - MAX_IFACE_LEN - 1)
 #define STATS_NET_DEV_ULL      7
 #define STATS_NET_DEV_UL       0
 #define STATS_NET_DEV_U                1
@@ -306,6 +307,7 @@ struct stats_net_edev {
 };
 
 #define STATS_NET_EDEV_SIZE    (sizeof(struct stats_net_edev))
+#define STATS_NET_EDEV_SIZE2CMP        (STATS_NET_EDEV_SIZE - MAX_IFACE_LEN)
 #define STATS_NET_EDEV_ULL     9
 #define STATS_NET_EDEV_UL      0
 #define STATS_NET_EDEV_U       0
@@ -657,10 +659,11 @@ struct stats_filesystem {
        char               mountp[MAX_FS_LEN];
 };
 
-#define STATS_FILESYSTEM_SIZE  (sizeof(struct stats_filesystem))
-#define STATS_FILESYSTEM_ULL   5
-#define STATS_FILESYSTEM_UL    0
-#define STATS_FILESYSTEM_U     0
+#define STATS_FILESYSTEM_SIZE          (sizeof(struct stats_filesystem))
+#define STATS_FILESYSTEM_SIZE2CMP      (STATS_FILESYSTEM_SIZE - 2 * MAX_FS_LEN)
+#define STATS_FILESYSTEM_ULL           5
+#define STATS_FILESYSTEM_UL            0
+#define STATS_FILESYSTEM_U             0
 
 /* Structure for Fibre Channel HBA statistics */
 struct stats_fchost {
diff --git a/sa.h b/sa.h
index ea433251d045159e8c91a1ac2cc2dd7ab5688f98..f08f8f8ee6b7055cdbee212747d4b7a9b4a1171b 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -98,6 +98,8 @@
 #define S_F_LOCAL_TIME         0x00004000
 #define S_F_PREFD_TIME_OUTPUT  0x00008000
 #define S_F_SVG_SKIP           0x00010000
+/* Same value as S_F_SVG_SKIP above. Used for sar */
+#define S_F_ZERO_OMIT          0x00010000
 /* Same value as S_F_SVG_SKIP above. Used for a different output format */
 #define S_F_RAW_DEBUG_MODE     0x00010000
 #define S_F_SVG_AUTOSCALE      0x00020000
 #define PRINT_LOCAL_TIME(m)            (((m) & S_F_LOCAL_TIME)   == S_F_LOCAL_TIME)
 #define USE_PREFD_TIME_OUTPUT(m)       (((m) & S_F_PREFD_TIME_OUTPUT)   == S_F_PREFD_TIME_OUTPUT)
 #define SKIP_EMPTY_VIEWS(m)            (((m) & S_F_SVG_SKIP)     == S_F_SVG_SKIP)
+#define DISPLAY_ZERO_OMIT(m)           (((m) & S_F_ZERO_OMIT)    == S_F_ZERO_OMIT)
 #define DISPLAY_DEBUG_MODE(m)          (((m) & S_F_RAW_DEBUG_MODE) == S_F_RAW_DEBUG_MODE)
 #define AUTOSCALE_ON(m)                        (((m) & S_F_SVG_AUTOSCALE) == S_F_SVG_AUTOSCALE)
 #define DISPLAY_ONE_DAY(m)             (((m) & S_F_SVG_ONE_DAY)   == S_F_SVG_ONE_DAY)
diff --git a/sar.c b/sar.c
index 3c2a3d1006ea5f67c29c7260a83d0a2f7324985c..e6b8cc91949ef873c78de32fbe1c37e2653792ee 100644 (file)
--- a/sar.c
+++ b/sar.c
@@ -115,7 +115,7 @@ 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 ] [ --help ] [ --human ] [ --sadc ]\n"
+                         "[ -v ] [ -W ] [ -w ] [ -y ] [ -z ] [ --help ] [ --human ] [ --sadc ]\n"
                          "[ -I { <int_list> | SUM | ALL } ] [ -P { <cpu_list> | ALL } ]\n"
                          "[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]\n"
                          "[ -j { ID | LABEL | PATH | UUID | ... } ]\n"
@@ -1387,6 +1387,11 @@ int main(int argc, char **argv)
                        }
                }
 
+               else if (!strcmp(argv[opt], "-z")) {
+                       flags |= S_F_ZERO_OMIT;
+                       opt++;
+               }
+
                else if ((strlen(argv[opt]) > 1) &&
                         (strlen(argv[opt]) < 4) &&
                         !strncmp(argv[opt], "-", 1) &&