]> granicus.if.org Git - sysstat/commitdiff
sadf: Add new output format: raw (part 1)
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 18 Dec 2016 09:42:10 +0000 (10:42 +0100)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 18 Dec 2016 09:42:10 +0000 (10:42 +0100)
Add a new output format to sadf to display statistics saved in a binary
data file in raw format. Counters values are displayed "as is", without
trying to calculate an average value over the elapsed time interval.
This is something I have selfishly wanted to have for a long time now,
mainly for debugging purpose.
This first patch adds all the necessary global functions, and implements
the raw format only for CPU and task creation/system switching
statistics.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
Makefile.in
activity.c
format.c
raw_stats.c [new file with mode: 0644]
raw_stats.h [new file with mode: 0644]
sa.h
sadf.c
sadf.h
sadf_misc.c

index efb56cef41ac3ee90e5bc75b6225b83e6d4ac5f2..e3c3b28ee7f1cb553904bbae6acda2228df454b6 100644 (file)
@@ -187,7 +187,7 @@ act_sadc.o: activity.c sa.h rd_stats.h rd_sensors.h
 act_sar.o: activity.c sa.h pr_stats.h
        $(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $<
 
-act_sadf.o: activity.c sa.h rndr_stats.h xml_stats.h json_stats.h svg_stats.h
+act_sadf.o: activity.c sa.h rndr_stats.h xml_stats.h json_stats.h svg_stats.h raw_stats.h
        $(CC) -o $@ -c $(CFLAGS) -DSOURCE_SADF $(DFLAGS) $<
 
 rd_stats.o: rd_stats.c common.h rd_stats.h ioconf.h sysconfig.h
@@ -214,6 +214,8 @@ json_stats.o: json_stats.c sa.h sadf.h ioconf.h sysconfig.h json_stats.h
 
 svg_stats.o: svg_stats.c sa.h sadf.h ioconf.h sysconfig.h svg_stats.h
 
+raw_stats.o: raw_stats.c sa.h sadf.h ioconf.h sysconfig.h raw_stats.h
+
 sa_wrap.o: sa_wrap.c sa.h rd_stats.h count.h rd_sensors.h prealloc.h
 
 format_sadf.o: format.c sadf.h
@@ -253,7 +255,7 @@ sar: sar.o act_sar.o format_sar.o sa_common.o pr_stats.o libsyscom.a
 
 sadf.o: sadf.c sadf.h version.h sa.h common.h ioconf.h sysconfig.h
 
-sadf: sadf.o act_sadf.o format_sadf.o sadf_misc.o sa_conv.o rndr_stats.o xml_stats.o json_stats.o svg_stats.o sa_common.o libsyscom.a
+sadf: sadf.o act_sadf.o format_sadf.o sadf_misc.o sa_conv.o rndr_stats.o xml_stats.o json_stats.o svg_stats.o raw_stats.o sa_common.o libsyscom.a
 
 iostat.o: iostat.c iostat.h version.h common.h ioconf.h sysconfig.h rd_stats.h count.h
 
index fff8ae0711d943a235392fe4e45a3c29495408a5..dfe8b38b65299e0dfe13ac0b0f8dae4ff1559f25 100644 (file)
@@ -35,6 +35,7 @@
 #include "xml_stats.h"
 #include "json_stats.h"
 #include "svg_stats.h"
+#include "raw_stats.h"
 #endif
 
 /*
@@ -92,6 +93,7 @@ struct activity cpu_act = {
        .f_xml_print    = xml_print_cpu_stats,
        .f_json_print   = json_print_cpu_stats,
        .f_svg_print    = svg_print_cpu_stats,
+       .f_raw_print    = raw_print_cpu_stats,
        .name           = "A_CPU",
        .g_nr           = 1,
 #endif
@@ -128,6 +130,7 @@ struct activity pcsw_act = {
        .f_xml_print    = xml_print_pcsw_stats,
        .f_json_print   = json_print_pcsw_stats,
        .f_svg_print    = svg_print_pcsw_stats,
+       .f_raw_print    = raw_print_pcsw_stats,
        .name           = "A_PCSW",
        .g_nr           = 2,
 #endif
index 1283e5cf25941a04cf955aa7fba95e96f04f9b69..4a90b5372ac249a3817d631b5e3380f0801a87bf 100644 (file)
--- a/format.c
+++ b/format.c
@@ -127,6 +127,19 @@ struct report_format svg_fmt = {
        .f_comment      = NULL
 };
 
+/*
+ * Raw output.
+ */
+struct report_format raw_fmt = {
+       .id             = F_RAW_OUTPUT,
+       .options        = FO_GROUPED_STATS + FO_LOCAL_TIME + FO_SEC_EPOCH,
+       .f_header       = NULL,
+       .f_statistics   = NULL,
+       .f_timestamp    = print_raw_timestamp,
+       .f_restart      = print_raw_restart,
+       .f_comment      = print_raw_comment
+};
+
 /*
  * Array of output formats.
  */
@@ -137,7 +150,8 @@ struct report_format *fmt[NR_FMT] = {
        &xml_fmt,
        &json_fmt,
        &conv_fmt,
-       &svg_fmt
+       &svg_fmt,
+       &raw_fmt
 };
 #endif
 
diff --git a/raw_stats.c b/raw_stats.c
new file mode 100644 (file)
index 0000000..3c61e76
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * raw_stats.c: Functions used by sar to display statistics in raw format.
+ * (C) 1999-2017 by Sebastien GODARD (sysstat <at> orange.fr)
+ *
+ ***************************************************************************
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU General Public License as published  by  the *
+ * Free Software Foundation; either version 2 of the License, or (at  your *
+ * option) any later version.                                              *
+ *                                                                         *
+ * This program is distributed in the hope that it  will  be  useful,  but *
+ * WITHOUT ANY WARRANTY; without the implied warranty  of  MERCHANTABILITY *
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
+ * for more details.                                                       *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA              *
+ ***************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "sa.h"
+#include "ioconf.h"
+#include "raw_stats.h"
+
+extern unsigned int flags;
+
+
+/*
+ ***************************************************************************
+ * Display current field name.
+ *
+ * IN:
+ * @hdr_line   On the first call, complete header line, containing all the
+ *             metric names. In each subsequent call, must be NULL.
+ * @pos                Index in @hdr_line string, 0 being the first one (headers
+ *             are delimited by the '|' character).
+ ***************************************************************************
+ */
+char *pfield(char *hdr_line, int pos)
+{
+       char hline[HEADER_LINE_LEN] = "";
+       static char field[HEADER_LINE_LEN] = "";
+       static int idx = 0;
+       char *hl;
+       int i, j = 0;
+
+       if (hdr_line) {
+               strncpy(hline, hdr_line, HEADER_LINE_LEN - 1);
+               hline[HEADER_LINE_LEN - 1] = '\0';
+               idx = 0;
+
+               for (hl = strtok(hline, "|"); hl && (pos > 0); hl = strtok(NULL, "|"), pos--);
+               if (!hl) {
+                       /* Bad @pos arg given to function */
+                       strcpy(field, "");
+                       return field;
+               }
+               if (strchr(hl, '&')) {
+                       j = strcspn(hl, "&");
+                       *(hl + j) = ';';
+               }
+               strcpy(field, hl);
+       }
+
+       /* Display current field */
+       if (strchr(field + idx, ';')) {
+               j = strcspn(field + idx, ";");
+               *(field + idx + j) = '\0';
+       }
+       i = idx;
+       idx += j + 1;
+
+       return field + i;
+}
+
+/*
+ ***************************************************************************
+ * Display field values.
+ *
+ * IN:
+ * @valp       Field's value from previous statistics sample.
+ * @valc       Field's value from current statistics sample.
+ ***************************************************************************
+ */
+void pval(unsigned long long valp, unsigned long long valc)
+{
+       printf("%llu>%llu", valp, valc);
+       if (DISPLAY_HINTS(flags)) {
+               if (valc < valp) {
+                       /* Field's value has decreased */
+                       printf(" [DEC]");
+               }
+       }
+}
+
+/*
+ ***************************************************************************
+ * Display CPU statistics in raw format.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @timestr    Time for current statistics sample.
+ * @curr       Index in array for current statistics sample.
+ ***************************************************************************
+ */
+__print_funct_t raw_print_cpu_stats(struct activity *a, char *timestr, int curr)
+{
+       int i;
+       struct stats_cpu *scc, *scp;
+
+       for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+
+               /*
+                * The size of a->buf[...] CPU structure may be different from the default
+                * sizeof(struct stats_cpu) value if data have been read from a file!
+                * That's why we don't use a syntax like:
+                * scc = (struct stats_cpu *) a->buf[...] + i;
+                */
+               scc = (struct stats_cpu *) ((char *) a->buf[curr] + i * a->msize);
+               scp = (struct stats_cpu *) ((char *) a->buf[!curr] + i * a->msize);
+
+               /*
+                * Note: a->nr is in [1, NR_CPUS + 1].
+                * Bitmap size is provided for (NR_CPUS + 1) CPUs.
+                * Anyway, NR_CPUS may vary between the version of sysstat
+                * used by sadc to create a file, and the version of sysstat
+                * used by sar to read it...
+                */
+
+               /* Should current CPU (including CPU "all") be displayed? */
+               if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
+                       /* No */
+                       continue;
+
+               /* Yes: Display it */
+               printf("%s %s:%d", timestr,
+                      pfield(a->hdr_line, DISPLAY_CPU_ALL(a->opt_flags)), i - 1);
+
+               if (DISPLAY_HINTS(flags) && i) {
+                       if ((scc->cpu_user + scc->cpu_nice + scc->cpu_sys +
+                            scc->cpu_iowait + scc->cpu_idle + scc->cpu_steal +
+                            scc->cpu_hardirq + scc->cpu_softirq) == 0) {
+                               /* CPU is offline */
+                               printf(" [OFF]");
+                       }
+                       else {
+                               if (!get_per_cpu_interval(scc, scp)) {
+                                       /* CPU is tickless */
+                                       printf(" [TLS]");
+                               }
+                       }
+               }
+
+               if (DISPLAY_CPU_DEF(a->opt_flags)) {
+                       printf(" %s:", pfield(NULL, 0));
+                       pval(scp->cpu_user, scc->cpu_user);
+                       printf(" %s:", pfield(NULL, 0));
+                       pval(scp->cpu_nice, scc->cpu_nice);
+                       printf(" %s:", pfield(NULL, 0));
+                       pval(scp->cpu_sys + scp->cpu_hardirq + scp->cpu_softirq,
+                            scc->cpu_sys + scc->cpu_hardirq + scc->cpu_softirq);
+                       printf(" %s:", pfield(NULL, 0));
+                       pval(scp->cpu_iowait, scc->cpu_iowait);
+                       printf(" %s:", pfield(NULL, 0));
+                       pval(scp->cpu_steal, scc->cpu_steal);
+                       printf(" %s:", pfield(NULL, 0));
+                       pval(scp->cpu_idle, scc->cpu_idle);
+               }
+               else if (DISPLAY_CPU_ALL(a->opt_flags)) {
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_user - scp->cpu_guest, scc->cpu_user - scc->cpu_guest);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_nice - scp->cpu_guest_nice, scc->cpu_nice - scc->cpu_guest_nice);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_sys, scc->cpu_sys);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_iowait, scc->cpu_iowait);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_steal, scc->cpu_steal);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_hardirq, scc->cpu_hardirq);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_softirq, scc->cpu_softirq);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_guest, scc->cpu_guest);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_guest_nice, scc->cpu_guest_nice);
+                       printf(" %s:", pfield(NULL, 1));
+                       pval(scp->cpu_idle, scc->cpu_idle);
+               }
+               printf("\n");
+       }
+}
+
+/*
+ ***************************************************************************
+ * Display tasks creation and context switches statistics in raw format.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @timestr    Time for current statistics sample.
+ * @curr       Index in array for current sample statistics.
+ ***************************************************************************
+ */
+__print_funct_t raw_print_pcsw_stats(struct activity *a, char *timestr, int curr)
+{
+       struct stats_pcsw
+               *spc = (struct stats_pcsw *) a->buf[curr],
+               *spp = (struct stats_pcsw *) a->buf[!curr];
+
+       printf("%s %s:", timestr, pfield(a->hdr_line, 0));
+       pval(spp->processes, spc->processes);
+       printf(" %s:", pfield(NULL, 0));
+       pval(spp->context_switch, spc->context_switch);
+       printf("\n");
+}
diff --git a/raw_stats.h b/raw_stats.h
new file mode 100644 (file)
index 0000000..1db8bc0
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * raw_stats.h: Include file used to display statistics in raw format.
+ * (C) 1999-2017 by Sebastien Godard (sysstat <at> orange.fr)
+ */
+
+#ifndef _RAW_STATS_H
+#define _RAW_STATS_H
+
+#include "common.h"
+
+/*
+ ***************************************************************************
+ * Prototypes for functions used to display statistics in raw format.
+ ***************************************************************************
+ */
+
+__print_funct_t raw_print_cpu_stats
+       (struct activity *, char *, int);
+__print_funct_t raw_print_pcsw_stats
+       (struct activity *, char *, int);
+
+#endif /* _RAW_STATS_H */
diff --git a/sa.h b/sa.h
index 68eb88e6b8475ddba48e84808a7582b13a528660..c02e5c7fe033c1bcc898d47c31afcd387d5e03cb 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -99,6 +99,8 @@
 #define S_F_LOCAL_TIME         0x00004000
 #define S_F_PREFD_TIME_OUTPUT  0x00008000
 #define S_F_SVG_SKIP           0x00010000
