2 * sadf_misc.c: Functions used by sadf to display special records
3 * (C) 2011-2023 by Sebastien GODARD (sysstat <at> orange.fr)
5 ***************************************************************************
6 * This program is free software; you can redistribute it and/or modify it *
7 * under the terms of the GNU General Public License as published by the *
8 * Free Software Foundation; either version 2 of the License, or (at your *
9 * option) any later version. *
11 * This program is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
16 * You should have received a copy of the GNU General Public License along *
17 * with this program; if not, write to the Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA *
19 ***************************************************************************
27 #include "pcp_def_metrics.h"
32 #define _(string) gettext(string)
34 #define _(string) (string)
38 #include <pcp/pmapi.h>
39 #include <pcp/import.h>
42 extern uint64_t flags;
46 extern unsigned int svg_colors[][SVG_COL_PALETTE_SIZE];
49 ***************************************************************************
50 * Flush data to PCP archive.
53 * @record_hdr Record header for current sample.
54 * @flags Flags for common options.
55 ***************************************************************************
57 void pcp_write_data(struct record_header *record_hdr, unsigned int flags)
61 unsigned long long utc_sec = record_hdr->ust_time;
63 /* Write data to PCP archive */
64 if ((rc = pmiWrite(utc_sec, 0)) < 0) {
65 fprintf(stderr, "PCP: pmiWrite: %s\n", pmiErrStr(rc));
72 ***************************************************************************
73 * Display restart messages (database and ppc formats).
76 * @cur_date Date string of current restart message.
77 * @cur_time Time string of current restart message.
78 * @my_tz Current timezone.
79 * @sep Character used as separator.
80 * @file_hdr System activity file standard header.
81 ***************************************************************************
83 void print_dbppc_restart(char *cur_date, char *cur_time, char *my_tz, char sep,
84 struct file_header *file_hdr)
86 printf("%s%c-1%c", file_hdr->sa_nodename, sep, sep);
87 if (strlen(cur_date)) {
88 printf("%s ", cur_date);
90 printf("%s", cur_time);
91 if (strlen(cur_date)) {
92 printf(" %s", PRINT_LOCAL_TIME(flags) ? my_tz
93 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
96 printf("%cLINUX-RESTART\t(%u CPU)\n",
97 sep, file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
101 ***************************************************************************
102 * Display restart messages (ppc format).
105 * @tab Number of tabulations (unused here).
106 * @action Action expected from current function.
107 * @cur_date Date string of current restart message.
108 * @cur_time Time string of current restart message.
109 * @my_tz Current timezone.
110 * @file_hdr System activity file standard header.
111 * @record_hdr Current record header (unused here).
112 ***************************************************************************
114 __printf_funct_t print_db_restart(int *tab, int action, char *cur_date, char *cur_time,
115 char *my_tz, struct file_header *file_hdr,
116 struct record_header *record_hdr)
118 /* Actions F_BEGIN and F_END ignored */
119 if (action == F_MAIN) {
120 print_dbppc_restart(cur_date, cur_time, my_tz, ';', file_hdr);
125 ***************************************************************************
126 * Display restart messages (database format).
129 * @tab Number of tabulations (unused here).
130 * @action Action expected from current function.
131 * @cur_date Date string of current restart message.
132 * @cur_time Time string of current restart message.
133 * @my_tz Current timezone.
134 * @file_hdr System activity file standard header.
135 * @record_hdr Current record header (unused here).
136 ***************************************************************************
138 __printf_funct_t print_ppc_restart(int *tab, int action, char *cur_date, char *cur_time,
139 char *my_tz, struct file_header *file_hdr,
140 struct record_header *record_hdr)
142 /* Actions F_BEGIN and F_END ignored */
143 if (action == F_MAIN) {
144 print_dbppc_restart(cur_date, cur_time, my_tz, '\t', file_hdr);
149 ***************************************************************************
150 * Display restart messages (XML format).
153 * @tab Number of tabulations.
154 * @action Action expected from current function.
155 * @cur_date Date string of current restart message.
156 * @cur_time Time string of current restart message.
157 * @my_tz Current timezone (unused here).
158 * @file_hdr System activity file standard header.
159 * @record_hdr Current record header (unused here).
162 * @tab Number of tabulations.
163 ***************************************************************************
165 __printf_funct_t print_xml_restart(int *tab, int action, char *cur_date, char *cur_time,
166 char *my_tz, struct file_header *file_hdr,
167 struct record_header *record_hdr)
169 if (action & F_BEGIN) {
170 xprintf((*tab)++, "<restarts>");
172 if (action & F_MAIN) {
173 xprintf(*tab, "<boot date=\"%s\" time=\"%s\" tz=\"%s\" cpu_count=\"%d\"/>",
175 PRINT_LOCAL_TIME(flags) ? my_tz
176 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
178 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
180 if (action & F_END) {
181 xprintf(--(*tab), "</restarts>");
186 ***************************************************************************
187 * Display restart messages (JSON format).
190 * @tab Number of tabulations.
191 * @action Action expected from current function.
192 * @cur_date Date string of current restart message.
193 * @cur_time Time string of current restart message.
194 * @my_tz Current timezone (unused here).
195 * @file_hdr System activity file standard header.
196 * @record_hdr Current record header (unused here).
199 * @tab Number of tabulations.
200 ***************************************************************************
202 __printf_funct_t print_json_restart(int *tab, int action, char *cur_date, char *cur_time,
203 char *my_tz, struct file_header *file_hdr,
204 struct record_header *record_hdr)
206 static int sep = FALSE;
208 if (action & F_BEGIN) {
210 xprintf((*tab)++, "\"restarts\": [");
212 if (action & F_MAIN) {
216 xprintf((*tab)++, "{");
217 xprintf(*tab, "\"boot\": {\"date\": \"%s\", \"time\": \"%s\", \"tz\": \"%s\", \"cpu_count\": %d}",
219 PRINT_LOCAL_TIME(flags) ? my_tz
220 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
222 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
223 xprintf0(--(*tab), "}");
226 if (action & F_END) {
231 xprintf0(--(*tab), "]");
236 ***************************************************************************
237 * Display restart messages (raw format).
240 * @tab Number of tabulations (unused here).
241 * @action Action expected from current function.
242 * @cur_date Date string of current restart message.
243 * @cur_time Time string of current restart message.
244 * @my_tz Current timezone.
245 * @file_hdr System activity file standard header.
246 * @record_hdr Current record header (unused here).
247 ***************************************************************************
249 __printf_funct_t print_raw_restart(int *tab, int action, char *cur_date, char *cur_time,
250 char *my_tz, struct file_header *file_hdr,
251 struct record_header *record_hdr)
253 /* Actions F_BEGIN and F_END ignored */
254 if (action == F_MAIN) {
255 printf("%s", cur_time);
256 if (strlen(cur_date)) {
257 printf(" %s", PRINT_LOCAL_TIME(flags) ? my_tz
258 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
261 printf("; LINUX-RESTART (%u CPU)\n",
262 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
267 ***************************************************************************
268 * Display restart messages (PCP format).
271 * @tab Number of tabulations (unused here).
272 * @action Action expected from current function.
273 * @cur_date Date string of current restart message (unused here).
274 * @cur_time Time string of current restart message (unused here).
275 * @my_tz Current timezone (unused here).
276 * @file_hdr System activity file standard header.
277 * @record_hdr Current record header.
278 ***************************************************************************
280 __printf_funct_t print_pcp_restart(int *tab, int action, char *cur_date, char *cur_time,
281 char *my_tz, struct file_header *file_hdr,
282 struct record_header *record_hdr)
285 static int def_metrics = FALSE;
288 if (action & F_BEGIN) {
290 pmiAddMetric("system.restart.count",
291 PM_IN_NULL, PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_DISCRETE,
292 pmiUnits(0, 0, 1, 0, 0, PM_COUNT_ONE));
294 pmiAddMetric("system.restart.ncpu",
295 PM_IN_NULL, PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_DISCRETE,
296 pmiUnits(0, 0, 1, 0, 0, PM_COUNT_ONE));
301 if (action & F_MAIN) {
302 pmiPutValue("system.restart.count", NULL, "1");
304 snprintf(buf, sizeof(buf), "%u",
305 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
306 pmiPutValue("system.restart.ncpu", NULL, buf);
308 /* Write data to PCP archive */
309 pcp_write_data(record_hdr, flags);
311 #endif /* HAVE_PCP */
315 ***************************************************************************
316 * Display comments (database and ppc formats).
319 * @cur_date Date string of current restart message.
320 * @cur_time Time string of current restart message.
321 * @my_tz Current timezone.
322 * @comment Comment to display.
323 * @sep Character used as separator.
324 * @file_hdr System activity file standard header.
325 ***************************************************************************
327 void print_dbppc_comment(char *cur_date, char *cur_time, char *my_tz, char *comment,
328 char sep, struct file_header *file_hdr)
330 printf("%s%c-1%c", file_hdr->sa_nodename, sep, sep);
331 if (strlen(cur_date)) {
332 printf("%s ", cur_date);
334 printf("%s", cur_time);
335 if (strlen(cur_date)) {
336 printf(" %s", PRINT_LOCAL_TIME(flags) ? my_tz
337 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
340 printf("%cCOM %s\n", sep, comment);
344 ***************************************************************************
345 * Display comments (database format).
348 * @tab Number of tabulations (unused here).
349 * @action Action expected from current function.
350 * @cur_date Date string of current restart message.
351 * @cur_time Time string of current restart message.
352 * @my_tz Current timezone.
353 * @comment Comment to display.
354 * @file_hdr System activity file standard header.
355 * @record_hdr Current record header (unused here).
356 ***************************************************************************
358 __printf_funct_t print_db_comment(int *tab, int action, char *cur_date, char *cur_time,
359 char *my_tz, char *comment, struct file_header *file_hdr,
360 struct record_header *record_hdr)
362 /* Actions F_BEGIN and F_END ignored */
363 if (action & F_MAIN) {
364 print_dbppc_comment(cur_date, cur_time, my_tz, comment, ';', file_hdr);
369 ***************************************************************************
370 * Display comments (ppc format).
373 * @tab Number of tabulations (unused here).
374 * @action Action expected from current function.
375 * @cur_date Date string of current restart message.
376 * @cur_time Time string of current restart message.
377 * @my_tz Current timezone.
378 * @comment Comment to display.
379 * @file_hdr System activity file standard header.
380 * @record_hdr Current record header (unused here).
381 ***************************************************************************
383 __printf_funct_t print_ppc_comment(int *tab, int action, char *cur_date, char *cur_time,
384 char *my_tz, char *comment, struct file_header *file_hdr,
385 struct record_header *record_hdr)
387 /* Actions F_BEGIN and F_END ignored */
388 if (action & F_MAIN) {
389 print_dbppc_comment(cur_date, cur_time, my_tz, comment, '\t', file_hdr);
394 ***************************************************************************
395 * Display comments (XML format).
398 * @tab Number of tabulations.
399 * @action Action expected from current function.
400 * @cur_date Date string of current comment.
401 * @cur_time Time string of current comment.
402 * @my_tz Current timezone.
403 * @comment Comment to display.
404 * @file_hdr System activity file standard header (unused here).
405 * @record_hdr Current record header (unused here).
408 * @tab Number of tabulations.
409 ***************************************************************************
411 __printf_funct_t print_xml_comment(int *tab, int action, char *cur_date, char *cur_time,
412 char *my_tz, char *comment, struct file_header *file_hdr,
413 struct record_header *record_hdr)
415 if (action & F_BEGIN) {
416 xprintf((*tab)++, "<comments>");
418 if (action & F_MAIN) {
419 xprintf(*tab, "<comment date=\"%s\" time=\"%s\" tz=\"%s\" com=\"%s\"/>",
421 PRINT_LOCAL_TIME(flags) ? my_tz
422 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
426 if (action & F_END) {
427 xprintf(--(*tab), "</comments>");
432 ***************************************************************************
433 * Display comments (JSON format).
436 * @tab Number of tabulations.
437 * @action Action expected from current function.
438 * @cur_date Date string of current comment.
439 * @cur_time Time string of current comment.
440 * @my_tz Current timezone.
441 * @comment Comment to display.
442 * @file_hdr System activity file standard header (unused here).
443 * @record_hdr Current record header (unused here).
446 * @tab Number of tabulations.
447 ***************************************************************************
449 __printf_funct_t print_json_comment(int *tab, int action, char *cur_date, char *cur_time,
450 char *my_tz, char *comment, struct file_header *file_hdr,
451 struct record_header *record_hdr)
453 static int sep = FALSE;
455 if (action & F_BEGIN) {
457 xprintf((*tab)++, "\"comments\": [");
459 if (action & F_MAIN) {
463 xprintf((*tab)++, "{");
465 "\"comment\": {\"date\": \"%s\", \"time\": \"%s\", "
466 "\"tz\": \"%s\", \"com\": \"%s\"}",
468 PRINT_LOCAL_TIME(flags) ? my_tz
469 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
472 xprintf0(--(*tab), "}");
475 if (action & F_END) {
480 xprintf0(--(*tab), "]");
485 ***************************************************************************
486 * Display comments (raw format).
489 * @tab Number of tabulations (unused here).
490 * @action Action expected from current function.
491 * @cur_date Date string of current restart message.
492 * @cur_time Time string of current restart message.
493 * @my_tz Current timezone.
494 * @comment Comment to display.
495 * @file_hdr System activity file standard header (unused here).
496 * @record_hdr Current record header (unused here).
497 ***************************************************************************
499 __printf_funct_t print_raw_comment(int *tab, int action, char *cur_date, char *cur_time,
500 char *my_tz, char *comment, struct file_header *file_hdr,
501 struct record_header *record_hdr)
503 /* Actions F_BEGIN and F_END ignored */
504 if (action & F_MAIN) {
505 printf("%s", cur_time);
506 if (strlen(cur_date)) {
508 PRINT_LOCAL_TIME(flags) ? my_tz
509 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
512 printf("; COM %s\n", comment);
517 ***************************************************************************
518 * Display comments (PCP format).
521 * @tab Number of tabulations (unused here).
522 * @action Action expected from current function.
523 * @cur_date Date string of current restart message (unused here).
524 * @cur_time Time string of current restart message (unused here).
525 * @my_tz Current timezone (unused here).
526 * @comment Comment to display.
527 * @file_hdr System activity file standard header (unused here).
528 * @record_hdr Current record header.
529 ***************************************************************************
531 __printf_funct_t print_pcp_comment(int *tab, int action, char *cur_date, char *cur_time,
532 char *my_tz, char *comment, struct file_header *file_hdr,
533 struct record_header *record_hdr)
536 static int def_metrics = FALSE;
538 if (action & F_BEGIN) {
540 pmiAddMetric("system.comment.value",
541 PM_IN_NULL, PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_DISCRETE,
542 pmiUnits(0, 0, 0, 0, 0, 0));
547 if (action & F_MAIN) {
548 pmiPutValue("system.comment.value", NULL, comment);
550 /* Write data to PCP archive */
551 pcp_write_data(record_hdr, flags);
553 #endif /* HAVE_PCP */
557 ***************************************************************************
558 * Display the "statistics" part of the report (XML format).
561 * @tab Number of tabulations.
562 * @action Action expected from current function.
563 * @act Array of activities (unused here).
564 * @id_seq Activity sequence (unused here).
567 * @tab Number of tabulations.
568 ***************************************************************************
570 __printf_funct_t print_xml_statistics(int *tab, int action, struct activity *act[],
571 unsigned int id_seq[])
573 if (action & F_BEGIN) {
574 xprintf((*tab)++, "<statistics>");
576 if (action & F_END) {
577 xprintf(--(*tab), "</statistics>");
582 ***************************************************************************
583 * Display the "statistics" part of the report (JSON format).
586 * @tab Number of tabulations.
587 * @action Action expected from current function.
588 * @act Array of activities (unused here).
589 * @id_seq Activity sequence (unused here).
592 * @tab Number of tabulations.
593 ***************************************************************************
595 __printf_funct_t print_json_statistics(int *tab, int action, struct activity *act[],
596 unsigned int id_seq[])
598 static int sep = FALSE;
600 if (action & F_BEGIN) {
602 xprintf((*tab)++, "\"statistics\": [");
604 if (action & F_MAIN) {
606 xprintf(--(*tab), "},");
608 xprintf((*tab)++, "{");
611 if (action & F_END) {
613 xprintf(--(*tab), "}");
616 xprintf0(--(*tab), "]");
621 ***************************************************************************
622 * Display the "statistics" part of the report (PCP format).
625 * @tab Number of tabulations (unused here).
626 * @action Action expected from current function.
627 * @act Array of activities.
628 * @id_seq Activity sequence.
629 ***************************************************************************
631 __printf_funct_t print_pcp_statistics(int *tab, int action, struct activity *act[],
632 unsigned int id_seq[])
635 if (action & F_BEGIN) {
638 for (i = 0; i < NR_ACT; i++) {
640 continue; /* Activity not in file */
642 p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND);
643 if (!IS_SELECTED(act[p]->options))
644 continue; /* Activity not selected */
646 switch (act[p]->id) {
651 pcp_def_cpu_metrics(act[p]);
655 pcp_def_pcsw_metrics();
659 pcp_def_irq_metrics(act[p]);
660 pcp_def_cpu_metrics(act[p]); /* For per_CPU int metrics */
664 pcp_def_swap_metrics();
668 pcp_def_paging_metrics();
672 pcp_def_io_metrics();
676 pcp_def_memory_metrics(act[p]);
680 pcp_def_ktables_metrics();
684 pcp_def_queue_metrics();
688 pcp_def_serial_metrics(act[p]);
692 pcp_def_disk_metrics(act[p]);
697 pcp_def_net_dev_metrics(act[p]);
701 pcp_def_net_nfs_metrics();
705 pcp_def_net_nfsd_metrics();
709 pcp_def_net_sock_metrics();
713 pcp_def_net_ip_metrics();
717 pcp_def_net_eip_metrics();
721 pcp_def_net_icmp_metrics();
725 pcp_def_net_eicmp_metrics();
729 pcp_def_net_tcp_metrics();
733 pcp_def_net_etcp_metrics();
737 pcp_def_net_udp_metrics();
741 pcp_def_net_sock6_metrics();
745 pcp_def_net_ip6_metrics();
749 pcp_def_net_eip6_metrics();
753 pcp_def_net_icmp6_metrics();
757 pcp_def_net_eicmp6_metrics();
761 pcp_def_net_udp6_metrics();
765 pcp_def_huge_metrics();
769 pcp_def_pwr_fan_metrics(act[p]);
773 pcp_def_pwr_temp_metrics(act[p]);
777 pcp_def_pwr_in_metrics(act[p]);
781 pcp_def_pwr_bat_metrics(act[p]);
785 pcp_def_pwr_usb_metrics(act[p]);
789 pcp_def_filesystem_metrics(act[p]);
793 pcp_def_fchost_metrics(act[p]);
799 pcp_def_psi_metrics(act[p]);
804 #endif /* HAVE_PCP */
808 ***************************************************************************
809 * Display the "timestamp" part of the report (db and ppc format).
812 * @fmt Output format (F_DB_OUTPUT or F_PPC_OUTPUT).
813 * @file_hdr System activity file standard header.
814 * @cur_date Date string of current record.
815 * @cur_time Time string of current record.
816 * @my_tz Current timezone.
817 * @itv Interval of time with preceding record.
820 * Pointer on the "timestamp" string.
821 ***************************************************************************
823 char *print_dbppc_timestamp(int fmt, struct file_header *file_hdr, char *cur_date,
824 char *cur_time, char *my_tz, unsigned long long itv)
826 int isdb = (fmt == F_DB_OUTPUT);
827 static char pre[512];
828 char temp1[128], temp2[256];
830 /* This substring appears on every output line, preformat it here */
831 snprintf(temp1, sizeof(temp1), "%s%s%llu%s",
832 file_hdr->sa_nodename, seps[isdb], itv, seps[isdb]);
833 if (strlen(cur_date)) {
834 snprintf(temp2, sizeof(temp2), "%s%s ", temp1, cur_date);
837 strcpy(temp2, temp1);
840 if (strlen(cur_date) && (!PRINT_TRUE_TIME(flags) ||
841 (PRINT_TRUE_TIME(flags) && strlen(file_hdr->sa_tzname)))) {
842 snprintf(pre, sizeof(pre), "%s%s %s", temp2, cur_time,
843 PRINT_LOCAL_TIME(flags) ? my_tz
844 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
848 snprintf(pre, sizeof(pre), "%s%s", temp2, cur_time);
853 pre[sizeof(pre) - 1] = '\0';
855 if (DISPLAY_HORIZONTALLY(flags)) {
863 ***************************************************************************
864 * Display the "timestamp" part of the report (ppc format).
867 * @parm Pointer on specific parameters (unused here).
868 * @action Action expected from current function.
869 * @cur_date Date string of current record.
870 * @cur_time Time string of current record.
871 * @my_tz Current timezone.
872 * @itv Interval of time with preceding record.
873 * @record_hdr Record header for current sample (unused here).
874 * @file_hdr System activity file standard header.
875 * @flags Flags for common options (unused here).
878 * Pointer on the "timestamp" string.
879 ***************************************************************************
881 __tm_funct_t print_ppc_timestamp(void *parm, int action, char *cur_date,
882 char *cur_time, char *my_tz, unsigned long long itv,
883 struct record_header *record_hdr,
884 struct file_header *file_hdr, unsigned int flags)
886 if (action & F_BEGIN) {
887 return print_dbppc_timestamp(F_PPC_OUTPUT, file_hdr, cur_date, cur_time,
895 ***************************************************************************
896 * Display the "timestamp" part of the report (db format).
899 * @parm Pointer on specific parameters (unused here).
900 * @action Action expected from current function.
901 * @cur_date Date string of current record.
902 * @cur_time Time string of current record.
903 * @my_tz Current timezone.
904 * @itv Interval of time with preceding record.
905 * @record_hdr Record header for current sample (unused here).
906 * @file_hdr System activity file standard header.
907 * @flags Flags for common options.
910 * Pointer on the "timestamp" string.
911 ***************************************************************************
913 __tm_funct_t print_db_timestamp(void *parm, int action, char *cur_date,
914 char *cur_time, char *my_tz, unsigned long long itv,
915 struct record_header *record_hdr,
916 struct file_header *file_hdr, unsigned int flags)
918 if (action & F_BEGIN) {
919 return print_dbppc_timestamp(F_DB_OUTPUT, file_hdr, cur_date, cur_time,
922 if (action & F_END) {
923 if (DISPLAY_HORIZONTALLY(flags)) {
932 ***************************************************************************
933 * Display the "timestamp" part of the report (XML format).
936 * @parm Specific parameter. Here: number of tabulations.
937 * @action Action expected from current function.
938 * @cur_date Date string of current comment.
939 * @cur_time Time string of current comment.
940 * @my_tz Current timezone.
941 * @itv Interval of time with preceding record.
942 * @record_hdr Record header for current sample (unused here).
943 * @file_hdr System activity file standard header (unused here).
944 * @flags Flags for common options.
945 ***************************************************************************
947 __tm_funct_t print_xml_timestamp(void *parm, int action, char *cur_date,
948 char *cur_time, char *my_tz, unsigned long long itv,
949 struct record_header *record_hdr,
950 struct file_header *file_hdr, unsigned int flags)
952 int *tab = (int *) parm;
954 if (action & F_BEGIN) {
955 xprintf((*tab)++, "<timestamp date=\"%s\" time=\"%s\" tz=\"%s\" interval=\"%llu\">",
957 PRINT_LOCAL_TIME(flags) ? my_tz
958 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
962 if (action & F_END) {
963 xprintf(--(*tab), "</timestamp>");
970 ***************************************************************************
971 * Display the "timestamp" part of the report (JSON format).
974 * @parm Specific parameter. Here: number of tabulations.
975 * @action Action expected from current function.
976 * @cur_date Date string of current comment.
977 * @cur_time Time string of current comment.
978 * @my_tz Current timezone.
979 * @itv Interval of time with preceding record.
980 * @record_hdr Record header for current sample (unused here).
981 * @file_hdr System activity file standard header (unused here).
982 * @flags Flags for common options.
983 ***************************************************************************
985 __tm_funct_t print_json_timestamp(void *parm, int action, char *cur_date,
986 char *cur_time, char *my_tz, unsigned long long itv,
987 struct record_header *record_hdr,
988 struct file_header *file_hdr, unsigned int flags)
990 int *tab = (int *) parm;
992 if (action & F_BEGIN) {
994 "\"timestamp\": {\"date\": \"%s\", \"time\": \"%s\", "
995 "\"tz\": \"%s\", \"interval\": %llu}",
997 PRINT_LOCAL_TIME(flags) ? my_tz
998 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
1002 if (action & F_MAIN) {
1005 if (action & F_END) {
1013 ***************************************************************************
1014 * Display the "timestamp" part of the report (raw format).
1017 * @parm Pointer on specific parameters (unused here).
1018 * @action Action expected from current function.
1019 * @cur_date Date string of current record.
1020 * @cur_time Time string of current record.
1021 * @my_tz Current timezone.
1022 * @itv Interval of time with preceding record (unused here).
1023 * @record_hdr Record header for current sample (unused here).
1024 * @file_hdr System activity file standard header (unused here).
1025 * @flags Flags for common options.
1028 * Pointer on the "timestamp" string.
1029 ***************************************************************************
1031 __tm_funct_t print_raw_timestamp(void *parm, int action, char *cur_date,
1032 char *cur_time, char *my_tz, unsigned long long itv,
1033 struct record_header *record_hdr,
1034 struct file_header *file_hdr, unsigned int flags)
1036 static char pre[80];
1038 if (action & F_BEGIN) {
1039 if (strlen(cur_date) && (!PRINT_TRUE_TIME(flags) ||
1040 (PRINT_TRUE_TIME(flags) && strlen(file_hdr->sa_tzname)))) {
1041 snprintf(pre, sizeof(pre), "%s %s", cur_time,
1042 PRINT_LOCAL_TIME(flags) ? my_tz
1043 : (PRINT_TRUE_TIME(flags) ? file_hdr->sa_tzname
1047 snprintf(pre, sizeof(pre), "%s", cur_time);
1049 pre[sizeof(pre) - 1] = '\0';
1058 ***************************************************************************
1059 * Display the "timestamp" part of the report (PCP format).
1062 * @parm Pointer on specific parameters (unused here).
1063 * @action Action expected from current function.
1064 * @cur_date Date string of current record (unused here).
1065 * @cur_time Time string of current record (unused here).
1066 * @my_tz Current timezone (unused here).
1067 * @itv Interval of time with preceding record (unused here).
1068 * @record_hdr Record header for current sample.
1069 * @file_hdr System activity file standard header (unused here).
1070 * @flags Flags for common options.
1073 * Pointer on the "timestamp" string.
1074 ***************************************************************************
1076 __tm_funct_t print_pcp_timestamp(void *parm, int action, char *cur_date,
1077 char *cur_time, char *my_tz, unsigned long long itv,
1078 struct record_header *record_hdr,
1079 struct file_header *file_hdr, unsigned int flags)
1081 if (action & F_END) {
1082 pcp_write_data(record_hdr, flags);
1089 ***************************************************************************
1090 * Display the header of the report (XML format).
1093 * @parm Specific parameter. Here: number of tabulations.
1094 * @action Action expected from current function.
1095 * @dfile Unused here (PCP archive file).
1096 * @my_tz Current timezone (unused here).
1097 * @file_magic System activity file magic header.
1098 * @file_hdr System activity file standard header.
1099 * @act Array of activities (unused here).
1100 * @id_seq Activity sequence (unused here).
1101 * @file_actlst List of (known or unknown) activities in file (unused here).
1104 * @parm Number of tabulations.
1105 ***************************************************************************
1107 __printf_funct_t print_xml_header(void *parm, int action, char *dfile, char *my_tz,
1108 struct file_magic *file_magic,
1109 struct file_header *file_hdr,
1110 struct activity *act[], unsigned int id_seq[],
1111 struct file_activity *file_actlst)
1113 struct tm rectime, loc_t;
1114 time_t t = file_hdr->sa_ust_time;
1115 int *tab = (int *) parm;
1117 if (action & F_BEGIN) {
1118 char cur_time[TIMESTAMP_LEN];
1120 printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1121 printf("<!DOCTYPE sysstat PUBLIC \"DTD v%s sysstat //EN\"\n",
1123 printf("\"http://pagesperso-orange.fr/sebastien.godard/sysstat-%s.dtd\">\n",
1126 xprintf(*tab, "<sysstat\n"
1127 "xmlns=\"http://pagesperso-orange.fr/sebastien.godard/sysstat\"\n"
1128 "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
1129 "xsi:schemaLocation=\"http://pagesperso-orange.fr/sebastien.godard sysstat.xsd\">");
1131 xprintf(++(*tab), "<sysdata-version>%s</sysdata-version>",
1134 xprintf(*tab, "<host nodename=\"%s\">", file_hdr->sa_nodename);
1135 xprintf(++(*tab), "<sysname>%s</sysname>", file_hdr->sa_sysname);
1136 xprintf(*tab, "<release>%s</release>", file_hdr->sa_release);
1138 xprintf(*tab, "<machine>%s</machine>", file_hdr->sa_machine);
1139 xprintf(*tab, "<number-of-cpus>%d</number-of-cpus>",
1140 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
1142 /* Fill file timestmap structure (rectime) */
1143 get_file_timestamp_struct(flags, &rectime, file_hdr);
1144 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
1145 xprintf(*tab, "<file-date>%s</file-date>", cur_time);
1147 if (gmtime_r(&t, &loc_t) != NULL) {
1148 strftime(cur_time, sizeof(cur_time), "%T", &loc_t);
1149 xprintf(*tab, "<file-utc-time>%s</file-utc-time>", cur_time);
1152 xprintf(*tab, "<timezone>%s</timezone>", file_hdr->sa_tzname);
1154 if (action & F_END) {
1155 xprintf(--(*tab), "</host>");
1156 xprintf(--(*tab), "</sysstat>");
1161 ***************************************************************************
1162 * Display the header of the report (JSON format).
1165 * @parm Specific parameter. Here: number of tabulations.
1166 * @action Action expected from current function.
1167 * @dfile Unused here (PCP archive file).
1168 * @my_tz Current timezone (unused here).
1169 * @file_magic System activity file magic header.
1170 * @file_hdr System activity file standard header.
1171 * @act Array of activities (unused here).
1172 * @id_seq Activity sequence (unused here).
1173 * @file_actlst List of (known or unknown) activities in file (unused here).
1176 * @parm Number of tabulations.
1177 ***************************************************************************
1179 __printf_funct_t print_json_header(void *parm, int action, char *dfile, char *my_tz,
1180 struct file_magic *file_magic,
1181 struct file_header *file_hdr,
1182 struct activity *act[], unsigned int id_seq[],
1183 struct file_activity *file_actlst)
1185 struct tm rectime, loc_t;
1186 time_t t = file_hdr->sa_ust_time;
1187 int *tab = (int *) parm;
1189 if (action & F_BEGIN) {
1190 char cur_time[TIMESTAMP_LEN];
1192 xprintf(*tab, "{\"sysstat\": {");
1194 xprintf(++(*tab), "\"hosts\": [");
1195 xprintf(++(*tab), "{");
1196 xprintf(++(*tab), "\"nodename\": \"%s\",", file_hdr->sa_nodename);
1197 xprintf(*tab, "\"sysname\": \"%s\",", file_hdr->sa_sysname);
1198 xprintf(*tab, "\"release\": \"%s\",", file_hdr->sa_release);
1200 xprintf(*tab, "\"machine\": \"%s\",", file_hdr->sa_machine);
1201 xprintf(*tab, "\"number-of-cpus\": %d,",
1202 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
1204 /* Fill file timestmap structure (rectime) */
1205 get_file_timestamp_struct(flags, &rectime, file_hdr);
1206 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
1207 xprintf(*tab, "\"file-date\": \"%s\",", cur_time);
1209 if (gmtime_r(&t, &loc_t) != NULL) {
1210 strftime(cur_time, sizeof(cur_time), "%T", &loc_t);
1211 xprintf(*tab, "\"file-utc-time\": \"%s\",", cur_time);
1214 xprintf0(*tab, "\"timezone\": \"%s\"", file_hdr->sa_tzname);
1216 if (action & F_END) {
1218 xprintf(--(*tab), "}");
1219 xprintf(--(*tab), "]");
1220 xprintf(--(*tab), "}}");
1225 ***************************************************************************
1226 * Display data file header.
1229 * @parm Specific parameter (unused here).
1230 * @action Action expected from current function.
1231 * @dfile Name of system activity data file (unused here).
1232 * @my_tz Current timezone (unused here).
1233 * @file_magic System activity file magic header.
1234 * @file_hdr System activity file standard header.
1235 * @act Array of activities.
1236 * @id_seq Activity sequence.
1237 * @file_actlst List of (known or unknown) activities in file.
1238 ***************************************************************************
1240 __printf_funct_t print_hdr_header(void *parm, int action, char *dfile, char *my_tz,
1241 struct file_magic *file_magic,
1242 struct file_header *file_hdr,
1243 struct activity *act[], unsigned int id_seq[],
1244 struct file_activity *file_actlst)
1246 /* Actions F_MAIN and F_END ignored */
1247 if (action & F_BEGIN) {
1248 struct tm rectime, loc_t;
1249 time_t t = file_hdr->sa_ust_time;
1251 char cur_time[TIMESTAMP_LEN];
1252 struct file_activity *fal;
1254 printf(_("System activity data file: %s (%#x)\n"),
1255 dfile, file_magic->format_magic);
1257 display_sa_file_version(stdout, file_magic);
1259 if (file_magic->format_magic != FORMAT_MAGIC) {
1263 printf(_("Genuine sa datafile: %s (%x)\n"),
1264 file_magic->upgraded ? _("no") : _("yes"),
1265 file_magic->upgraded);
1267 printf(_("Host: "));
1268 print_gal_header(localtime_r(&t, &rectime),
1269 file_hdr->sa_sysname, file_hdr->sa_release,
1270 file_hdr->sa_nodename, file_hdr->sa_machine,
1271 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1,
1274 /* Fill file timestamp structure (rectime) */
1275 get_file_timestamp_struct(flags, &rectime, file_hdr);
1276 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
1277 printf(_("File date: %s\n"), cur_time);
1279 if (gmtime_r(&t, &loc_t) != NULL) {
1280 printf(_("File time: "));
1281 strftime(cur_time, sizeof(cur_time), "%T", &loc_t);
1282 printf("%s UTC (%llu)\n", cur_time, file_hdr->sa_ust_time);
1285 printf(_("Timezone: %s\n"), file_hdr->sa_tzname);
1287 /* File composition: file_header, file_activity, record_header */
1288 printf(_("File composition: (%u,%u,%u),(%u,%u,%u),(%u,%u,%u)\n"),
1289 file_magic->hdr_types_nr[0], file_magic->hdr_types_nr[1], file_magic->hdr_types_nr[2],
1290 file_hdr->act_types_nr[0], file_hdr->act_types_nr[1], file_hdr->act_types_nr[2],
1291 file_hdr->rec_types_nr[0], file_hdr->rec_types_nr[1], file_hdr->rec_types_nr[2]);
1293 printf(_("Size of a long int: %d\n"), file_hdr->sa_sizeof_long);
1294 printf("HZ = %lu\n", file_hdr->sa_hz);
1295 printf(_("Number of activities in file: %u\n"),
1296 file_hdr->sa_act_nr);
1297 printf(_("Extra structures available: %c\n"),
1298 file_hdr->extra_next ? 'Y' : 'N');
1300 printf(_("List of activities:\n"));
1302 for (i = 0; i < file_hdr->sa_act_nr; i++, fal++) {
1304 p = get_activity_position(act, fal->id, RESUME_IF_NOT_FOUND);
1306 printf("%02u: [%02x] ", fal->id, fal->magic);
1308 printf("%-20s", act[p]->name);
1311 printf("%-20s", _("Unknown activity"));
1313 printf(" %c:%4d", fal->has_nr ? 'Y' : 'N', fal->nr);
1315 printf("x%d", fal->nr2);
1317 printf("\t(%u,%u,%u)", fal->types_nr[0], fal->types_nr[1], fal->types_nr[2]);
1318 if ((p >= 0) && (act[p]->magic != fal->magic)) {
1319 printf(_(" \t[Unknown format]"));
1327 ***************************************************************************
1328 * Display the header of the report (SVG format).
1331 * @parm Specific parameters. Here: number of rows of views to display
1332 * or canvas height entered on the command line (@graph_nr), and
1333 * max number of views on a single row (@views_per_row).
1334 * @action Action expected from current function.
1335 * @dfile Name of system activity data file (unused here).
1336 * @my_tz Current timezone (unused here).
1337 * @file_magic System activity file magic header (unused here).
1338 * @file_hdr System activity file standard header.
1339 * @act Array of activities (unused here).
1340 * @id_seq Activity sequence (unused here).
1341 * @file_actlst List of (known or unknown) activities in file (unused here).
1342 ***************************************************************************
1344 __printf_funct_t print_svg_header(void *parm, int action, char *dfile, char *my_tz,
1345 struct file_magic *file_magic,
1346 struct file_header *file_hdr,
1347 struct activity *act[], unsigned int id_seq[],
1348 struct file_activity *file_actlst)
1350 struct svg_hdr_parm *hdr_parm = (struct svg_hdr_parm *) parm;
1352 time_t t = file_hdr->sa_ust_time;
1354 if (action & F_BEGIN) {
1355 printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1356 printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ");
1357 printf("\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
1358 printf("<svg xmlns=\"http://www.w3.org/2000/svg\"");
1359 if (DISPLAY_TOC(flags)) {
1360 printf(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
1362 if (action & F_END) {
1367 if (action & F_MAIN) {
1368 unsigned int height;
1370 if (SET_CANVAS_HEIGHT(flags)) {
1372 * Option "-O height=..." used: @graph_nr is
1373 * the SVG canvas height set on the command line.
1375 height = hdr_parm->graph_nr;
1378 height = SVG_H_YSIZE +
1379 SVG_C_YSIZE * (DISPLAY_TOC(flags) ? hdr_parm->nr_act_dispd : 0) +
1380 SVG_T_YSIZE * hdr_parm->graph_nr;
1383 /* Min canvas height is 100 (at least to display "No data") */
1386 printf(" width=\"%d\" height=\"%u\""
1387 " fill=\"black\" stroke=\"#%06x\" stroke-width=\"1\">\n",
1388 SVG_T_XSIZE * (hdr_parm->views_per_row), height,
1389 svg_colors[palette][SVG_COL_DEFAULT_IDX]);
1390 printf("<text x=\"0\" y=\"30\" text-anchor=\"start\" stroke=\"#%06x\">",
1391 svg_colors[palette][SVG_COL_HEADER_IDX]);
1392 print_gal_header(localtime_r(&t, &rectime),
1393 file_hdr->sa_sysname, file_hdr->sa_release,
1394 file_hdr->sa_nodename, file_hdr->sa_machine,
1395 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1,
1397 printf("</text>\n");
1398 if (DISPLAY_TOC(flags)) {
1399 unsigned int ht = 0;
1402 for (i = 0; i < NR_ACT; i++) {
1404 continue; /* Activity not in file */
1406 p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND);
1407 if (!IS_SELECTED(act[p]->options) || !act[p]->g_nr)
1408 continue; /* Activity not selected or no graph available */
1410 printf("<a xlink:href=\"#g%u-0\" xlink:title=\"%s\">\n",
1411 act[p]->id, act[p]->name);
1412 printf("<text x=\"10\" y=\"%u\">%s</text></a>\n",
1413 SVG_H_YSIZE + ht, act[p]->desc);
1419 if (action & F_END) {
1420 if (!(action & F_BEGIN)) {
1421 if (!hdr_parm->graph_nr) {
1422 /* No views displayed */
1423 printf("<text x= \"0\" y=\"%d\" text-anchor=\"start\" stroke=\"#%06x\">",
1425 SVG_C_YSIZE * (DISPLAY_TOC(flags) ? hdr_parm->nr_act_dispd : 0),
1426 svg_colors[palette][SVG_COL_ERROR_IDX]);
1427 printf("No data!</text>\n");
1429 /* Give actual SVG height */
1430 printf("<!-- Actual canvas height: %d -->\n",
1432 SVG_C_YSIZE * (DISPLAY_TOC(flags) ? hdr_parm->nr_act_dispd : 0) +
1433 SVG_T_YSIZE * hdr_parm->graph_nr);
1440 ***************************************************************************
1441 * PCP header function.
1444 * @parm Specific parameter (unused here).
1445 * @action Action expected from current function.
1446 * @dfile Name of PCP archive file.
1447 * @my_tz Current timezone (unused here).
1448 * @file_magic System activity file magic header (unused here).
1449 * @file_hdr System activity file standard header (unused here).
1450 * @act Array of activities (unused here).
1451 * @id_seq Activity sequence (unused here).
1452 * @file_actlst List of (known or unknown) activities in file (unused here).
1453 ***************************************************************************
1455 __printf_funct_t print_pcp_header(void *parm, int action, char *dfile, char *my_tz,
1456 struct file_magic *file_magic,
1457 struct file_header *file_hdr,
1458 struct activity *act[], unsigned int id_seq[],
1459 struct file_activity *file_actlst)
1463 unsigned long long utc_sec = file_hdr->sa_ust_time;
1465 if (action & F_BEGIN) {
1466 /* Create new PCP context */
1467 pmiStart(dfile, FALSE);
1470 pmiSetTimezone(file_hdr->sa_tzname);
1473 pmiSetHostname(file_hdr->sa_nodename);
1475 /* Save number of CPU in PCP archive */
1476 pmiAddMetric("hinv.ncpu",
1477 pmiID(60, 0, 32), PM_TYPE_U32, PM_INDOM_NULL,
1478 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1479 snprintf(buf, sizeof(buf), "%u",
1480 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
1481 pmiPutValue("hinv.ncpu", NULL, buf);
1483 /* Save uname(2) information */
1484 pmiAddMetric("kernel.uname.release",
1485 pmiID(60, 12, 0), PM_TYPE_STRING, PM_INDOM_NULL,
1486 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1487 pmiPutValue("kernel.uname.release", NULL, file_hdr->sa_release);
1488 pmiAddMetric("kernel.uname.sysname",
1489 pmiID(60, 12, 2), PM_TYPE_STRING, PM_INDOM_NULL,
1490 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1491 pmiPutValue("kernel.uname.sysname", NULL, file_hdr->sa_sysname);
1492 pmiAddMetric("kernel.uname.machine",
1493 pmiID(60, 12, 3), PM_TYPE_STRING, PM_INDOM_NULL,
1494 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1495 pmiPutValue("kernel.uname.machine", NULL, file_hdr->sa_machine);
1496 pmiAddMetric("kernel.uname.nodename",
1497 pmiID(60, 12, 4), PM_TYPE_STRING, PM_INDOM_NULL,
1498 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1499 pmiPutValue("kernel.uname.nodename", NULL, file_hdr->sa_nodename);
1502 if (action & F_END) {
1503 if (action & F_BEGIN) {
1506 if ((rc = pmiWrite(utc_sec, 0)) < 0) {
1507 fprintf(stderr, "PCP: pmiWrite: %s\n", pmiErrStr(rc));
1517 ***************************************************************************
1518 * Count the number of new network interfaces in current sample. If a new
1519 * interface is found then add it to the linked list starting at
1523 * @a Activity structure with statistics.
1524 * @curr Index in array for current sample statistics.
1527 * Number of new interfaces identified in current sample that were not
1528 * previously in the list.
1529 ***************************************************************************
1531 __nr_t count_new_net_dev(struct activity *a, int curr)
1534 struct stats_net_dev *sndc;
1536 for (i = 0; i < a->nr[curr]; i++) {
1537 sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
1539 nr += add_list_item(&(a->item_list), sndc->interface, MAX_IFACE_LEN);
1546 ***************************************************************************
1547 * Count the number of new network interfaces in current sample. If a new
1548 * interface is found then add it to the linked list starting at
1552 * @a Activity structure with statistics.
1553 * @curr Index in array for current sample statistics.
1556 * Number of new interfaces identified in current sample that were not
1557 * previously in the list.
1558 ***************************************************************************
1560 __nr_t count_new_net_edev(struct activity *a, int curr)
1563 struct stats_net_edev *snedc;
1565 for (i = 0; i < a->nr[curr]; i++) {
1566 snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
1568 nr += add_list_item(&(a->item_list), snedc->interface, MAX_IFACE_LEN);
1575 ***************************************************************************
1576 * Count the number of new filesystems in current sample. If a new
1577 * filesystem is found then add it to the linked list starting at
1581 * @a Activity structure with statistics.
1582 * @curr Index in array for current sample statistics.
1585 * Number of new filesystems identified in current sample that were not
1586 * previously in the list.
1587 ***************************************************************************
1589 __nr_t count_new_filesystem(struct activity *a, int curr)
1592 struct stats_filesystem *sfc;
1594 for (i = 0; i < a->nr[curr]; i++) {
1595 sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
1597 nr += add_list_item(&(a->item_list),
1598 get_fs_name_to_display(a, flags, sfc),
1606 ***************************************************************************
1607 * Count the number of new fchosts in current sample. If a new
1608 * fchost is found then add it to the linked list starting at
1612 * @a Activity structure with statistics.
1613 * @curr Index in array for current sample statistics.
1616 * Number of new fchosts identified in current sample that were not
1617 * previously in the list.
1618 ***************************************************************************
1620 __nr_t count_new_fchost(struct activity *a, int curr)
1623 struct stats_fchost *sfcc;
1625 for (i = 0; i < a->nr[curr]; i++) {
1626 sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
1628 nr += add_list_item(&(a->item_list), sfcc->fchost_name, MAX_FCH_LEN);
1635 ***************************************************************************
1636 * Count the number of new block devices in current sample. If a new
1637 * block device is found then add it to the linked list starting at
1641 * @a Activity structure with statistics.
1642 * @curr Index in array for current sample statistics.
1645 * Number of new block devices identified in current sample that were not
1646 * previously in the list.
1647 ***************************************************************************
1649 __nr_t count_new_disk(struct activity *a, int curr)
1652 struct stats_disk *sdc;
1654 for (i = 0; i < a->nr[curr]; i++) {
1655 sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
1657 nr += add_list_item(&(a->item_list),
1658 get_device_name(sdc->major, sdc->minor, sdc->wwn, sdc->part_nr,
1659 DISPLAY_PRETTY(flags), DISPLAY_PERSIST_NAME_S(flags),
1660 USE_STABLE_ID(flags), NULL),
1668 ***************************************************************************
1669 * Count the number of interrupts in current sample. Add each interrupt name
1670 * to the linked list starting at @a->item_list.
1673 * @a Activity structure with statistics.
1674 * @curr Index in array for current sample statistics.
1677 * Number of interrupts added to the list.
1678 ***************************************************************************
1680 __nr_t count_new_int(struct activity *a, int curr)
1683 struct stats_irq *stc_cpuall_irq;
1687 * If a list already exists, do nothing. This means that a list has been
1688 * explicitly entered on the command line using option "--int=", or that
1689 * the list has already been created here (remember that the number of
1690 * interrupts cannot change in file: @nr2, the second matrix dimension,
1695 for (i = 0; i < a->nr2; i++) {
1696 stc_cpuall_irq = (struct stats_irq *) ((char *) a->buf[curr] + i * a->msize);
1698 nr += add_list_item(&(a->item_list), stc_cpuall_irq->irq_name, MAX_SA_IRQ_LEN);
1705 * **************************************************************************
1706 * Count the number of new batteries in current sample. If a new
1707 * battery is found then add it to the linked list starting at
1709 * Mainly useful to create a list of battery names (BATx) that will be used
1710 * as instance names for sadf PCP output format.
1713 * @a Activity structure with statistics.
1714 * @curr Index in array for current sample statistics.
1717 * Number of new batteries identified in current sample that were not
1718 * previously in the list.
1719 ***************************************************************************
1721 __nr_t count_new_bat(struct activity *a, int curr)
1724 struct stats_pwr_bat *spbc;
1727 for (i = 0; i < a->nr[curr]; i++) {
1728 spbc = (struct stats_pwr_bat *) ((char *) a->buf[curr] + i * a->msize);
1730 snprintf(bat_name, sizeof(bat_name), "BAT%d", (int) spbc->bat_id);
1731 nr += add_list_item(&(a->item_list), bat_name, sizeof(bat_name));
1738 ***************************************************************************
1739 * Init custom color palette used to draw graphs (sadf -g).
1740 ***************************************************************************
1742 void init_custom_color_palette()
1748 /* Read S_COLORS_PALETTE environment variable */
1749 if ((e = __getenv(ENV_COLORS_PALETTE)) == NULL)
1750 /* Environment variable not set */
1753 for (p = strtok(e, ":"); p; p =strtok(NULL, ":")) {
1756 if ((len > 8) || (len < 3) || (*(p + 1) != '=') ||
1757 (strspn(p + 2, "0123456789ABCDEFabcdef") != (len - 2)))
1758 /* Ignore malformed codes */
1761 sscanf(p + 2, "%x", &val);
1763 if ((*p >= '0') && (*p <= '9')) {
1764 svg_colors[SVG_CUSTOM_COL_PALETTE][*p & 0xf] = val;
1767 else if (((*p >= 'A') && (*p <= 'F')) ||
1768 ((*p >= 'a') && (*p <= 'f'))) {
1769 svg_colors[SVG_CUSTOM_COL_PALETTE][9 + (*p & 0xf)] = val;
1775 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_GRID_IDX] = val;
1778 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_HEADER_IDX] = val;
1781 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_INFO_IDX] = val;
1784 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_BCKGRD_IDX] = val;
1787 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_DEFAULT_IDX] = val;
1790 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_TITLE_IDX] = val;
1793 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_ERROR_IDX] = val;
1796 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_AXIS_IDX] = val;