2 * sadf_misc.c: Functions used by sadf to display special records
3 * (C) 2011-2022 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 char *tzname[2];
44 extern uint64_t flags;
48 extern unsigned int svg_colors[][SVG_COL_PALETTE_SIZE];
51 ***************************************************************************
52 * Flush data to PCP archive.
55 * @record_hdr Record header for current sample.
56 * @flags Flags for common options.
57 ***************************************************************************
59 void pcp_write_data(struct record_header *record_hdr, unsigned int flags)
64 time_t t = record_hdr->ust_time;
65 unsigned long long utc_sec = record_hdr->ust_time;
66 static long long delta_utc = LONG_MAX;
68 if (!PRINT_LOCAL_TIME(flags)) {
69 if (delta_utc == LONG_MAX) {
70 /* Convert a time_t value from local time to UTC */
71 if (gmtime_r(&t, &lrectime)) {
72 utc_sec = mktime(&lrectime);
73 delta_utc = utc_sec - record_hdr->ust_time;
78 * Once pmiWrite() has been called (after the first stats sample),
79 * subsequent mktime() calls will not give the same result with
80 * the same input data. So compute a time shift that will be used
81 * for the next samples.
82 * We should (really) be careful if pmiWrite() was to be used sooner
83 * than for the first stats sample (e.g. if we want to save a
84 * LINUX RESTART record heading the file).
90 /* Write data to PCP archive */
91 if ((rc = pmiWrite(utc_sec, 0)) < 0) {
92 fprintf(stderr, "PCP: pmiWrite: %s\n", pmiErrStr(rc));
99 ***************************************************************************
100 * Display restart messages (database and ppc formats).
103 * @cur_date Date string of current restart message.
104 * @cur_time Time string of current restart message.
105 * @utc True if @cur_time is expressed in UTC.
106 * @sep Character used as separator.
107 * @file_hdr System activity file standard header.
108 ***************************************************************************
110 void print_dbppc_restart(char *cur_date, char *cur_time, int utc, char sep,
111 struct file_header *file_hdr)
113 printf("%s%c-1%c", file_hdr->sa_nodename, sep, sep);
114 if (strlen(cur_date)) {
115 printf("%s ", cur_date);
117 printf("%s", cur_time);
118 if (strlen(cur_date) && utc) {
121 printf("%cLINUX-RESTART\t(%d CPU)\n",
122 sep, file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
126 ***************************************************************************
127 * Display restart messages (ppc format).
130 * @tab Number of tabulations (unused here).
131 * @action Action expected from current function.
132 * @cur_date Date string of current restart message.
133 * @cur_time Time string of current restart message.
134 * @utc True if @cur_time is expressed in UTC.
135 * @file_hdr System activity file standard header.
136 * @record_hdr Current record header (unused here).
137 ***************************************************************************
139 __printf_funct_t print_db_restart(int *tab, int action, char *cur_date,
140 char *cur_time, int utc, struct file_header *file_hdr,
141 struct record_header *record_hdr)
143 /* Actions F_BEGIN and F_END ignored */
144 if (action == F_MAIN) {
145 print_dbppc_restart(cur_date, cur_time, utc, ';', file_hdr);
150 ***************************************************************************
151 * Display restart messages (database format).
154 * @tab Number of tabulations (unused here).
155 * @action Action expected from current function.
156 * @cur_date Date string of current restart message.
157 * @cur_time Time string of current restart message.
158 * @utc True if @cur_time is expressed in UTC.
159 * @file_hdr System activity file standard header.
160 * @record_hdr Current record header (unused here).
161 ***************************************************************************
163 __printf_funct_t print_ppc_restart(int *tab, int action, char *cur_date,
164 char *cur_time, int utc, struct file_header *file_hdr,
165 struct record_header *record_hdr)
167 /* Actions F_BEGIN and F_END ignored */
168 if (action == F_MAIN) {
169 print_dbppc_restart(cur_date, cur_time, utc, '\t', file_hdr);
174 ***************************************************************************
175 * Display restart messages (XML format).
178 * @tab Number of tabulations.
179 * @action Action expected from current function.
180 * @cur_date Date string of current restart message.
181 * @cur_time Time string of current restart message.
182 * @utc True if @cur_time is expressed in UTC.
183 * @file_hdr System activity file standard header.
184 * @record_hdr Current record header (unused here).
187 * @tab Number of tabulations.
188 ***************************************************************************
190 __printf_funct_t print_xml_restart(int *tab, int action, char *cur_date,
191 char *cur_time, int utc, struct file_header *file_hdr,
192 struct record_header *record_hdr)
194 if (action & F_BEGIN) {
195 xprintf((*tab)++, "<restarts>");
197 if (action & F_MAIN) {
198 xprintf(*tab, "<boot date=\"%s\" time=\"%s\" utc=\"%d\" cpu_count=\"%d\"/>",
199 cur_date, cur_time, utc ? 1 : 0,
200 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
202 if (action & F_END) {
203 xprintf(--(*tab), "</restarts>");
208 ***************************************************************************
209 * Display restart messages (JSON format).
212 * @tab Number of tabulations.
213 * @action Action expected from current function.
214 * @cur_date Date string of current restart message.
215 * @cur_time Time string of current restart message.
216 * @utc True if @cur_time is expressed in UTC.
217 * @file_hdr System activity file standard header.
218 * @record_hdr Current record header (unused here).
221 * @tab Number of tabulations.
222 ***************************************************************************
224 __printf_funct_t print_json_restart(int *tab, int action, char *cur_date,
225 char *cur_time, int utc, struct file_header *file_hdr,
226 struct record_header *record_hdr)
228 static int sep = FALSE;
230 if (action & F_BEGIN) {
232 xprintf((*tab)++, "\"restarts\": [");
234 if (action & F_MAIN) {
238 xprintf((*tab)++, "{");
239 xprintf(*tab, "\"boot\": {\"date\": \"%s\", \"time\": \"%s\", \"utc\": %d, \"cpu_count\": %d}",
240 cur_date, cur_time, utc ? 1 : 0,
241 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
242 xprintf0(--(*tab), "}");
245 if (action & F_END) {
250 xprintf0(--(*tab), "]");
255 ***************************************************************************
256 * Display restart messages (raw format).
259 * @tab Number of tabulations (unused here).
260 * @action Action expected from current function.
261 * @cur_date Date string of current restart message.
262 * @cur_time Time string of current restart message.
263 * @utc True if @cur_time is expressed in UTC.
264 * @file_hdr System activity file standard header.
265 * @record_hdr Current record header (unused here).
266 ***************************************************************************
268 __printf_funct_t print_raw_restart(int *tab, int action, char *cur_date,
269 char *cur_time, int utc, struct file_header *file_hdr,
270 struct record_header *record_hdr)
272 /* Actions F_BEGIN and F_END ignored */
273 if (action == F_MAIN) {
274 printf("%s", cur_time);
275 if (strlen(cur_date) && utc) {
278 printf("; LINUX-RESTART (%d CPU)\n",
279 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
284 ***************************************************************************
285 * Display restart messages (PCP format).
288 * @tab Number of tabulations (unused here).
289 * @action Action expected from current function.
290 * @cur_date Date string of current restart message (unused here).
291 * @cur_time Time string of current restart message (unused here).
292 * @utc True if @cur_time is expressed in UTC (unused here).
293 * @file_hdr System activity file standard header.
294 * @record_hdr Current record header.
295 ***************************************************************************
297 __printf_funct_t print_pcp_restart(int *tab, int action, char *cur_date, char *cur_time,
298 int utc, struct file_header *file_hdr,
299 struct record_header *record_hdr)
302 static int def_metrics = FALSE;
305 if (action & F_BEGIN) {
307 pmiAddMetric("system.restart.count",
308 PM_IN_NULL, PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_DISCRETE,
309 pmiUnits(0, 0, 1, 0, 0, PM_COUNT_ONE));
311 pmiAddMetric("system.restart.ncpu",
312 PM_IN_NULL, PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_DISCRETE,
313 pmiUnits(0, 0, 1, 0, 0, PM_COUNT_ONE));
318 if (action & F_MAIN) {
319 pmiPutValue("system.restart.count", NULL, "1");
321 snprintf(buf, sizeof(buf), "%u",
322 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
323 pmiPutValue("system.restart.ncpu", NULL, buf);
325 /* Write data to PCP archive */
326 pcp_write_data(record_hdr, flags);
328 #endif /* HAVE_PCP */
332 ***************************************************************************
333 * Display comments (database and ppc formats).
336 * @cur_date Date string of current restart message.
337 * @cur_time Time string of current restart message.
338 * @utc True if @cur_time is expressed in UTC.
339 * @comment Comment to display.
340 * @sep Character used as separator.
341 * @file_hdr System activity file standard header.
342 ***************************************************************************
344 void print_dbppc_comment(char *cur_date, char *cur_time, int utc,
345 char *comment, char sep, struct file_header *file_hdr)
347 printf("%s%c-1%c", file_hdr->sa_nodename, sep, sep);
348 if (strlen(cur_date)) {
349 printf("%s ", cur_date);
351 printf("%s", cur_time);
352 if (strlen(cur_date) && utc) {
355 printf("%cCOM %s\n", sep, comment);
359 ***************************************************************************
360 * Display comments (database format).
363 * @tab Number of tabulations (unused here).
364 * @action Action expected from current function.
365 * @cur_date Date string of current restart message.
366 * @cur_time Time string of current restart message.
367 * @utc True if @cur_time is expressed in UTC.
368 * @comment Comment to display.
369 * @file_hdr System activity file standard header.
370 * @record_hdr Current record header (unused here).
371 ***************************************************************************
373 __printf_funct_t print_db_comment(int *tab, int action, char *cur_date, char *cur_time,
374 int utc, char *comment, struct file_header *file_hdr,
375 struct record_header *record_hdr)
377 /* Actions F_BEGIN and F_END ignored */
378 if (action & F_MAIN) {
379 print_dbppc_comment(cur_date, cur_time, utc, comment,
385 ***************************************************************************
386 * Display comments (ppc format).
389 * @tab Number of tabulations (unused here).
390 * @action Action expected from current function.
391 * @cur_date Date string of current restart message.
392 * @cur_time Time string of current restart message.
393 * @utc True if @cur_time is expressed in UTC.
394 * @comment Comment to display.
395 * @file_hdr System activity file standard header.
396 * @record_hdr Current record header (unused here).
397 ***************************************************************************
399 __printf_funct_t print_ppc_comment(int *tab, int action, char *cur_date, char *cur_time,
400 int utc, char *comment, struct file_header *file_hdr,
401 struct record_header *record_hdr)
403 /* Actions F_BEGIN and F_END ignored */
404 if (action & F_MAIN) {
405 print_dbppc_comment(cur_date, cur_time, utc, comment,
411 ***************************************************************************
412 * Display comments (XML format).
415 * @tab Number of tabulations.
416 * @action Action expected from current function.
417 * @cur_date Date string of current comment.
418 * @cur_time Time string of current comment.
419 * @utc True if @cur_time is expressed in UTC.
420 * @comment Comment to display.
421 * @file_hdr System activity file standard header (unused here).
422 * @record_hdr Current record header (unused here).
425 * @tab Number of tabulations.
426 ***************************************************************************
428 __printf_funct_t print_xml_comment(int *tab, int action, char *cur_date, char *cur_time,
429 int utc, char *comment, struct file_header *file_hdr,
430 struct record_header *record_hdr)
432 if (action & F_BEGIN) {
433 xprintf((*tab)++, "<comments>");
435 if (action & F_MAIN) {
436 xprintf(*tab, "<comment date=\"%s\" time=\"%s\" utc=\"%d\" com=\"%s\"/>",
437 cur_date, cur_time, utc ? 1 : 0, comment);
439 if (action & F_END) {
440 xprintf(--(*tab), "</comments>");
445 ***************************************************************************
446 * Display comments (JSON format).
449 * @tab Number of tabulations.
450 * @action Action expected from current function.
451 * @cur_date Date string of current comment.
452 * @cur_time Time string of current comment.
453 * @utc True if @cur_time is expressed in UTC.
454 * @comment Comment to display.
455 * @file_hdr System activity file standard header (unused here).
456 * @record_hdr Current record header (unused here).
459 * @tab Number of tabulations.
460 ***************************************************************************
462 __printf_funct_t print_json_comment(int *tab, int action, char *cur_date, char *cur_time,
463 int utc, char *comment, struct file_header *file_hdr,
464 struct record_header *record_hdr)
466 static int sep = FALSE;
468 if (action & F_BEGIN) {
470 xprintf((*tab)++, "\"comments\": [");
472 if (action & F_MAIN) {
476 xprintf((*tab)++, "{");
478 "\"comment\": {\"date\": \"%s\", \"time\": \"%s\", "
479 "\"utc\": %d, \"com\": \"%s\"}",
480 cur_date, cur_time, utc ? 1 : 0, comment);
481 xprintf0(--(*tab), "}");
484 if (action & F_END) {
489 xprintf0(--(*tab), "]");
494 ***************************************************************************
495 * Display comments (raw format).
498 * @tab Number of tabulations (unused here).
499 * @action Action expected from current function.
500 * @cur_date Date string of current restart message.
501 * @cur_time Time string of current restart message.
502 * @utc True if @cur_time is expressed in UTC.
503 * @comment Comment to display.
504 * @file_hdr System activity file standard header (unused here).
505 * @record_hdr Current record header (unused here).
506 ***************************************************************************
508 __printf_funct_t print_raw_comment(int *tab, int action, char *cur_date, char *cur_time,
509 int utc, char *comment, struct file_header *file_hdr,
510 struct record_header *record_hdr)
512 /* Actions F_BEGIN and F_END ignored */
513 if (action & F_MAIN) {
514 printf("%s", cur_time);
515 if (strlen(cur_date) && utc) {
518 printf("; COM %s\n", comment);
523 ***************************************************************************
524 * Display comments (PCP format).
527 * @tab Number of tabulations (unused here).
528 * @action Action expected from current function.
529 * @cur_date Date string of current restart message (unused here).
530 * @cur_time Time string of current restart message (unused here).
531 * @utc True if @cur_time is expressed in UTC (unused here).
532 * @comment Comment to display.
533 * @file_hdr System activity file standard header (unused here).
534 * @record_hdr Current record header.
535 ***************************************************************************
537 __printf_funct_t print_pcp_comment(int *tab, int action, char *cur_date, char *cur_time,
538 int utc, char *comment, struct file_header *file_hdr,
539 struct record_header *record_hdr)
542 static int def_metrics = FALSE;
544 if (action & F_BEGIN) {
546 pmiAddMetric("system.comment.value",
547 PM_IN_NULL, PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_DISCRETE,
548 pmiUnits(0, 0, 0, 0, 0, 0));
553 if (action & F_MAIN) {
554 pmiPutValue("system.comment.value", NULL, comment);
556 /* Write data to PCP archive */
557 pcp_write_data(record_hdr, flags);
559 #endif /* HAVE_PCP */
563 ***************************************************************************
564 * Display the "statistics" part of the report (XML format).
567 * @tab Number of tabulations.
568 * @action Action expected from current function.
569 * @act Array of activities (unused here).
570 * @id_seq Activity sequence (unused here).
573 * @tab Number of tabulations.
574 ***************************************************************************
576 __printf_funct_t print_xml_statistics(int *tab, int action, struct activity *act[],
577 unsigned int id_seq[])
579 if (action & F_BEGIN) {
580 xprintf((*tab)++, "<statistics>");
582 if (action & F_END) {
583 xprintf(--(*tab), "</statistics>");
588 ***************************************************************************
589 * Display the "statistics" part of the report (JSON format).
592 * @tab Number of tabulations.
593 * @action Action expected from current function.
594 * @act Array of activities (unused here).
595 * @id_seq Activity sequence (unused here).
598 * @tab Number of tabulations.
599 ***************************************************************************
601 __printf_funct_t print_json_statistics(int *tab, int action, struct activity *act[],
602 unsigned int id_seq[])
604 static int sep = FALSE;
606 if (action & F_BEGIN) {
608 xprintf((*tab)++, "\"statistics\": [");
610 if (action & F_MAIN) {
612 xprintf(--(*tab), "},");
614 xprintf((*tab)++, "{");
617 if (action & F_END) {
619 xprintf(--(*tab), "}");
622 xprintf0(--(*tab), "]");
627 ***************************************************************************
628 * Display the "statistics" part of the report (PCP format).
631 * @tab Number of tabulations (unused here).
632 * @action Action expected from current function.
633 * @act Array of activities.
634 * @id_seq Activity sequence.
635 ***************************************************************************
637 __printf_funct_t print_pcp_statistics(int *tab, int action, struct activity *act[],
638 unsigned int id_seq[])
643 if (action & F_BEGIN) {
644 for (i = 0; i < NR_ACT; i++) {
646 continue; /* Activity not in file */
648 p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND);
649 if (!IS_SELECTED(act[p]->options))
650 continue; /* Activity not selected */
652 switch (act[p]->id) {
657 pcp_def_cpu_metrics(act[p]);
661 pcp_def_pcsw_metrics();
665 pcp_def_irq_metrics(act[p]);
666 pcp_def_cpu_metrics(act[p]); /* For per_CPU int metrics */
670 pcp_def_swap_metrics();
674 pcp_def_paging_metrics();
678 pcp_def_io_metrics();
682 pcp_def_memory_metrics(act[p]);
686 pcp_def_ktables_metrics();
690 pcp_def_queue_metrics();
694 pcp_def_serial_metrics(act[p]);
698 pcp_def_disk_metrics(act[p]);
703 pcp_def_net_dev_metrics(act[p]);
707 pcp_def_net_nfs_metrics();
711 pcp_def_net_nfsd_metrics();
715 pcp_def_net_sock_metrics();
719 pcp_def_net_ip_metrics();
723 pcp_def_net_eip_metrics();
727 pcp_def_net_icmp_metrics();
731 pcp_def_net_eicmp_metrics();
735 pcp_def_net_tcp_metrics();
739 pcp_def_net_etcp_metrics();
743 pcp_def_net_udp_metrics();
747 pcp_def_net_sock6_metrics();
751 pcp_def_net_ip6_metrics();
755 pcp_def_net_eip6_metrics();
759 pcp_def_net_icmp6_metrics();
763 pcp_def_net_eicmp6_metrics();
767 pcp_def_net_udp6_metrics();
771 pcp_def_huge_metrics();
775 pcp_def_pwr_fan_metrics(act[p]);
779 pcp_def_pwr_temp_metrics(act[p]);
783 pcp_def_pwr_in_metrics(act[p]);
787 pcp_def_pwr_usb_metrics(act[p]);
791 pcp_def_filesystem_metrics(act[p]);
795 pcp_def_fchost_metrics(act[p]);
801 pcp_def_psi_metrics(act[p]);
806 #endif /* HAVE_PCP */
810 ***************************************************************************
811 * Display the "timestamp" part of the report (db and ppc format).
814 * @fmt Output format (F_DB_OUTPUT or F_PPC_OUTPUT).
815 * @file_hdr System activity file standard header.
816 * @cur_date Date string of current record.
817 * @cur_time Time string of current record.
818 * @utc True if @cur_time is expressed in UTC.
819 * @itv Interval of time with preceding record.
822 * Pointer on the "timestamp" string.
823 ***************************************************************************
825 char *print_dbppc_timestamp(int fmt, struct file_header *file_hdr, char *cur_date,
826 char *cur_time, int utc, unsigned long long itv)
828 int isdb = (fmt == F_DB_OUTPUT);
829 static char pre[512];
830 char temp1[128], temp2[256];
832 /* This substring appears on every output line, preformat it here */
833 snprintf(temp1, sizeof(temp1), "%s%s%lld%s",
834 file_hdr->sa_nodename, seps[isdb], itv, seps[isdb]);
835 if (strlen(cur_date)) {
836 snprintf(temp2, sizeof(temp2), "%s%s ", temp1, cur_date);
839 strcpy(temp2, temp1);
841 snprintf(pre, sizeof(pre), "%s%s%s", temp2, cur_time,
842 strlen(cur_date) && utc ? " UTC" : "");
843 pre[sizeof(pre) - 1] = '\0';
845 if (DISPLAY_HORIZONTALLY(flags)) {
853 ***************************************************************************
854 * Display the "timestamp" part of the report (ppc format).
857 * @parm Pointer on specific parameters (unused here).
858 * @action Action expected from current function.
859 * @cur_date Date string of current record.
860 * @cur_time Time string of current record.
861 * @itv Interval of time with preceding record.
862 * @record_hdr Record header for current sample (unused here).
863 * @file_hdr System activity file standard header.
864 * @flags Flags for common options.
867 * Pointer on the "timestamp" string.
868 ***************************************************************************
870 __tm_funct_t print_ppc_timestamp(void *parm, int action, char *cur_date,
871 char *cur_time, unsigned long long itv,
872 struct record_header *record_hdr,
873 struct file_header *file_hdr, unsigned int flags)
875 int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
877 if (action & F_BEGIN) {
878 return print_dbppc_timestamp(F_PPC_OUTPUT, file_hdr, cur_date, cur_time, utc, itv);
885 ***************************************************************************
886 * Display the "timestamp" part of the report (db format).
889 * @parm Pointer on specific parameters (unused here).
890 * @action Action expected from current function.
891 * @cur_date Date string of current record.
892 * @cur_time Time string of current record.
893 * @itv Interval of time with preceding record.
894 * @record_hdr Record header for current sample (unused here).
895 * @file_hdr System activity file standard header.
896 * @flags Flags for common options.
899 * Pointer on the "timestamp" string.
900 ***************************************************************************
902 __tm_funct_t print_db_timestamp(void *parm, int action, char *cur_date,
903 char *cur_time, unsigned long long itv,
904 struct record_header *record_hdr,
905 struct file_header *file_hdr, unsigned int flags)
907 int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
909 if (action & F_BEGIN) {
910 return print_dbppc_timestamp(F_DB_OUTPUT, file_hdr, cur_date, cur_time, utc, itv);
912 if (action & F_END) {
913 if (DISPLAY_HORIZONTALLY(flags)) {
922 ***************************************************************************
923 * Display the "timestamp" part of the report (XML format).
926 * @parm Specific parameter. Here: number of tabulations.
927 * @action Action expected from current function.
928 * @cur_date Date string of current comment.
929 * @cur_time Time string of current comment.
930 * @itv Interval of time with preceding record.
931 * @record_hdr Record header for current sample (unused here).
932 * @file_hdr System activity file standard header (unused here).
933 * @flags Flags for common options.
934 ***************************************************************************
936 __tm_funct_t print_xml_timestamp(void *parm, int action, char *cur_date,
937 char *cur_time, unsigned long long itv,
938 struct record_header *record_hdr,
939 struct file_header *file_hdr, unsigned int flags)
941 int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
942 int *tab = (int *) parm;
944 if (action & F_BEGIN) {
945 xprintf((*tab)++, "<timestamp date=\"%s\" time=\"%s\" utc=\"%d\" interval=\"%llu\">",
946 cur_date, cur_time, utc ? 1 : 0, itv);
948 if (action & F_END) {
949 xprintf(--(*tab), "</timestamp>");
956 ***************************************************************************
957 * Display the "timestamp" part of the report (JSON format).
960 * @parm Specific parameter. Here: number of tabulations.
961 * @action Action expected from current function.
962 * @cur_date Date string of current comment.
963 * @cur_time Time string of current comment.
964 * @itv Interval of time with preceding record.
965 * @record_hdr Record header for current sample (unused here).
966 * @file_hdr System activity file standard header (unused here).
967 * @flags Flags for common options.
968 ***************************************************************************
970 __tm_funct_t print_json_timestamp(void *parm, int action, char *cur_date,
971 char *cur_time, unsigned long long itv,
972 struct record_header *record_hdr,
973 struct file_header *file_hdr, unsigned int flags)
975 int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
976 int *tab = (int *) parm;
978 if (action & F_BEGIN) {
980 "\"timestamp\": {\"date\": \"%s\", \"time\": \"%s\", "
981 "\"utc\": %d, \"interval\": %llu}",
982 cur_date, cur_time, utc ? 1 : 0, itv);
984 if (action & F_MAIN) {
987 if (action & F_END) {
995 ***************************************************************************
996 * Display the "timestamp" part of the report (raw format).
999 * @parm Pointer on specific parameters (unused here).
1000 * @action Action expected from current function.
1001 * @cur_date Date string of current record.
1002 * @cur_time Time string of current record.
1003 * @itv Interval of time with preceding record (unused here).
1004 * @record_hdr Record header for current sample (unused here).
1005 * @file_hdr System activity file standard header (unused here).
1006 * @flags Flags for common options.
1009 * Pointer on the "timestamp" string.
1010 ***************************************************************************
1012 __tm_funct_t print_raw_timestamp(void *parm, int action, char *cur_date,
1013 char *cur_time, unsigned long long itv,
1014 struct record_header *record_hdr,
1015 struct file_header *file_hdr, unsigned int flags)
1017 int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
1018 static char pre[80];
1020 if (action & F_BEGIN) {
1021 snprintf(pre, sizeof(pre), "%s%s", cur_time, strlen(cur_date) && utc ? " UTC" : "");
1022 pre[sizeof(pre) - 1] = '\0';
1030 ***************************************************************************
1031 * Display the "timestamp" part of the report (PCP format).
1034 * @parm Pointer on specific parameters (unused here).
1035 * @action Action expected from current function.
1036 * @cur_date Date string of current record (unused here).
1037 * @cur_time Time string of current record (unused here).
1038 * @itv Interval of time with preceding record (unused here).
1039 * @record_hdr Record header for current sample.
1040 * @file_hdr System activity file standard header (unused here).
1041 * @flags Flags for common options.
1044 * Pointer on the "timestamp" string.
1045 ***************************************************************************
1047 __tm_funct_t print_pcp_timestamp(void *parm, int action, char *cur_date,
1048 char *cur_time, unsigned long long itv,
1049 struct record_header *record_hdr,
1050 struct file_header *file_hdr, unsigned int flags)
1052 if (action & F_END) {
1053 pcp_write_data(record_hdr, flags);
1060 ***************************************************************************
1061 * Display the header of the report (XML format).
1064 * @parm Specific parameter. Here: number of tabulations.
1065 * @action Action expected from current function.
1066 * @dfile Unused here (PCP archive file).
1067 * @file_magic System activity file magic header.
1068 * @file_hdr System activity file standard header.
1069 * @act Array of activities (unused here).
1070 * @id_seq Activity sequence (unused here).
1071 * @file_actlst List of (known or unknown) activities in file (unused here).
1074 * @parm Number of tabulations.
1075 ***************************************************************************
1077 __printf_funct_t print_xml_header(void *parm, int action, char *dfile,
1078 struct file_magic *file_magic,
1079 struct file_header *file_hdr,
1080 struct activity *act[], unsigned int id_seq[],
1081 struct file_activity *file_actlst)
1083 struct tm rectime, loc_t;
1084 time_t t = file_hdr->sa_ust_time;
1085 char cur_time[TIMESTAMP_LEN];
1086 int *tab = (int *) parm;
1088 if (action & F_BEGIN) {
1089 printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1090 printf("<!DOCTYPE sysstat PUBLIC \"DTD v%s sysstat //EN\"\n",
1092 printf("\"http://pagesperso-orange.fr/sebastien.godard/sysstat-%s.dtd\">\n",
1095 xprintf(*tab, "<sysstat\n"
1096 "xmlns=\"http://pagesperso-orange.fr/sebastien.godard/sysstat\"\n"
1097 "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
1098 "xsi:schemaLocation=\"http://pagesperso-orange.fr/sebastien.godard sysstat.xsd\">");
1100 xprintf(++(*tab), "<sysdata-version>%s</sysdata-version>",
1103 xprintf(*tab, "<host nodename=\"%s\">", file_hdr->sa_nodename);
1104 xprintf(++(*tab), "<sysname>%s</sysname>", file_hdr->sa_sysname);
1105 xprintf(*tab, "<release>%s</release>", file_hdr->sa_release);
1107 xprintf(*tab, "<machine>%s</machine>", file_hdr->sa_machine);
1108 xprintf(*tab, "<number-of-cpus>%d</number-of-cpus>",
1109 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
1111 /* Fill file timestmap structure (rectime) */
1112 get_file_timestamp_struct(flags, &rectime, file_hdr);
1113 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
1114 xprintf(*tab, "<file-date>%s</file-date>", cur_time);
1116 if (gmtime_r(&t, &loc_t) != NULL) {
1117 strftime(cur_time, sizeof(cur_time), "%T", &loc_t);
1118 xprintf(*tab, "<file-utc-time>%s</file-utc-time>", cur_time);
1121 xprintf(*tab, "<timezone>%s</timezone>", file_hdr->sa_tzname);
1123 if (action & F_END) {
1124 xprintf(--(*tab), "</host>");
1125 xprintf(--(*tab), "</sysstat>");
1130 ***************************************************************************
1131 * Display the header of the report (JSON format).
1134 * @parm Specific parameter. Here: number of tabulations.
1135 * @action Action expected from current function.
1136 * @dfile Unused here (PCP archive file).
1137 * @file_magic System activity file magic header.
1138 * @file_hdr System activity file standard header.
1139 * @act Array of activities (unused here).
1140 * @id_seq Activity sequence (unused here).
1141 * @file_actlst List of (known or unknown) activities in file (unused here).
1144 * @parm Number of tabulations.
1145 ***************************************************************************
1147 __printf_funct_t print_json_header(void *parm, int action, char *dfile,
1148 struct file_magic *file_magic,
1149 struct file_header *file_hdr,
1150 struct activity *act[], unsigned int id_seq[],
1151 struct file_activity *file_actlst)
1153 struct tm rectime, loc_t;
1154 time_t t = file_hdr->sa_ust_time;
1155 char cur_time[TIMESTAMP_LEN];
1156 int *tab = (int *) parm;
1158 if (action & F_BEGIN) {
1159 xprintf(*tab, "{\"sysstat\": {");
1161 xprintf(++(*tab), "\"hosts\": [");
1162 xprintf(++(*tab), "{");
1163 xprintf(++(*tab), "\"nodename\": \"%s\",", file_hdr->sa_nodename);
1164 xprintf(*tab, "\"sysname\": \"%s\",", file_hdr->sa_sysname);
1165 xprintf(*tab, "\"release\": \"%s\",", file_hdr->sa_release);
1167 xprintf(*tab, "\"machine\": \"%s\",", file_hdr->sa_machine);
1168 xprintf(*tab, "\"number-of-cpus\": %d,",
1169 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
1171 /* Fill file timestmap structure (rectime) */
1172 get_file_timestamp_struct(flags, &rectime, file_hdr);
1173 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
1174 xprintf(*tab, "\"file-date\": \"%s\",", cur_time);
1176 if (gmtime_r(&t, &loc_t) != NULL) {
1177 strftime(cur_time, sizeof(cur_time), "%T", &loc_t);
1178 xprintf(*tab, "\"file-utc-time\": \"%s\",", cur_time);
1181 xprintf0(*tab, "\"timezone\": \"%s\"", file_hdr->sa_tzname);
1183 if (action & F_END) {
1185 xprintf(--(*tab), "}");
1186 xprintf(--(*tab), "]");
1187 xprintf(--(*tab), "}}");
1192 ***************************************************************************
1193 * Display data file header.
1196 * @parm Specific parameter (unused here).
1197 * @action Action expected from current function.
1198 * @dfile Name of system activity data file (unused here).
1199 * @file_magic System activity file magic header.
1200 * @file_hdr System activity file standard header.
1201 * @act Array of activities.
1202 * @id_seq Activity sequence.
1203 * @file_actlst List of (known or unknown) activities in file.
1204 ***************************************************************************
1206 __printf_funct_t print_hdr_header(void *parm, int action, char *dfile,
1207 struct file_magic *file_magic,
1208 struct file_header *file_hdr,
1209 struct activity *act[], unsigned int id_seq[],
1210 struct file_activity *file_actlst)
1213 struct tm rectime, loc_t;
1214 time_t t = file_hdr->sa_ust_time;
1215 struct file_activity *fal;
1216 char cur_time[TIMESTAMP_LEN];
1218 /* Actions F_MAIN and F_END ignored */
1219 if (action & F_BEGIN) {
1220 printf(_("System activity data file: %s (%#x)\n"),
1221 dfile, file_magic->format_magic);
1223 display_sa_file_version(stdout, file_magic);
1225 if (file_magic->format_magic != FORMAT_MAGIC) {
1229 printf(_("Genuine sa datafile: %s (%x)\n"),
1230 file_magic->upgraded ? _("no") : _("yes"),
1231 file_magic->upgraded);
1233 printf(_("Host: "));
1234 print_gal_header(localtime_r(&t, &rectime),
1235 file_hdr->sa_sysname, file_hdr->sa_release,
1236 file_hdr->sa_nodename, file_hdr->sa_machine,
1237 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1,
1240 /* Fill file timestamp structure (rectime) */
1241 get_file_timestamp_struct(flags, &rectime, file_hdr);
1242 strftime(cur_time, sizeof(cur_time), "%Y-%m-%d", &rectime);
1243 printf(_("File date: %s\n"), cur_time);
1245 if (gmtime_r(&t, &loc_t) != NULL) {
1246 printf(_("File time: "));
1247 strftime(cur_time, sizeof(cur_time), "%T", &loc_t);
1248 printf("%s UTC (%lld)\n", cur_time, file_hdr->sa_ust_time);
1251 printf(_("Timezone: %s\n"), file_hdr->sa_tzname);
1253 /* File composition: file_header, file_activity, record_header */
1254 printf(_("File composition: (%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n"),
1255 file_magic->hdr_types_nr[0], file_magic->hdr_types_nr[1], file_magic->hdr_types_nr[2],
1256 file_hdr->act_types_nr[0], file_hdr->act_types_nr[1], file_hdr->act_types_nr[2],
1257 file_hdr->rec_types_nr[0], file_hdr->rec_types_nr[1], file_hdr->rec_types_nr[2]);
1259 printf(_("Size of a long int: %d\n"), file_hdr->sa_sizeof_long);
1260 printf("HZ = %lu\n", file_hdr->sa_hz);
1261 printf(_("Number of activities in file: %u\n"),
1262 file_hdr->sa_act_nr);
1263 printf(_("Extra structures available: %c\n"),
1264 file_hdr->extra_next ? 'Y' : 'N');
1266 printf(_("List of activities:\n"));
1268 for (i = 0; i < file_hdr->sa_act_nr; i++, fal++) {
1270 p = get_activity_position(act, fal->id, RESUME_IF_NOT_FOUND);
1272 printf("%02d: [%02x] ", fal->id, fal->magic);
1274 printf("%-20s", act[p]->name);
1277 printf("%-20s", _("Unknown activity"));
1279 printf(" %c:%4d", fal->has_nr ? 'Y' : 'N', fal->nr);
1281 printf("x%d", fal->nr2);
1283 printf("\t(%d,%d,%d)", fal->types_nr[0], fal->types_nr[1], fal->types_nr[2]);
1284 if ((p >= 0) && (act[p]->magic != fal->magic)) {
1285 printf(_(" \t[Unknown format]"));
1293 ***************************************************************************
1294 * Display the header of the report (SVG format).
1297 * @parm Specific parameters. Here: number of rows of views to display
1298 * or canvas height entered on the command line (@graph_nr), and
1299 * max number of views on a single row (@views_per_row).
1300 * @action Action expected from current function.
1301 * @dfile Name of system activity data file (unused here).
1302 * @file_magic System activity file magic header (unused here).
1303 * @file_hdr System activity file standard header.
1304 * @act Array of activities (unused here).
1305 * @id_seq Activity sequence (unused here).
1306 * @file_actlst List of (known or unknown) activities in file (unused here).
1307 ***************************************************************************
1309 __printf_funct_t print_svg_header(void *parm, int action, char *dfile,
1310 struct file_magic *file_magic,
1311 struct file_header *file_hdr,
1312 struct activity *act[], unsigned int id_seq[],
1313 struct file_activity *file_actlst)
1315 struct svg_hdr_parm *hdr_parm = (struct svg_hdr_parm *) parm;
1317 time_t t = file_hdr->sa_ust_time;
1318 unsigned int height = 0, ht = 0;
1321 if (action & F_BEGIN) {
1322 printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1323 printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ");
1324 printf("\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
1325 printf("<svg xmlns=\"http://www.w3.org/2000/svg\"");
1326 if (DISPLAY_TOC(flags)) {
1327 printf(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
1329 if (action & F_END) {
1334 if (action & F_MAIN) {
1335 if (SET_CANVAS_HEIGHT(flags)) {
1337 * Option "-O height=..." used: @graph_nr is
1338 * the SVG canvas height set on the command line.
1340 height = hdr_parm->graph_nr;
1343 height = SVG_H_YSIZE +
1344 SVG_C_YSIZE * (DISPLAY_TOC(flags) ? hdr_parm->nr_act_dispd : 0) +
1345 SVG_T_YSIZE * hdr_parm->graph_nr;
1348 /* Min canvas height is 100 (at least to display "No data") */
1351 printf(" width=\"%d\" height=\"%d\""
1352 " fill=\"black\" stroke=\"#%06x\" stroke-width=\"1\">\n",
1353 SVG_T_XSIZE * (hdr_parm->views_per_row), height,
1354 svg_colors[palette][SVG_COL_DEFAULT_IDX]);
1355 printf("<text x=\"0\" y=\"30\" text-anchor=\"start\" stroke=\"#%06x\">",
1356 svg_colors[palette][SVG_COL_HEADER_IDX]);
1357 print_gal_header(localtime_r(&t, &rectime),
1358 file_hdr->sa_sysname, file_hdr->sa_release,
1359 file_hdr->sa_nodename, file_hdr->sa_machine,
1360 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1,
1362 printf("</text>\n");
1363 if (DISPLAY_TOC(flags)) {
1364 for (i = 0; i < NR_ACT; i++) {
1366 continue; /* Activity not in file */
1368 p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND);
1369 if (!IS_SELECTED(act[p]->options) || !act[p]->g_nr)
1370 continue; /* Activity not selected or no graph available */
1372 printf("<a xlink:href=\"#g%d-0\" xlink:title=\"%s\">\n",
1373 act[p]->id, act[p]->name);
1374 printf("<text x=\"10\" y=\"%d\">%s</text></a>\n",
1375 SVG_H_YSIZE + ht, act[p]->desc);
1381 if (action & F_END) {
1382 if (!(action & F_BEGIN)) {
1383 if (!hdr_parm->graph_nr) {
1384 /* No views displayed */
1385 printf("<text x= \"0\" y=\"%d\" text-anchor=\"start\" stroke=\"#%06x\">",
1387 SVG_C_YSIZE * (DISPLAY_TOC(flags) ? hdr_parm->nr_act_dispd : 0),
1388 svg_colors[palette][SVG_COL_ERROR_IDX]);
1389 printf("No data!</text>\n");
1391 /* Give actual SVG height */
1392 printf("<!-- Actual canvas height: %d -->\n",
1394 SVG_C_YSIZE * (DISPLAY_TOC(flags) ? hdr_parm->nr_act_dispd : 0) +
1395 SVG_T_YSIZE * hdr_parm->graph_nr);
1402 ***************************************************************************
1403 * PCP header function.
1406 * @parm Specific parameter (unused here).
1407 * @action Action expected from current function.
1408 * @dfile Name of PCP archive file.
1409 * @file_magic System activity file magic header (unused here).
1410 * @file_hdr System activity file standard header (unused here).
1411 * @act Array of activities (unused here).
1412 * @id_seq Activity sequence (unused here).
1413 * @file_actlst List of (known or unknown) activities in file (unused here).
1414 ***************************************************************************
1416 __printf_funct_t print_pcp_header(void *parm, int action, char *dfile,
1417 struct file_magic *file_magic,
1418 struct file_header *file_hdr,
1419 struct activity *act[], unsigned int id_seq[],
1420 struct file_activity *file_actlst)
1425 time_t t = file_hdr->sa_ust_time;
1426 unsigned long long utc_sec = file_hdr->sa_ust_time;
1428 if (action & F_BEGIN) {
1429 /* Create new PCP context */
1430 pmiStart(dfile, FALSE);
1432 if (PRINT_LOCAL_TIME(flags)) {
1433 pmiSetTimezone(file_hdr->sa_tzname);
1436 pmiSetTimezone("UTC");
1440 pmiSetHostname(file_hdr->sa_nodename);
1442 /* Save number of CPU in PCP archive */
1443 pmiAddMetric("hinv.ncpu",
1444 pmiID(60, 0, 32), PM_TYPE_U32, PM_INDOM_NULL,
1445 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1446 snprintf(buf, sizeof(buf), "%u",
1447 file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1);
1448 pmiPutValue("hinv.ncpu", NULL, buf);
1450 /* Save uname(2) information */
1451 pmiAddMetric("kernel.uname.release",
1452 pmiID(60, 12, 0), PM_TYPE_STRING, PM_INDOM_NULL,
1453 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1454 pmiPutValue("kernel.uname.release", NULL, file_hdr->sa_release);
1455 pmiAddMetric("kernel.uname.sysname",
1456 pmiID(60, 12, 2), PM_TYPE_STRING, PM_INDOM_NULL,
1457 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1458 pmiPutValue("kernel.uname.sysname", NULL, file_hdr->sa_sysname);
1459 pmiAddMetric("kernel.uname.machine",
1460 pmiID(60, 12, 3), PM_TYPE_STRING, PM_INDOM_NULL,
1461 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1462 pmiPutValue("kernel.uname.machine", NULL, file_hdr->sa_machine);
1463 pmiAddMetric("kernel.uname.nodename",
1464 pmiID(60, 12, 4), PM_TYPE_STRING, PM_INDOM_NULL,
1465 PM_SEM_DISCRETE, pmiUnits(0, 0, 0, 0, 0, 0));
1466 pmiPutValue("kernel.uname.nodename", NULL, file_hdr->sa_nodename);
1469 if (action & F_END) {
1470 if (action & F_BEGIN) {
1471 /* Only the header data will be written to PCP archive */
1472 if (!PRINT_LOCAL_TIME(flags)) {
1473 /* Convert a time_t value from local time to UTC */
1474 if (gmtime_r(&t, &lrectime)) {
1475 utc_sec = mktime(&lrectime);
1478 pmiWrite(utc_sec, 0);
1486 ***************************************************************************
1487 * Count the number of new network interfaces in current sample. If a new
1488 * interface is found then add it to the linked list starting at
1492 * @a Activity structure with statistics.
1493 * @curr Index in array for current sample statistics.
1496 * Number of new interfaces identified in current sample that were not
1497 * previously in the list.
1498 ***************************************************************************
1500 __nr_t count_new_net_dev(struct activity *a, int curr)
1503 struct stats_net_dev *sndc;
1505 for (i = 0; i < a->nr[curr]; i++) {
1506 sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
1508 nr += add_list_item(&(a->item_list), sndc->interface, MAX_IFACE_LEN);
1515 ***************************************************************************
1516 * Count the number of new network interfaces in current sample. If a new
1517 * interface is found then add it to the linked list starting at
1521 * @a Activity structure with statistics.
1522 * @curr Index in array for current sample statistics.
1525 * Number of new interfaces identified in current sample that were not
1526 * previously in the list.
1527 ***************************************************************************
1529 __nr_t count_new_net_edev(struct activity *a, int curr)
1532 struct stats_net_edev *snedc;
1534 for (i = 0; i < a->nr[curr]; i++) {
1535 snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
1537 nr += add_list_item(&(a->item_list), snedc->interface, MAX_IFACE_LEN);
1544 ***************************************************************************
1545 * Count the number of new filesystems in current sample. If a new
1546 * filesystem is found then add it to the linked list starting at
1550 * @a Activity structure with statistics.
1551 * @curr Index in array for current sample statistics.
1554 * Number of new filesystems identified in current sample that were not
1555 * previously in the list.
1556 ***************************************************************************
1558 __nr_t count_new_filesystem(struct activity *a, int curr)
1561 struct stats_filesystem *sfc;
1563 for (i = 0; i < a->nr[curr]; i++) {
1564 sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
1566 nr += add_list_item(&(a->item_list),
1567 get_fs_name_to_display(a, flags, sfc),
1575 ***************************************************************************
1576 * Count the number of new fchosts in current sample. If a new
1577 * fchost 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 fchosts identified in current sample that were not
1586 * previously in the list.
1587 ***************************************************************************
1589 __nr_t count_new_fchost(struct activity *a, int curr)
1592 struct stats_fchost *sfcc;
1594 for (i = 0; i < a->nr[curr]; i++) {
1595 sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
1597 nr += add_list_item(&(a->item_list), sfcc->fchost_name, MAX_FCH_LEN);
1604 ***************************************************************************
1605 * Count the number of new block devices in current sample. If a new
1606 * block device is found then add it to the linked list starting at
1610 * @a Activity structure with statistics.
1611 * @curr Index in array for current sample statistics.
1614 * Number of new block devices identified in current sample that were not
1615 * previously in the list.
1616 ***************************************************************************
1618 __nr_t count_new_disk(struct activity *a, int curr)
1621 struct stats_disk *sdc;
1623 for (i = 0; i < a->nr[curr]; i++) {
1624 sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
1626 nr += add_list_item(&(a->item_list),
1627 get_device_name(sdc->major, sdc->minor, sdc->wwn, sdc->part_nr,
1628 DISPLAY_PRETTY(flags), DISPLAY_PERSIST_NAME_S(flags),
1629 USE_STABLE_ID(flags), NULL),
1637 ***************************************************************************
1638 * Count the number of interrupts in current sample. Add each interrupt name
1639 * to the linked list starting at @a->item_list.
1642 * @a Activity structure with statistics.
1643 * @curr Index in array for current sample statistics.
1646 * Number of interrupts added to the list.
1647 ***************************************************************************
1649 __nr_t count_new_int(struct activity *a, int curr)
1652 struct stats_irq *stc_cpuall_irq;
1656 * If a list already exists, do nothing. This means that a list has been
1657 * explicitly entered on the command line using option "--int=", or that
1658 * the list has already been created here (remember that the number of
1659 * interrupts cannot change in file: @nr2, the second matrix dimension,
1664 for (i = 0; i < a->nr2; i++) {
1665 stc_cpuall_irq = (struct stats_irq *) ((char *) a->buf[curr] + i * a->msize);
1667 nr += add_list_item(&(a->item_list), stc_cpuall_irq->irq_name, MAX_SA_IRQ_LEN);
1674 ***************************************************************************
1675 * Init custom color palette used to draw graphs (sadf -g).
1676 ***************************************************************************
1678 void init_custom_color_palette()
1684 /* Read S_COLORS_PALETTE environment variable */
1685 if ((e = __getenv(ENV_COLORS_PALETTE)) == NULL)
1686 /* Environment variable not set */
1689 for (p = strtok(e, ":"); p; p =strtok(NULL, ":")) {
1692 if ((len > 8) || (len < 3) || (*(p + 1) != '=') ||
1693 (strspn(p + 2, "0123456789ABCDEFabcdef") != (len - 2)))
1694 /* Ignore malformed codes */
1697 sscanf(p + 2, "%x", &val);
1699 if ((*p >= '0') && (*p <= '9')) {
1700 svg_colors[SVG_CUSTOM_COL_PALETTE][*p & 0xf] = val;
1703 else if (((*p >= 'A') && (*p <= 'F')) ||
1704 ((*p >= 'a') && (*p <= 'f'))) {
1705 svg_colors[SVG_CUSTOM_COL_PALETTE][9 + (*p & 0xf)] = val;
1711 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_GRID_IDX] = val;
1714 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_HEADER_IDX] = val;
1717 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_INFO_IDX] = val;
1720 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_BCKGRD_IDX] = val;
1723 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_DEFAULT_IDX] = val;
1726 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_TITLE_IDX] = val;
1729 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_ERROR_IDX] = val;
1732 svg_colors[SVG_CUSTOM_COL_PALETTE][SVG_COL_AXIS_IDX] = val;