+/* Same value as S_F_SVG_SKIP above. Used for a different output format */
+#define S_F_RAW_SHOW_HINTS     0x00010000
 #define S_F_SVG_AUTOSCALE      0x00020000
 #define S_F_SVG_ONE_DAY                0x00040000
 #define S_F_SVG_SHOW_IDLE      0x00080000
 #define PRINT_LOCAL_TIME(m)            (((m) & S_F_LOCAL_TIME)   == S_F_LOCAL_TIME)
 #define USE_PREFD_TIME_OUTPUT(m)       (((m) & S_F_PREFD_TIME_OUTPUT)   == S_F_PREFD_TIME_OUTPUT)
 #define SKIP_EMPTY_VIEWS(m)            (((m) & S_F_SVG_SKIP)     == S_F_SVG_SKIP)
+#define DISPLAY_HINTS(m)               (((m) & S_F_RAW_SHOW_HINTS) == S_F_RAW_SHOW_HINTS)
 #define AUTOSCALE_ON(m)                        (((m) & S_F_SVG_AUTOSCALE) == S_F_SVG_AUTOSCALE)
 #define DISPLAY_ONE_DAY(m)             (((m) & S_F_SVG_ONE_DAY)   == S_F_SVG_ONE_DAY)
 #define DISPLAY_IDLE(m)                        (((m) & S_F_SVG_SHOW_IDLE) == S_F_SVG_SHOW_IDLE)
 #define K_AUTOSCALE    "autoscale"
 #define K_ONEDAY       "oneday"
 #define K_SHOWIDLE     "showidle"
