]> granicus.if.org Git - sysstat/commitdiff
sadf: PCP: Add support for A_DISK activity
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 19 May 2019 07:44:10 +0000 (09:44 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 19 May 2019 07:44:10 +0000 (09:44 +0200)
Add metrics displayed by "sar -d" (disks statistics) to PCP archive.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
activity.c
pcp_def_metrics.c
pcp_def_metrics.h
pcp_stats.c
pcp_stats.h
sadf_misc.c

index 8651bdb1328d38d84664a848472657b14a950f3e..c30089529bd693612b0d927eff3222c4ba8207eb 100644 (file)
@@ -555,6 +555,7 @@ struct activity disk_act = {
        .f_json_print   = json_print_disk_stats,
        .f_svg_print    = svg_print_disk_stats,
        .f_raw_print    = raw_print_disk_stats,
+       .f_pcp_print    = pcp_print_disk_stats,
        .f_count_new    = count_new_disk,
        .item_list      = NULL,
        .desc           = "Block devices statistics",
index cde34d17731dc3dbdf105f26f6e3a29aca34a4bf..262722c7ed1556d49a174c5eb28d3a27cdf8519c 100644 (file)
@@ -545,6 +545,66 @@ void pcp_def_queue_metrics(void)
 #endif /* HAVE_PCP */
 }
 
+/*
+ ***************************************************************************
+ * Define PCP metrics for disks statistics.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ ***************************************************************************
+ */
+void pcp_def_disk_metrics(struct activity *a)
+{
+#ifdef HAVE_PCP
+       int inst = 0;
+       static pmInDom indom = PM_INDOM_NULL;
+       struct sa_item *list = a->item_list;
+
+       if (indom == PM_INDOM_NULL) {
+               /* Create domain */
+               indom = pmInDom_build(0, PM_INDOM_DISK);
+
+               /* Create instances */
+               while (list != NULL) {
+                       pmiAddInstance(indom, list->item_name, inst++);
+                       list = list->next;
+               }
+       }
+
+       pmiAddMetric("disk.device.tps",
+                    PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT,
+                    pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE));
+
+       pmiAddMetric("disk.device.read_bytes",
+                    PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT,
+                    pmiUnits(1, -1, 0, PM_SPACE_KBYTE, PM_TIME_SEC, 0));
+
+       pmiAddMetric("disk.device.write_bytes",
+                    PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT,
+                    pmiUnits(1, -1, 0, PM_SPACE_KBYTE, PM_TIME_SEC, 0));
+
+       pmiAddMetric("disk.device.discard_bytes",
+                    PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT,
+                    pmiUnits(1, -1, 0, PM_SPACE_KBYTE, PM_TIME_SEC, 0));
+
+       pmiAddMetric("disk.device.areq_sz",
+                    PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT,
+                    pmiUnits(1, 0, 0, PM_SPACE_KBYTE, 0, 0));
+
+       pmiAddMetric("disk.device.aqu_sz",
+                    PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT,
+                    pmiUnits(0, 0, 0, 0, 0, 0));
+
+       pmiAddMetric("disk.device.await",
+                    PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT,
+                    pmiUnits(0, 0, 0, 0, 0, 0));
+
+       pmiAddMetric("disk.device.util",
+                    PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT,
+                    pmiUnits(0, 0, 0, 0, 0, 0));
+#endif /* HAVE_PCP */
+}
+
 /*
  ***************************************************************************
  * Define PCP metrics for network interfaces (errors) statistics.
index 15a4875c2f406bed1b07c3e1b124b81db7465d43..383c32031579281b3d3366f4fff0016b71def8f0 100644 (file)
@@ -22,6 +22,7 @@ void pcp_def_memory_metrics(struct activity *);
 void pcp_def_ktables_metrics(void);
 void pcp_def_queue_metrics(void);
 void pcp_def_serial_metrics(struct activity *);
+void pcp_def_disk_metrics(struct activity *);
 void pcp_def_net_dev_metrics(struct activity *);
 void pcp_def_net_nfs_metrics(void);
 void pcp_def_net_nfsd_metrics(void);
@@ -53,6 +54,7 @@ void pcp_def_fchost_metrics(struct activity *);
 #define PM_INDOM_FILESYSTEM    5
 #define PM_INDOM_FCHOST                6
 #define PM_INDOM_USB           7
+#define PM_INDOM_DISK          8
 
 
 #endif /* _PCP_DEF_METRICS_H */
