Beispiel #1
0
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]));
    }
}
Beispiel #2
0
int
QmcGroup::useDefault()
{
    if (numContexts() == 0)
	createLocalContext();
    if (numContexts() == 0)
	return my.localSource->status();
    my.use = 0;
    return pmUseContext(context()->handle());
}
Beispiel #3
0
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;
}
Beispiel #4
0
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);
    }
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
    }
}
Beispiel #7
0
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;
    }
}
Beispiel #8
0
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();
}