Skip to content

Commit

Permalink
sadf: PCP: Take into account timezone value
Browse files Browse the repository at this point in the history
The user can choose to save data in PCP archive with timestamps in UTC
(by default) or in local time (when option -T is used).
Timezone value, which is saved in PCP archive, is set accordingly.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
  • Loading branch information
sysstat committed Mar 29, 2019
1 parent dcf740a commit 25c17c5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 21 deletions.
2 changes: 1 addition & 1 deletion format.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ struct report_format raw_fmt = {
*/
struct report_format pcp_fmt = {
.id = F_PCP_OUTPUT,
.options = FO_HEADER_ONLY,
.options = FO_HEADER_ONLY + FO_LOCAL_TIME + FO_NO_TRUE_TIME,
.f_header = print_pcp_header,
.f_statistics = print_pcp_statistics,
.f_timestamp = print_pcp_timestamp,
Expand Down
6 changes: 6 additions & 0 deletions sa.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,12 @@
/* Type for all functions displaying statistics */
#define __print_funct_t void

/* Structure containing specific parameters for logic#1 output (XML/JSON/PCP...) */
struct log1_parm {
unsigned int flags; /* Common flags */
int tab; /* Number of tabulations */
};

/* Structure for SVG specific parameters */
struct svg_parm {
unsigned long long dt; /* Interval of time for current sample */
Expand Down
36 changes: 20 additions & 16 deletions sadf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,8 @@ void logic1_display_loop(int ifd, struct file_activity *file_actlst, char *file,
char *pcparchive, struct file_magic *file_magic,
struct tm *rectime, struct tm *loctime)
{
int curr, tab = 0, rtype;
struct log1_parm parm;
int curr, rtype;
int eosaf, next, reset = FALSE;
long cnt = 1;

Expand All @@ -1029,15 +1030,18 @@ void logic1_display_loop(int ifd, struct file_activity *file_actlst, char *file,
/* Save current file position */
seek_file_position(ifd, DO_SAVE);

parm.tab = 0;
parm.flags = flags;

/* Print header (eg. XML file header) */
if (*fmt[f_position]->f_header) {
(*fmt[f_position]->f_header)(&tab, F_BEGIN, pcparchive, file_magic,
(*fmt[f_position]->f_header)(&parm, F_BEGIN, pcparchive, file_magic,
&file_hdr, act, id_seq, file_actlst);
}

/* Process activities */
if (*fmt[f_position]->f_statistics) {
(*fmt[f_position]->f_statistics)(&tab, F_BEGIN, act, id_seq);
(*fmt[f_position]->f_statistics)(&(parm.tab), F_BEGIN, act, id_seq);
}

do {
Expand All @@ -1047,7 +1051,7 @@ void logic1_display_loop(int ifd, struct file_activity *file_actlst, char *file,
*/
do {
eosaf = read_next_sample(ifd, IGNORE_COMMENT | IGNORE_RESTART, 0,
file, &rtype, tab, file_magic, file_actlst,
file, &rtype, parm.tab, file_magic, file_actlst,
rectime, loctime, UEOF_STOP);
}
while (!eosaf && ((rtype == R_RESTART) || (rtype == R_COMMENT) ||
Expand All @@ -1064,17 +1068,17 @@ void logic1_display_loop(int ifd, struct file_activity *file_actlst, char *file,
if (!eosaf) {
do {
eosaf = read_next_sample(ifd, IGNORE_COMMENT | IGNORE_RESTART, curr,
file, &rtype, tab, file_magic, file_actlst,
file, &rtype, parm.tab, file_magic, file_actlst,
rectime, loctime, UEOF_CONT);

if (!eosaf && (rtype != R_COMMENT) && (rtype != R_RESTART)) {
if (*fmt[f_position]->f_statistics) {
(*fmt[f_position]->f_statistics)(&tab, F_MAIN, act, id_seq);
(*fmt[f_position]->f_statistics)(&(parm.tab), F_MAIN, act, id_seq);
}

/* next is set to 1 when we were close enough to desired interval */
next = generic_write_stats(curr, tm_start.use, tm_end.use, reset,
&cnt, &tab, rectime, loctime,
&cnt, &(parm.tab), rectime, loctime,
FALSE, ALL_ACTIVITIES);

if (next) {
Expand All @@ -1092,7 +1096,7 @@ void logic1_display_loop(int ifd, struct file_activity *file_actlst, char *file,
/* Go to next Linux restart, if possible */
do {
eosaf = read_next_sample(ifd, IGNORE_COMMENT | IGNORE_RESTART, curr,
file, &rtype, tab, file_magic, file_actlst,
file, &rtype, parm.tab, file_magic, file_actlst,
rectime, loctime, UEOF_CONT);
}
while (!eosaf && (rtype != R_RESTART));
Expand All @@ -1103,27 +1107,27 @@ void logic1_display_loop(int ifd, struct file_activity *file_actlst, char *file,
while (!eosaf);

if (*fmt[f_position]->f_statistics) {
(*fmt[f_position]->f_statistics)(&tab, F_END, act, id_seq);
(*fmt[f_position]->f_statistics)(&(parm.tab), F_END, act, id_seq);
}

/* Rewind file */
seek_file_position(ifd, DO_RESTORE);

/* Process now RESTART entries to display restart messages */
if (*fmt[f_position]->f_restart) {
(*fmt[f_position]->f_restart)(&tab, F_BEGIN, NULL, NULL, FALSE,
(*fmt[f_position]->f_restart)(&(parm.tab), F_BEGIN, NULL, NULL, FALSE,
&file_hdr);
}

do {
eosaf = read_next_sample(ifd, IGNORE_COMMENT, 0,
file, &rtype, tab, file_magic, file_actlst,
file, &rtype, parm.tab, file_magic, file_actlst,
rectime, loctime, UEOF_CONT);
}
while (!eosaf);

if (*fmt[f_position]->f_restart) {
(*fmt[f_position]->f_restart)(&tab, F_END, NULL, NULL, FALSE, &file_hdr);
(*fmt[f_position]->f_restart)(&(parm.tab), F_END, NULL, NULL, FALSE, &file_hdr);
}

/* Rewind file */
Expand All @@ -1132,25 +1136,25 @@ void logic1_display_loop(int ifd, struct file_activity *file_actlst, char *file,
/* Last, process COMMENT entries to display comments */
if (DISPLAY_COMMENT(flags)) {
if (*fmt[f_position]->f_comment) {
(*fmt[f_position]->f_comment)(&tab, F_BEGIN, NULL, NULL, 0, NULL,
(*fmt[f_position]->f_comment)(&(parm.tab), F_BEGIN, NULL, NULL, 0, NULL,
&file_hdr);
}
do {
eosaf = read_next_sample(ifd, IGNORE_RESTART, 0,
file, &rtype, tab, file_magic, file_actlst,
file, &rtype, parm.tab, file_magic, file_actlst,
rectime, loctime, UEOF_CONT);
}
while (!eosaf);

if (*fmt[f_position]->f_comment) {
(*fmt[f_position]->f_comment)(&tab, F_END, NULL, NULL, 0, NULL,
(*fmt[f_position]->f_comment)(&(parm.tab), F_END, NULL, NULL, 0, NULL,
&file_hdr);
}
}

/* Print header trailer */
if (*fmt[f_position]->f_header) {
(*fmt[f_position]->f_header)(&tab, F_END, pcparchive, file_magic,
(*fmt[f_position]->f_header)(&parm, F_END, pcparchive, file_magic,
&file_hdr, act, id_seq, file_actlst);
}
}
Expand Down
29 changes: 25 additions & 4 deletions sadf_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <stdio.h>
#include <string.h>
#include <time.h>

#include "sadf.h"
#include "pcp_def_metrics.h"
Expand All @@ -38,6 +39,8 @@
#include <pcp/import.h>
#endif

extern char *tzname[2];

extern unsigned int flags;
extern char *seps[];

Expand Down Expand Up @@ -813,9 +816,19 @@ __tm_funct_t print_pcp_timestamp(void *parm, int action, char *cur_date,
{
#ifdef HAVE_PCP
int rc;
struct tm lrectime;
unsigned long long utc_sec = record_hdr->ust_time;

if (action & F_END) {
if ((rc = pmiWrite(record_hdr->ust_time, 0)) < 0) {
if (!PRINT_LOCAL_TIME(flags)) {
/* Convert a time_t value from local time to UTC */
if (gmtime_r((const time_t *) &(record_hdr->ust_time), &lrectime)) {
utc_sec = mktime(&lrectime);
}
}

/* Write data to PCP archive */
if ((rc = pmiWrite(utc_sec, 0)) < 0) {
fprintf(stderr, "PCP: pmiWrite: %s\n", pmiErrStr(rc));
exit(4);
}
Expand Down Expand Up @@ -850,7 +863,7 @@ __printf_funct_t print_xml_header(void *parm, int action, char *dfile,
{
struct tm rectime, loc_t;
char cur_time[TIMESTAMP_LEN];
int *tab = (int *) parm;
int *tab = &(((struct log1_parm *) parm)->tab);

if (action & F_BEGIN) {
printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
Expand Down Expand Up @@ -918,7 +931,7 @@ __printf_funct_t print_json_header(void *parm, int action, char *dfile,
{
struct tm rectime, loc_t;
char cur_time[TIMESTAMP_LEN];
int *tab = (int *) parm;
int *tab = &(((struct log1_parm *) parm)->tab);

if (action & F_BEGIN) {
xprintf(*tab, "{\"sysstat\": {");
Expand Down Expand Up @@ -1179,12 +1192,20 @@ __printf_funct_t print_pcp_header(void *parm, int action, char *dfile,
struct file_activity *file_actlst)
{
#ifdef HAVE_PCP
unsigned int lflags = ((struct log1_parm *) parm)->flags;
char buf[64];

if (action & F_BEGIN) {
/* Create new PCP context */
pmiStart(dfile, FALSE);
pmiSetTimezone("UTC");

if (PRINT_LOCAL_TIME(lflags)) {
tzset(); /* Set timezone value in tzname */
pmiSetTimezone(tzname[0]);
}
else {
pmiSetTimezone("UTC");
}

/* Save number of CPU in PCP archive */
pmiAddMetric("hinv.ncpu",
Expand Down

0 comments on commit 25c17c5

Please sign in to comment.