void GroupControl::updateTimeAxis(void) { QString tz, otz, unused; if (numContexts() > 0 || isArchiveSource() == false) { if (numContexts() > 0) defaultTZ(unused, otz); else otz = QmcSource::localHost; tz = otz; pmchart->timeAxis()->setAxisScale(QwtPlot::xBottom, my.timeData[my.visible - 1], my.timeData[0], pmchart->timeAxis()->scaleValue(my.realDelta, my.visible)); pmchart->setDateLabel(my.position.tv_sec, tz); pmchart->timeAxis()->replot(); } else { pmchart->timeAxis()->noArchiveSources(); pmchart->setDateLabel(tr("[No open archives]")); } if (console->logLevel(PmChart::DebugProtocol)) { int i = my.visible - 1; console->post(PmChart::DebugProtocol, "GroupControl::updateTimeAxis: tz=%s; visible points=%d", (const char *)tz.toLatin1(), i); console->post(PmChart::DebugProtocol, "GroupControl::updateTimeAxis: first time is %.3f (%s)", my.timeData[i], timeString(my.timeData[i])); console->post(PmChart::DebugProtocol, "GroupControl::updateTimeAxis: final time is %.3f (%s)", my.timeData[0], timeString(my.timeData[0])); } }
int QmcGroup::useDefault() { if (numContexts() == 0) createLocalContext(); if (numContexts() == 0) return my.localSource->status(); my.use = 0; return pmUseContext(context()->handle()); }
int QmcGroup::setArchiveMode(int mode, const struct timeval *when, int interval) { int sts, result = 0; for (unsigned int i = 0; i < numContexts(); i++) { if (my.contexts[i]->source().type() != PM_CONTEXT_ARCHIVE) continue; sts = pmUseContext(my.contexts[i]->handle()); if (sts < 0) { pmprintf("%s: Error: Unable to switch to context for %s: %s\n", pmProgname, my.contexts[i]->source().sourceAscii(), pmErrStr(sts)); result = sts; continue; } sts = pmSetMode(mode, when, interval); if (sts < 0) { pmprintf("%s: Error: Unable to set context mode for %s: %s\n", pmProgname, my.contexts[i]->source().sourceAscii(), pmErrStr(sts)); result = sts; } } sts = useContext(); if (sts < 0) result = sts; return result; }
void QmcGroup::dump(QTextStream &stream) { stream << "mode: "; switch(my.mode) { case PM_CONTEXT_LOCAL: stream << "local"; break; case PM_CONTEXT_HOST: stream << "live host"; break; case PM_CONTEXT_ARCHIVE: stream << "archive"; break; } stream << ", timezone: "; switch(my.tzFlag) { case QmcGroup::localTZ: stream << "local = \"" << tzLocalString; break; case QmcGroup::userTZ: stream << "user = \"" << my.tzUserString; break; case QmcGroup::groupTZ: stream << "group = \"" << my.contexts[my.tzGroupIndex]->source().timezone(); break; case QmcGroup::unknownTZ: stream << "unknown = \"???"; break; } stream << "\": " << endl; stream << " " << numContexts() << " contexts:" << endl; for (unsigned int i = 0; i < numContexts(); i++) { stream << " [" << i << "] " << *(my.contexts[i]) << endl; my.contexts[i]->dumpMetrics(stream); } }
int QmcGroup::fetch(bool update) { int sts = 0; if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::fetch: " << numContexts() << " contexts" << endl; } for (unsigned int i = 0; i < numContexts(); i++) my.contexts[i]->fetch(update); if (numContexts()) sts = useContext(); if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::fetch: Done" << endl; } return sts; }
void QmcGroup::updateBounds() { double newStart = DBL_MAX; double newEnd = 0.0; double startReal; double endReal; struct timeval startTv; struct timeval endTv; my.timeStart.tv_sec = 0; my.timeStart.tv_usec = 0; my.timeEnd = my.timeStart; for (unsigned int i = 0; i < numContexts(); i++) { if (my.contexts[i]->handle() >= 0 && my.contexts[i]->source().type() == PM_CONTEXT_ARCHIVE) { startTv = my.contexts[i]->source().start(); endTv = my.contexts[i]->source().end(); startReal = __pmtimevalToReal(&startTv); endReal = __pmtimevalToReal(&endTv); if (startReal < newStart) newStart = startReal; if (endReal > newEnd) newEnd = endReal; } } __pmtimevalFromReal(newStart, &my.timeStart); __pmtimevalFromReal(newEnd, &my.timeEnd); my.timeEndReal = newEnd; if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::updateBounds: start = " << my.timeStart.tv_sec << '.' << my.timeStart.tv_usec << ", end = " << my.timeEnd.tv_sec << '.' << my.timeEnd.tv_usec << endl; } }
void QmcGroup::createLocalContext() { if (numContexts() == 0) { QTextStream cerr(stderr); QmcSource *localSource = QmcSource::getSource(PM_CONTEXT_HOST, localHost, 0, false); if (localSource->status() < 0 && pmDebug & DBG_TRACE_PMC) cerr << "QmcGroup::createLocalContext: Default context to " << localSource->desc() << " failed: " << pmErrStr(localSource->status()) << endl; else if (pmDebug & DBG_TRACE_PMC) cerr << "QmcGroup::createLocalContext: Default context to " << localSource->desc() << endl; QmcContext *newContext = new QmcContext(localSource); if (newContext->handle() < 0) { pmprintf("%s: Error: %s: %s\n", pmProgname, (const char *)localHost.toAscii(), pmErrStr(newContext->handle())); } my.contexts.append(newContext); my.use = my.contexts.size() - 1; } }
int QmcGroup::use(int type, const QString &theSource, int flags) { int sts = 0; unsigned int i; QString source(theSource); if (type == PM_CONTEXT_LOCAL) { for (i = 0; i < numContexts(); i++) if (my.contexts[i]->source().type() == type) break; } else if (type == PM_CONTEXT_ARCHIVE) { if (source == QString::null) { pmprintf("%s: Error: Archive context requires archive path\n", pmProgname); return PM_ERR_NOCONTEXT; } // This doesn't take into account {.N,.meta,.index,} ... but // then again, nor does pmNewContext. More work ... useful? for (i = 0; i < numContexts(); i++) { if (source == my.contexts[i]->source().source()) break; } } else { if (source == QString::null) { if (!defaultDefined()) { createLocalContext(); if (!defaultDefined()) { pmprintf("%s: Error: " "Cannot connect to PMCD on localhost: %s\n", pmProgname, pmErrStr(my.localSource->status())); return my.localSource->status(); } } source = my.contexts[0]->source().source(); } for (i = 0; i < numContexts(); i++) { if (source == my.contexts[i]->source().source()) break; } } if (i == numContexts()) { if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: No direct match for context \"" << source << "\" (type " << type << ")." << endl; } // Determine live or archive mode by the first source if (i == 0) my.mode = type; // If the assumed mode differs from the requested context type // we may need to map the host to an archive if (my.mode != type) { if (my.mode == PM_CONTEXT_HOST && type == PM_CONTEXT_ARCHIVE) { pmprintf("%s: Error: Archive \"%s\" requested " "after live mode was assumed.\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOCONTEXT; } // If we are in archive mode, map hosts to archives of same host if (my.mode == PM_CONTEXT_ARCHIVE && type == PM_CONTEXT_HOST) { QString chop1 = source.remove(PM_LOG_MAXHOSTLEN-1, INT_MAX); for (i = 0; i < numContexts(); i++) { QString chop2 = my.contexts[i]->source().host(); chop2.remove(PM_LOG_MAXHOSTLEN-1, INT_MAX); if (chop1 == chop2) break; } if (i == numContexts()) { pmprintf("%s: Error: No archives were specified " "for host \"%s\"\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOTARCHIVE; } } } } if (i == numContexts()) { if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Creating new context for \"" << source << '\"' << endl; } QmcSource *src = QmcSource::getSource(type, source, flags, false); if (src == NULL) { pmprintf("%s: Error: No archives were specified for host \"%s\"\n", pmProgname, (const char *)source.toAscii()); return PM_ERR_NOTARCHIVE; } QmcContext *newContext = new QmcContext(src); if (newContext->handle() < 0) { sts = newContext->handle(); pmprintf("%s: Error: %s: %s\n", pmProgname, (const char *)source.toAscii(), pmErrStr(sts)); delete newContext; return sts; } // If we are in archive mode and are adding an archive, // make sure another archive for the same host does not exist if (my.restrictArchives && type == PM_CONTEXT_ARCHIVE) { for (i = 0; i < numContexts(); i++) // No need to restrict comparison here, both are from // log labels. if (my.contexts[i]->source().host() == newContext->source().host()) { pmprintf("%s: Error: Archives \"%s\" and \"%s\" are from " "the same host \"%s\"\n", pmProgname, my.contexts[i]->source().sourceAscii(), newContext->source().sourceAscii(), my.contexts[i]->source().hostAscii()); delete newContext; return PM_ERR_NOCONTEXT; } } my.contexts.append(newContext); my.use = my.contexts.size() - 1; if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Added context " << my.use << ": " << *newContext << endl; } } // We found a match, do we need to use a different context? else if (i != (unsigned int)my.use) { my.use = i; sts = useContext(); if (sts < 0) { pmprintf("%s: Error: Unable to use context to %s: %s\n", pmProgname, context()->source().sourceAscii(), pmErrStr(sts)); return sts; } if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Using existing context " << my.use << " for " << context()->source().desc() << endl; } } else if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcGroup::use: Using current context " << my.use << " (handle = " << context()->handle() << ") for " << context()->source().desc() << endl; } return context()->handle(); }