void GroupControl::adjustArchiveWorldViewBackward(QmcTime::Packet *packet, bool setup) { console->post("GroupControl::adjustArchiveWorldViewBackward"); my.timeState = BackwardState; int setmode = PM_MODE_INTERP; int delta = packet->delta.tv_sec; if (packet->delta.tv_usec == 0) { setmode |= PM_XTB_SET(PM_TIME_SEC); } else { delta = delta * 1000 + packet->delta.tv_usec / 1000; setmode |= PM_XTB_SET(PM_TIME_MSEC); } // // X-Axis _min_ becomes packet->position. // Rest of (following) time window filled in using packet->delta. // int last = my.samples - 1; double tolerance = my.realDelta / 20.0; // 5% of the sample interval double position = my.realPosition; double left = position - (my.realDelta * last); double right = position; double interval = pmchart->timeAxis()->scaleValue((double)delta, my.visible); for (int i = 0; i <= last; i++, position -= my.realDelta) { if (setup == false && fuzzyTimeMatch(my.timeData[i], position, tolerance) == true) { continue; } my.timeData[i] = position; struct timeval timeval; __pmtimevalFromReal(position, &timeval); setArchiveMode(setmode, &timeval, -delta); console->post("Fetching data[%d] at %s", i, timeString(position)); fetch(); if (i == last) // refreshGadgets() finishes up last one break; console->post("GroupControl::adjustArchiveWorldViewBackward: " "setting time position[%d]=%.2f[%s] state=%s count=%d", i, position, timeString(position), timeState(), gadgetCount()); for (int j = 0; j < gadgetCount(); j++) my.gadgetsList.at(j)->updateValues(false, false, my.samples, my.visible, left, right, interval); } bool active = isActive(packet); if (setup) packet->state = QmcTime::StoppedState; if (active) newButtonState(packet->state, packet->mode, pmchart->isTabRecording()); pmtime->setArchivePosition(&packet->position); pmtime->setArchiveInterval(&packet->delta); refreshGadgets(active); }
static void setup_step_mode(pmOptions *opts, int forward) { const int SECONDS_IN_24_DAYS = 2073600; if (forward) curtime = opts->start; else curtime = opts->origin; if (!rawreadflag) fetchmode = PM_MODE_LIVE; else if (forward) fetchmode = PM_MODE_FORW; else fetchmode = PM_MODE_INTERP; if (interval.tv_sec > SECONDS_IN_24_DAYS) { fetchstep = interval.tv_sec; fetchmode |= PM_XTB_SET(PM_TIME_SEC); } else { fetchstep = interval.tv_sec * 1e3 + interval.tv_usec / 1e3; fetchmode |= PM_XTB_SET(PM_TIME_MSEC); } }
static int getXTBintervalFromTimeval(int *mode, struct timeval *tval) { double tmp_ival = tval->tv_sec + tval->tv_usec / 1000000.0; if (tmp_ival > SECS_IN_24_DAYS) { *mode = (*mode & 0x0000ffff) | PM_XTB_SET(PM_TIME_SEC); return ((int)tmp_ival); } else { *mode = (*mode & 0x0000ffff) | PM_XTB_SET(PM_TIME_MSEC); return ((int)(tmp_ival * 1000.0)); } }
/* helper function for Extended Time Base */ static void getDoubleAsXTB(double *realtime, int *ival, int *mode) { #define SECS_IN_24_DAYS 2073600.0 if (*realtime > SECS_IN_24_DAYS) { *ival = (int)*realtime; *mode = (*mode & 0x0000ffff) | PM_XTB_SET(PM_TIME_SEC); } else { *ival = (int)(*realtime * 1000.0); *mode = (*mode & 0x0000ffff) | PM_XTB_SET(PM_TIME_MSEC); } }
static void setup_step_mode(void) { const int SECONDS_IN_24_DAYS = 2073600; if (rawreadflag) fetchmode = PM_MODE_INTERP; else fetchmode = PM_MODE_LIVE; if (interval.tv_sec > SECONDS_IN_24_DAYS) { fetchstep = interval.tv_sec; fetchmode |= PM_XTB_SET(PM_TIME_SEC); } else { fetchstep = interval.tv_sec * 1e3 + interval.tv_usec / 1e3; fetchmode |= PM_XTB_SET(PM_TIME_MSEC); } }
int main(int argc, char **argv) { int sts; char *msg; pmResult *irp; /* input pmResult */ pmResult *orp; /* output pmResult */ __pmPDU *pb; /* pdu buffer */ struct timeval unused; unsigned long peek_offset; /* process cmd line args */ if (parseargs(argc, argv) < 0) { pmUsageMessage(&opts); exit(1); } /* input archive name is argv[opts.optind] */ /* output archive name is argv[argc-1]) */ /* output archive */ oname = argv[argc-1]; /* input archive */ iname = argv[opts.optind]; /* * This is the interp mode context */ if ((ictx_a = pmNewContext(PM_CONTEXT_ARCHIVE, iname)) < 0) { fprintf(stderr, "%s: Error: cannot open archive \"%s\" (ctx_a): %s\n", pmProgname, iname, pmErrStr(ictx_a)); exit(1); } if ((sts = pmGetArchiveLabel(&ilabel)) < 0) { fprintf(stderr, "%s: Error: cannot get archive label record (%s): %s\n", pmProgname, iname, pmErrStr(sts)); exit(1); } /* start time */ logstart_tval.tv_sec = ilabel.ll_start.tv_sec; logstart_tval.tv_usec = ilabel.ll_start.tv_usec; /* end time */ if ((sts = pmGetArchiveEnd(&logend_tval)) < 0) { fprintf(stderr, "%s: Error: cannot get end of archive (%s): %s\n", pmProgname, iname, pmErrStr(sts)); exit(1); } if (zarg) { /* use TZ from metrics source (input-archive) */ if ((sts = pmNewZone(ilabel.ll_tz)) < 0) { fprintf(stderr, "%s: Cannot set context timezone: %s\n", pmProgname, pmErrStr(sts)); exit(1); } printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n", ilabel.ll_hostname); } else if (tz != NULL) { /* use TZ as specified by user */ if ((sts = pmNewZone(tz)) < 0) { fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n", pmProgname, tz, pmErrStr(sts)); exit(1); } printf("Note: timezone set to \"TZ=%s\"\n\n", tz); } else { char *tz; tz = __pmTimezone(); /* use TZ from local host */ if ((sts = pmNewZone(tz)) < 0) { fprintf(stderr, "%s: Cannot set local host's timezone: %s\n", pmProgname, pmErrStr(sts)); exit(1); } } /* set winstart and winend timevals */ sts = pmParseTimeWindow(Sarg, Targ, Aarg, Oarg, &logstart_tval, &logend_tval, &winstart_tval, &winend_tval, &unused, &msg); if (sts < 0) { fprintf(stderr, "%s: Invalid time window specified: %s\n", pmProgname, msg); exit(1); } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) { char buf[26]; pmCtime((const time_t *)&winstart_tval.tv_sec, buf); fprintf(stderr, "Start time: %s", buf); pmCtime((const time_t *)&winend_tval.tv_sec, buf); fprintf(stderr, "End time: %s", buf); } #endif if ((sts = pmSetMode(PM_MODE_INTERP | PM_XTB_SET(PM_TIME_SEC), &winstart_tval, (int)targ)) < 0) { fprintf(stderr, "%s: pmSetMode(PM_MODE_INTERP ...) failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } /* create output log - must be done before writing label */ if ((sts = __pmLogCreate("", oname, PM_LOG_VERS02, &logctl)) < 0) { fprintf(stderr, "%s: Error: __pmLogCreate: %s\n", pmProgname, pmErrStr(sts)); exit(1); } /* This must be done after log is created: * - checks that archive version, host, and timezone are ok * - set archive version, host, and timezone of output archive * - set start time * - write labels */ newlabel(); current.tv_sec = logctl.l_label.ill_start.tv_sec = winstart_tval.tv_sec; current.tv_usec = logctl.l_label.ill_start.tv_usec = winstart_tval.tv_usec; /* write label record */ writelabel(); /* * Supress any automatic label creation in libpcp at the first * pmResult write. */ logctl.l_state = PM_LOG_STATE_INIT; /* * Traverse the PMNS to get all the metrics and their metadata */ if ((sts = pmTraversePMNS ("", dometric)) < 0) { fprintf(stderr, "%s: Error traversing namespace ... %s\n", pmProgname, pmErrStr(sts)); goto cleanup; } /* * All the initial metadata has been generated, add timestamp */ fflush(logctl.l_mdfp); __pmLogPutIndex(&logctl, ¤t); written = 0; /* * main loop */ while (sarg == -1 || written < sarg) { /* * do stuff */ if ((sts = pmUseContext(ictx_a)) < 0) { fprintf(stderr, "%s: Error: cannot use context (%s): %s\n", pmProgname, iname, pmErrStr(sts)); goto cleanup; } if ((sts = pmFetch(numpmid, pmidlist, &irp)) < 0) { if (sts == PM_ERR_EOL) break; fprintf(stderr, "%s: Error: pmFetch failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } if (irp->timestamp.tv_sec > winend_tval.tv_sec || (irp->timestamp.tv_sec == winend_tval.tv_sec && irp->timestamp.tv_usec > winend_tval.tv_usec)) { /* past end time as per -T */ break; } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) { fprintf(stderr, "input record ...\n"); __pmDumpResult(stderr, irp); } #endif /* * traverse the interval, looking at every archive record ... * we are particularly interested in: * - metric-values that are interpolated but not present in * this interval * - counter wraps * - mark records */ doscan(&irp->timestamp); if ((sts = pmUseContext(ictx_a)) < 0) { fprintf(stderr, "%s: Error: cannot use context (%s): %s\n", pmProgname, iname, pmErrStr(sts)); goto cleanup; } orp = rewrite(irp); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) { if (orp == NULL) fprintf(stderr, "output record ... none!\n"); else { fprintf(stderr, "output record ...\n"); __pmDumpResult(stderr, orp); } } #endif if (orp == NULL) goto next; /* * convert log record to a PDU, and enforce V2 encoding semantics, * then write it out */ sts = __pmEncodeResult(PDU_OVERRIDE2, orp, &pb); if (sts < 0) { fprintf(stderr, "%s: Error: __pmEncodeResult: %s\n", pmProgname, pmErrStr(sts)); goto cleanup; } /* switch volumes if required */ if (varg > 0) { if (written > 0 && (written % varg) == 0) { __pmTimeval next_stamp; next_stamp.tv_sec = irp->timestamp.tv_sec; next_stamp.tv_usec = irp->timestamp.tv_usec; newvolume(oname, &next_stamp); } } /* * Even without a -v option, we may need to switch volumes * if the data file exceeds 2^31-1 bytes */ peek_offset = ftell(logctl.l_mfp); peek_offset += ((__pmPDUHdr *)pb)->len - sizeof(__pmPDUHdr) + 2*sizeof(int); if (peek_offset > 0x7fffffff) { __pmTimeval next_stamp; next_stamp.tv_sec = irp->timestamp.tv_sec; next_stamp.tv_usec = irp->timestamp.tv_usec; newvolume(oname, &next_stamp); } current.tv_sec = orp->timestamp.tv_sec; current.tv_usec = orp->timestamp.tv_usec; doindom(orp); /* write out log record */ sts = __pmLogPutResult2(&logctl, pb); __pmUnpinPDUBuf(pb); if (sts < 0) { fprintf(stderr, "%s: Error: __pmLogPutResult2: log data: %s\n", pmProgname, pmErrStr(sts)); goto cleanup; } written++; rewrite_free(); next: pmFreeResult(irp); } /* write the last time stamp */ fflush(logctl.l_mfp); fflush(logctl.l_mdfp); __pmLogPutIndex(&logctl, ¤t); exit(exit_status); cleanup: { char fname[MAXNAMELEN]; fprintf(stderr, "Archive \"%s\" not created.\n", oname); snprintf(fname, sizeof(fname), "%s.0", oname); unlink(fname); snprintf(fname, sizeof(fname), "%s.meta", oname); unlink(fname); snprintf(fname, sizeof(fname), "%s.index", oname); unlink(fname); exit(1); } }