index 935042d9e522e0920ed037be7a01a9a5afcc2f2c..f30bd7c4aa1804ff7509e44cc3777166906e8d8c 100644 (file)
@@ -573,6 +573,90 @@ __print_funct_t pcp_print_queue_stats(struct activity *a, int curr, unsigned lon
 #endif /* HAVE_PCP */
 }
 
+/*
+ ***************************************************************************
+ * Display disks statistics in PCP format.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @itv                Interval of time in 1/100th of a second.
+ * @record_hdr Record header for current sample.
+ ***************************************************************************
+ */
+__print_funct_t pcp_print_disk_stats(struct activity *a, int curr, unsigned long long itv,
+                                    struct record_header *record_hdr)
+{
+#ifdef HAVE_PCP
+       int i, j;
+       struct stats_disk *sdc, *sdp, sdpzero;
+       struct ext_disk_stats xds;
+       char *dev_name;
+       char buf[64];
+
+       memset(&sdpzero, 0, STATS_DISK_SIZE);
+
+       for (i = 0; i < a->nr[curr]; i++) {
+
+               sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
+
+               j = check_disk_reg(a, curr, !curr, i);
+               if (j < 0) {
+                       /* This is a newly registered interface. Previous stats are zero */
+                       sdp = &sdpzero;
+               }
+               else {
+                       sdp = (struct stats_disk *) ((char *) a->buf[!curr] + j * a->msize);
+               }
+
+               /* Get device name */
+               dev_name = get_sa_devname(sdc->major, sdc->minor, flags);
+
+               if (a->item_list != NULL) {
+                       /* A list of devices has been entered on the command line */
+                       if (!search_list_item(a->item_list, dev_name))
+                               /* Device not found */
+                               continue;
+               }
+
+               /* Compute extended statistics values */
+               compute_ext_disk_stats(sdc, sdp, itv, &xds);
+
+               snprintf(buf, sizeof(buf), "%f",
+                        S_VALUE(sdp->nr_ios, sdc->nr_ios, itv));
+               pmiPutValue("disk.device.tps", dev_name, buf);
+
+               snprintf(buf, sizeof(buf), "%f",
+                        S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2);
+               pmiPutValue("disk.device.read_bytes", dev_name, buf);
+
+               snprintf(buf, sizeof(buf), "%f",
+                        S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2);
+               pmiPutValue("disk.device.write_bytes", dev_name, buf);
+
+               snprintf(buf, sizeof(buf), "%f",
+                        S_VALUE(sdp->dc_sect, sdc->dc_sect, itv) / 2);
+               pmiPutValue("disk.device.discard_bytes", dev_name, buf);
+
+               snprintf(buf, sizeof(buf), "%f",
+                        xds.arqsz / 2);
+               pmiPutValue("disk.device.areq_sz", dev_name, buf);
+
+               snprintf(buf, sizeof(buf), "%f",
+                        S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0);
+               pmiPutValue("disk.device.aqu_sz", dev_name, buf);
+
+               snprintf(buf, sizeof(buf), "%f",
+                        xds.await);
+               pmiPutValue("disk.device.await", dev_name, buf);
+
+               snprintf(buf, sizeof(buf), "%f",
+                        xds.util / 10.0);
+               pmiPutValue("disk.device.util", dev_name, buf);
+       }
+#endif /* HAVE_PCP */
+}
+
 /*
  ***************************************************************************
  * Display network interfaces statistics in PCP format.
index 79e1e601b8e4034a71210865732801cc1068483e..970664da29eaa01e05c7f2888a07155eb56aea2c 100644 (file)
@@ -31,6 +31,8 @@ __print_funct_t pcp_print_ktables_stats
        (struct activity *, int, unsigned long long, struct record_header *);
 __print_funct_t pcp_print_queue_stats
        (struct activity *, int, unsigned long long, struct record_header *);
+__print_funct_t pcp_print_disk_stats
+       (struct activity *, int, unsigned long long, struct record_header *);
 __print_funct_t pcp_print_serial_stats
        (struct activity *, int, unsigned long long, struct record_header *);
 __print_funct_t pcp_print_net_dev_stats
index 7e33f6f4d39f330f167e84b72112d49801847c3b..8c33965f49f2ce8ed2a24e1873e3d0a6e191b9e5 100644 (file)
@@ -692,6 +692,10 @@ __printf_funct_t print_pcp_statistics(int *tab, int action, struct activity *act
                                        pcp_def_serial_metrics(act[p]);
                                        break;
 
+                               case A_DISK:
+                                       pcp_def_disk_metrics(act[p]);
+                                       break;
+
                                case A_NET_DEV:
                                case A_NET_EDEV:
                                        pcp_def_net_dev_metrics(act[p]);