366
366
* Display XML activity records
369
* @curr Index in array for current sample statistics.
370
* @tab Number of tabulations to print.
371
* @cpu_nr Number of processors.
369
* @curr Index in array for current sample statistics.
370
* @use_tm_start Set to TRUE if option -s has been used.
371
* @use_tm_end Set to TRUE if option -e has been used.
372
* @reset Set to TRUE if last_uptime should be reinitialized
373
* (used in next_slice() function).
374
* @tab Number of tabulations to print.
375
* @cpu_nr Number of processors.
378
* @cnt Set to 0 to indicate that no other lines of stats
379
* should be displayed.
382
* 1 if stats have been successfully displayed.
372
383
***************************************************************************
374
void write_xml_stats(int curr, int tab, __nr_t cpu_nr)
385
int write_xml_stats(int curr, int use_tm_start, int use_tm_end, int reset,
386
long *cnt, int tab, __nr_t cpu_nr)
377
389
unsigned long long dt, itv, g_itv;
378
390
char cur_time[XML_TIMESTAMP_LEN];
391
static int cross_day = FALSE;
380
393
/* Fill timestamp structure (rectime) for current record */
381
394
sadf_get_record_timestamp_struct(curr);
398
* For this first check, we use the time interval entered on
399
* the command line. This is equivalent to sar's option -i which
400
* selects records at seconds as close as possible to the number
401
* specified by the interval parameter.
403
if (!next_slice(record_hdr[2].uptime0, record_hdr[curr].uptime0,
405
/* Not close enough to desired interval */
408
/* Check if we are beginning a new day */
409
if (use_tm_start && record_hdr[!curr].ust_time &&
410
(record_hdr[curr].ust_time > record_hdr[!curr].ust_time) &&
411
(record_hdr[curr].hour < record_hdr[!curr].hour)) {
417
* This is necessary if we want to properly handle something like:
418
* sar -s time_start -e time_end with
419
* time_start(day D) > time_end(day D+1)
421
loctime.tm_hour += 24;
425
if (use_tm_start && (datecmp(&loctime, &tm_start) < 0))
426
/* it's too soon... */
383
429
/* Get interval values */
384
430
get_itv_value(&record_hdr[curr], &record_hdr[!curr],
385
431
cpu_nr, &itv, &g_itv);
434
if (use_tm_end && (datecmp(&loctime, &tm_end) > 0)) {
435
/* It's too late... */
388
441
/* Correct rounding error for dt */
389
442
if ((itv % HZ) >= (HZ / 2)) {
420
474
* Display XML restart records
423
* @curr Index in array for current sample statistics.
424
* @tab Number of tabulations to print.
477
* @curr Index in array for current sample statistics.
478
* @use_tm_start Set to TRUE if option -s has been used.
479
* @use_tm_end Set to TRUE if option -e has been used.
480
* @tab Number of tabulations to print.
425
481
***************************************************************************
427
void write_xml_restarts(int curr, int tab)
483
void write_xml_restarts(int curr, int use_tm_start, int use_tm_end, int tab)
429
485
char cur_time[64];
431
487
/* Fill timestamp structure for current record */
432
488
sadf_get_record_timestamp_struct(curr);
490
/* The record must be in the interval specified by -s/-e options */
491
if ((use_tm_start && (datecmp(&loctime, &tm_start) < 0)) ||
492
(use_tm_end && (datecmp(&loctime, &tm_end) > 0)))
434
495
strftime(cur_time, 64, "date=\"%Y-%m-%d\" time=\"%H:%M:%S\"", &rectime);
435
496
xprintf(tab, "<boot %s/>", cur_time);
440
501
* Display XML COMMENT records
443
* @curr Index in array for current sample statistics.
444
* @tab Number of tabulations to print.
445
* @ifd Input file descriptor.
504
* @curr Index in array for current sample statistics.
505
* @use_tm_start Set to TRUE if option -s has been used.
506
* @use_tm_end Set to TRUE if option -e has been used.
507
* @tab Number of tabulations to print.
508
* @ifd Input file descriptor.
446
509
***************************************************************************
448
void write_xml_comments(int curr, int tab, int ifd)
511
void write_xml_comments(int curr, int use_tm_start, int use_tm_end, int tab, int ifd)
450
513
char cur_time[64];
451
514
char file_comment[MAX_COMMENT_LEN];
456
519
/* Fill timestamp structure for current record */
457
520
sadf_get_record_timestamp_struct(curr);
522
/* The record must be in the interval specified by -s/-e options */
523
if ((use_tm_start && (datecmp(&loctime, &tm_start) < 0)) ||
524
(use_tm_end && (datecmp(&loctime, &tm_end) > 0)))
459
527
strftime(cur_time, 64, "date=\"%Y-%m-%d\" time=\"%H:%M:%S\"", &rectime);
460
528
xprintf(tab, "<comment %s com=\"%s\"/>", cur_time, file_comment);
753
while (!eosaf && ((rtype == R_RESTART) || (rtype == R_COMMENT)));
822
while (!eosaf && ((rtype == R_RESTART) || (rtype == R_COMMENT) ||
823
(tm_start.use && (datecmp(&loctime, &tm_start) < 0)) ||
824
(tm_end.use && (datecmp(&loctime, &tm_end) >=0))));
826
/* Save the first stats collected. Used for example in next_slice() function */
827
copy_structures(act, id_seq, record_hdr, 2, 0);
765
841
read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act,
768
write_xml_stats(curr, tab, cpu_nr);
844
/* next is set to 1 when we were close enough to desired interval */
845
next = write_xml_stats(curr, tm_start.use, tm_end.use, reset,
772
857
if (!eosaf && (rtype == R_COMMENT)) {
779
while (!eosaf && (rtype != R_RESTART));
864
while (cnt && !eosaf && (rtype != R_RESTART));
867
/* Go to next Linux restart, if possible */
869
eosaf = sa_fread(ifd, &record_hdr[curr], RECORD_HEADER_SIZE,
871
rtype = record_hdr[curr].record_type;
872
if (!eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) {
873
read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act,
876
else if (!eosaf && (rtype == R_COMMENT)) {
877
/* Ignore COMMENT record */
878
if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) {
883
while (!eosaf && (rtype != R_RESTART));
822
928
/* Last, process COMMENT entries to display comments */
823
xprintf(tab++, "<comments>");
825
if ((eosaf = sa_fread(ifd, &record_hdr[0], RECORD_HEADER_SIZE,
929
if (DISPLAY_COMMENT(flags)) {
930
xprintf(tab++, "<comments>");
932
if ((eosaf = sa_fread(ifd, &record_hdr[0], RECORD_HEADER_SIZE,
828
rtype = record_hdr[0].record_type;
829
if ((rtype != R_RESTART) && (rtype != R_COMMENT)) {
830
read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act,
833
if (rtype == R_COMMENT) {
834
write_xml_comments(0, tab, ifd);
935
rtype = record_hdr[0].record_type;
936
if ((rtype != R_RESTART) && (rtype != R_COMMENT)) {
937
read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act,
940
if (rtype == R_COMMENT) {
941
write_xml_comments(0, tm_start.use, tm_end.use,
947
xprintf(--tab, "</comments>");
839
xprintf(--tab, "</comments>");
841
950
xprintf(--tab, "</host>");
842
951
xprintf(--tab, "</sysstat>");
891
1000
/* Save the first stats collected. Will be used to compute the average */
892
1001
copy_structures(act, id_seq, record_hdr, 2, 0);
894
reset = TRUE; /* Set flag to reset last_uptime variable */
1003
/* Set flag to reset last_uptime variable. Should be done after a LINUX RESTART record */
896
1006
/* Save current file position */
897
1007
if ((fpos = lseek(ifd, 0, SEEK_CUR)) < 0) {
955
1065
read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act,
1068
else if (!eosaf && (rtype == R_COMMENT)) {
1069
/* This was a COMMENT record: print it */
1070
sadf_print_special(curr, tm_start.use, tm_end.use, R_COMMENT, ifd);
959
1073
while (!eosaf && (rtype != R_RESTART));