Add metrics displayed by "sar -d" (disks statistics) to PCP archive.
Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
.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",
#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.
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);
#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 */
#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.
(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
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]);