+#define K_SHOWHINTS    "showhints"
 
 /* Groups of activities */
 #define G_DEFAULT      0x00
@@ -691,6 +695,10 @@ struct activity {
         */
        __print_funct_t (*f_svg_print) (struct activity *, int, int, struct svg_parm *,
                                        unsigned long long, struct record_header *);
+       /*
+        * This function is used by sadf to display activity statistics in raw format.
+        */
+       __print_funct_t (*f_raw_print) (struct activity *, char *, int);
        /*
         * Header string displayed by sadf -d.
         * Header lines for each output (for activities with multiple outputs) are
diff --git a/sadf.c b/sadf.c
index 655ac66a1abc89d60fc2e25f1be87e2ab253b4dc..92655cefbb033b5358c173a2cee32a08a721adea 100644 (file)
--- a/sadf.c
+++ b/sadf.c
@@ -691,6 +691,11 @@ int generic_write_stats(int curr, int use_tm_start, int use_tm_end, int reset,
                                                       &record_hdr[curr]);
                        }
 
+                       else if (format == F_RAW_OUTPUT) {
+                               /* Raw output */
+                               (*act[i]->f_raw_print)(act[i], pre, curr);
+                       }
+
                        else {
                                /* Other output formats: db, ppc */
                                (*act[i]->f_render)(act[i], (format == F_DB_OUTPUT), pre, curr,
@@ -1109,7 +1114,7 @@ void logic1_display_loop(int ifd, struct file_activity *file_actlst, char *file,
  * Display file contents in selected format (logic #2).
  * Logic #2:   Grouped by activity. Sorted by timestamp. Stop on RESTART
  *             records.
- * Formats:    ppc, CSV
+ * Formats:    ppc, CSV, raw
  *
  * IN:
  * @ifd                File descriptor of input file.
@@ -1476,7 +1481,7 @@ int main(int argc, char **argv)
                }
 
                else if (!strcmp(argv[opt], "-O")) {
-                       /* Parse SVG options */
+                       /* Parse output options */
                        if (!argv[++opt] || sar_options) {
                                usage(argv[0]);
                        }
@@ -1493,6 +1498,9 @@ int main(int argc, char **argv)
                                else if (!strcmp(t, K_SHOWIDLE)) {
                                        flags |= S_F_SVG_SHOW_IDLE;
                                }
+                               else if (!strcmp(t, K_SHOWHINTS)) {
+                                       flags |= S_F_RAW_SHOW_HINTS;
+                               }
                                else {
                                        usage(argv[0]);
                                }
@@ -1603,6 +1611,13 @@ int main(int argc, char **argv)
                                                format = F_PPC_OUTPUT;
                                                break;
 
+                                       case 'r':
+                                               if (format) {
+                                                       usage(argv[0]);
+                                               }
+                                               format = F_RAW_OUTPUT;
+                                               break;
+
                                        case 'T':
                                                flags |= S_F_LOCAL_TIME;
                                                break;
diff --git a/sadf.h b/sadf.h
index d9691a7efdae975913d9a3ca4ffd0a6f348406e0..2b4e3b66e4584c8be6c9afb240f60d15b0e359fa 100644 (file)
--- a/sadf.h
+++ b/sadf.h
@@ -28,7 +28,7 @@
  */
 
 /* Number of output formats */
-#define NR_FMT 7
+#define NR_FMT 8
 
 /* Output formats */
 #define F_DB_OUTPUT    1
@@ -38,6 +38,7 @@
 #define F_JSON_OUTPUT  5
 #define F_CONV_OUTPUT  6
 #define F_SVG_OUTPUT   7
+#define F_RAW_OUTPUT   8
 
 /* Format options */
 
@@ -138,6 +139,8 @@ __printf_funct_t print_json_restart
        (int *, int, char *, char *, int, struct file_header *, unsigned int);
 __printf_funct_t print_sar_restart
        (int *, int, char *, char *, int, struct file_header *, unsigned int);
+__printf_funct_t print_raw_restart
+       (int *, int, char *, char *, int, struct file_header *, unsigned int);
 
 /*
  * Prototypes used to display comments
@@ -152,6 +155,8 @@ __printf_funct_t print_json_comment
        (int *, int, char *, char *, int, char *, struct file_header *);
 __printf_funct_t print_sar_comment
        (int *, int, char *, char *, int, char *, struct file_header *);
+__printf_funct_t print_raw_comment
+       (int *, int, char *, char *, int, char *, struct file_header *);
 
 /*
  * Prototypes used to display the statistics part of the report
@@ -172,6 +177,8 @@ __tm_funct_t print_xml_timestamp
        (void *, int, char *, char *, unsigned long long, struct file_header *, unsigned int);
 __tm_funct_t print_json_timestamp
        (void *, int, char *, char *, unsigned long long, struct file_header *, unsigned int);
+__tm_funct_t print_raw_timestamp
+       (void *, int, char *, char *, unsigned long long, struct file_header *, unsigned int);
 
 /*
  * Prototypes used to display the report header
index 9aa4614678427703854b79eb36a8069acf46fde2..1b61d286918ba080bb69c7ea02c1eb413915cd29 100644 (file)
@@ -191,6 +191,34 @@ __printf_funct_t print_json_restart(int *tab, int action, char *cur_date,
        }
 }
 
+/*
+ ***************************************************************************
+ * Display restart messages (raw format).
+ *
+ * IN:
+ * @tab                Number of tabulations (unused here).
+ * @action     Action expected from current function.
+ * @cur_date   Date string of current restart message.
+ * @cur_time   Time string of current restart message.
+ * @utc                True if @cur_time is expressed in UTC.
+ * @file_hdr   System activity file standard header (unused here).
+ * @cpu_nr     CPU count associated with restart mark.
+ ***************************************************************************
+ */
+__printf_funct_t print_raw_restart(int *tab, int action, char *cur_date,
+                                  char *cur_time, int utc, struct file_header *file_hdr,
+                                  unsigned int cpu_nr)
+{
+       /* Actions F_BEGIN and F_END ignored */
+       if (action == F_MAIN) {
+               printf("%s", cur_time);
+               if (strlen(cur_date) && utc) {
+                       printf(" UTC");
+               }
+               printf("\tLINUX-RESTART\t(%d CPU)\n", cpu_nr > 1 ? cpu_nr - 1 : 1);
+       }
+}
+
 /*
  ***************************************************************************
  * Display comments (database and ppc formats).
@@ -349,6 +377,34 @@ __printf_funct_t print_json_comment(int *tab, int action, char *cur_date,
        }
 }
 
+/*
+ ***************************************************************************
+ * Display comments (raw format).
+ *
+ * IN:
+ * @tab                Number of tabulations (unused here).
+ * @action     Action expected from current function.
+ * @cur_date   Date string of current restart message.
+ * @cur_time   Time string of current restart message.
+ * @utc                True if @cur_time is expressed in UTC.
+ * @comment    Comment to display.
+ * @file_hdr   System activity file standard header (unused here).
+ ***************************************************************************
+ */
+__printf_funct_t print_raw_comment(int *tab, int action, char *cur_date,
+                                  char *cur_time, int utc, char *comment,
+                                  struct file_header *file_hdr)
+{
+       /* Actions F_BEGIN and F_END ignored */
+       if (action & F_MAIN) {
+               printf("%s", cur_time);
+               if (strlen(cur_date) && utc) {
+                       printf(" UTC");
+               }
+               printf("\tCOM %s\n", comment);
+       }
+}
+
 /*
  ***************************************************************************
  * Display the "statistics" part of the report (XML format).
@@ -589,6 +645,39 @@ __tm_funct_t print_json_timestamp(void *parm, int action, char *cur_date,
        return NULL;
 }
 
+/*
+ ***************************************************************************
+ * Display the "timestamp" part of the report (raw format).
+ *
+ * IN:
+ * @parm       Pointer on specific parameters (unused here).
+ * @action     Action expected from current function.
+ * @cur_date   Date string of current record.
+ * @cur_time   Time string of current record.
+ * @itv                Interval of time with preceding record (unused here).
+ * @file_hdr   System activity file standard header (unused here).
+ * @flags      Flags for common options.
+ *
+ * RETURNS:
+ * Pointer on the "timestamp" string.
+ ***************************************************************************
+ */
+__tm_funct_t print_raw_timestamp(void *parm, int action, char *cur_date,
+                               char *cur_time, unsigned long long itv,
+                               struct file_header *file_hdr, unsigned int flags)
+{
+       int utc = !PRINT_LOCAL_TIME(flags) && !PRINT_TRUE_TIME(flags);
+       static char pre[80];
+
+       if (action & F_BEGIN) {
+               snprintf(pre, 80, "%s%s", cur_time, strlen(cur_date) && utc ? " UTC" : "");
+               pre[79] = '\0';
+               return pre;
+       }
+
+       return NULL;
+}
+
 /*
  ***************************************************************************
  * Display the header of the report (XML format).