// // Requirement here is to merge in any event records that have // just arrived in the last timestep (from my.metric) with the // set already being displayed. // Additionally, we need to cull those that are no longer within // the time window of interest. // void TracingItem::updateValues(TracingEngine *engine, double left, double right) { QmcMetric *metric = ChartItem::my.metric; #if DESPERATE console->post(PmChart::DebugForce, "TracingItem::updateValues: " "%d total events, left=%.2f right=%.2f\n" "Metadata counts: drops=%d spans=%d points=%d " "Metric values: %d count\n", my.events.size(), left, right, my.drops.size(), my.spans.size(), my.points.size(), metric->numValues()); #endif cullOutlyingSpans(left, right); cullOutlyingDrops(left, right); cullOutlyingPoints(left, right); cullOutlyingEvents(left, right); // crack open newly arrived event records if (metric->numValues() > 0) updateEvents(engine, metric); // update the display my.dropCurve->setSamples(my.drops); my.spanCurve->setSamples(my.spans); my.pointCurve->setSamples(my.points); my.selectionCurve->setSamples(my.selections); }
QmcMetric * QmcGroup::addMetric(pmMetricSpec *theMetric, double theScale, bool active) { QmcMetric *metric = new QmcMetric(this, theMetric, theScale, active); if (metric->status() >= 0) metric->context()->addMetric(metric); return metric; }
QmcMetric * QmcGroup::addMetric(char const *string, double theScale, bool active) { QmcMetric *metric = new QmcMetric(this, string, theScale, active); if (metric->status() >= 0) metric->context()->addMetric(metric); return metric; }
static int traverse(const char *str, double scale) { pmMetricSpec *theMetric; char *msg; int sts = 0; sts = pmParseMetricSpec((char *)str, 0, (char *)0, &theMetric, &msg); if (sts < 0) { pmprintf("%s: Error: Unable to parse metric spec:\n%s\n", pmProgname, msg); free(msg); return sts; } // If the metric has instances, then it cannot be traversed if (theMetric->ninst) { QmcMetric *metric = group->addMetric(theMetric, scale); if (metric->status() >= 0) { checkUnits(metric); metrics.append(metric); numValues += metric->numValues(); } else sts = -1; } else { if (theMetric->isarch == 0) doMetricType = PM_CONTEXT_HOST; else if (theMetric->isarch == 1) doMetricType = PM_CONTEXT_ARCHIVE; else if (theMetric->isarch == 2) doMetricType = PM_CONTEXT_LOCAL; else { pmprintf("%s: Error: invalid metric source (%d): %s\n", pmProgname, theMetric->isarch, theMetric->metric); sts = -1; } doMetricSource = theMetric->source; if (sts >= 0) sts = group->use(doMetricType, doMetricSource); if (sts >= 0) { doMetricScale = scale; sts = pmTraversePMNS(theMetric->metric, dometric); if (sts >= 0 && doMetricFlag == false) sts = -1; else if (sts < 0) { pmprintf("%s: Error: %s: %s\n", pmProgname, theMetric->metric, pmErrStr(sts)); } } } free(theMetric); return sts; }
static void dometric(const char *name) { QString fullname = doMetricSource; if (fullname.length()) { if (doMetricType == PM_CONTEXT_ARCHIVE) fullname.append(QChar('/')); else fullname.append(QChar(':')); } fullname.append(name); QmcMetric* metric = group->addMetric((const char *)fullname.toAscii(), doMetricScale); if (metric->status() >= 0) { checkUnits(metric); metrics.append(metric); numValues += metric->numValues(); } else doMetricFlag = false; }
void SamplingItem::updateValues(bool forward, bool rateConvert, pmUnits *units, int sampleHistory, int, double, double, double) { pmAtomValue scaled, raw; QmcMetric *metric = ChartItem::my.metric; double value; int sz; if (metric->numValues() < 1 || metric->error(0)) { value = qQNaN(); } else { // convert raw value to current chart scale raw.d = rateConvert ? metric->value(0) : metric->currentValue(0); pmConvScale(PM_TYPE_DOUBLE, &raw, &ChartItem::my.units, &scaled, units); value = scaled.d * my.scale; } if (my.dataCount < sampleHistory) sz = qMax(0, (int)(my.dataCount * sizeof(double))); else sz = qMax(0, (int)((my.dataCount - 1) * sizeof(double))); if (forward) { memmove(&my.data[1], &my.data[0], sz); memmove(&my.itemData[1], &my.itemData[0], sz); my.data[0] = value; } else { memmove(&my.data[0], &my.data[1], sz); memmove(&my.itemData[0], &my.itemData[1], sz); my.data[my.dataCount - 1] = value; } if (my.dataCount < sampleHistory) my.dataCount++; }
void Launch::addMetric(const QmcMetric &metric, const SbColor &color, int instance, bool useSocks) { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { cerr << "Launch::addMetric(1): Adding "; metric.dump(cerr, true, instance); cerr << " (" << _metricCount << ')' << endl; } #endif QmcSource source = metric.context()->source(); QByteArray ba; ba = metric.instName(instance).toLocal8Bit(); addMetric(metric.context()->handle(), source.source(), source.host(), metric.name(), metric.hasInstances() == 0 ? NULL : ba.data(), metric.desc(), color, metric.scale(), useSocks); }
int QmcContext::fetch(bool update) { int i, sts; pmResult *result; for (i = 0; i < my.metrics.size(); i++) { QmcMetric *metric = my.metrics[i]; if (metric->status() < 0) continue; metric->shiftValues(); } // Inform each indom that we are about to do a new fetch so any // indom changes are now irrelevant for (i = 0; i < my.indoms.size(); i++) my.indoms[i]->newFetch(); sts = pmUseContext(my.context); if (sts >= 0) { for (i = 0; i < my.indoms.size(); i++) { if (my.indoms[i]->diffProfile()) sts = my.indoms[i]->genProfile(); } } else if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcContext::fetch: Unable to switch to this context: " << pmErrStr(sts) << endl; } if (sts >= 0 && my.needReconnect) { sts = pmReconnectContext(my.context); if (sts >= 0) { my.needReconnect = false; if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcContext::fetch: Reconnected context \"" << *my.source << endl; } } else if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcContext::fetch: Reconnect failed: " << pmErrStr(sts) << endl; } } if (sts >= 0 && my.pmids.size()) { if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcContext::fetch: fetching context " << *this << endl; } sts = pmFetch(my.pmids.size(), (pmID *)(my.pmids.toVector().data()), &result); if (sts >= 0) { my.previousTime = my.currentTime; my.currentTime = result->timestamp; my.delta = __pmtimevalSub(&my.currentTime, &my.previousTime); for (i = 0; i < my.metrics.size(); i++) { QmcMetric *metric = my.metrics[i]; if (metric->status() < 0) continue; Q_ASSERT((int)metric->idIndex() < result->numpmid); metric->extractValues(result->vset[metric->idIndex()]); } pmFreeResult(result); } else { if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcContext::fetch: pmFetch: " << pmErrStr(sts) << endl; } for (i = 0; i < my.metrics.size(); i++) { QmcMetric *metric = my.metrics[i]; if (metric->status() < 0) continue; metric->setError(sts); } if (sts == PM_ERR_IPC || sts == PM_ERR_TIMEOUT) my.needReconnect = true; } if (update) { if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcContext::fetch: Updating metrics" << endl; } for (i = 0; i < my.metrics.size(); i++) { QmcMetric *metric = my.metrics[i]; if (metric->status() < 0) continue; metric->update(); } } } else if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcContext::fetch: nothing to fetch" << endl; } return sts; }
static void dumpHeader() { static bool fullOnce = false; QmcMetric *metric; bool instFlag = false; QString noneStr = "none"; QString srcStr = "Source"; QString metricStr = "Metric"; QString instStr = "Inst"; QString normStr = "Normal"; QString unitStr = "Units"; QString columnStr = "Column"; const char *timeStr; int m; int i; int c; int v; int p; int len = 0; if (niceFlag) { struct timeval pos = { 0, 0 }; timeStr = dumpTime(pos); len = strlen(timeStr); } if (fullFlag) { fullOnce = true; for (m = 0, v = 1; m < metrics.size(); m++) { metric = metrics[m]; for (i = 0; i < metric->numValues(); i++, v++) { cout << '[' << qSetFieldWidth(2) << v << qSetFieldWidth(0) << "] " << metric->spec(sourceFlag, true, i) << endl; } } cout << endl; } if (fullOnce) { if (timeFlag) { if (len < columnStr.length()) { columnStr.remove(len, columnStr.length() - len); } cout << qSetFieldWidth(len) << columnStr << qSetFieldWidth(0) << delimiter; } for (m = 0, v = 1; m < metrics.size(); m++) { metric = metrics[m]; for (i = 0; i < metric->numValues(); i++) { cout << qSetFieldWidth(width) << v << qSetFieldWidth(0); if (v < numValues) { cout << delimiter; v++; } } } cout << endl; } if (niceFlag && sourceFlag) { if (timeFlag) { if (len < srcStr.length()) { srcStr.remove(len, srcStr.length() - len); } cout << qSetFieldWidth(len) << srcStr << qSetFieldWidth(0) << delimiter; } for (m = 0, v = 1; m < metrics.size(); m++) { metric = metrics[m]; QString const& str = metric->context()->source().host(); strncpy(buffer, (const char *)str.toAscii(), width); buffer[width] = '\0'; for (i = 0; i < metric->numValues(); i++) { cout << qSetFieldWidth(width) << buffer << qSetFieldWidth(0); if (v < numValues) { cout << delimiter; v++; } } } cout << endl; } if (metricFlag || (sourceFlag && !niceFlag)) { if (timeFlag) { if (niceFlag) { if (len < metricStr.length()) { metricStr.remove(len, metricStr.length() - len); } cout << qSetFieldWidth(len) << metricStr << qSetFieldWidth(0); cout << delimiter; } else cout << "Time" << delimiter; } for (m = 0, v = 1; m < metrics.size(); m++) { metric = metrics[m]; if (niceFlag && !instFlag && metric->hasInstances()) instFlag = true; for (i = 0; i < metric->numValues(); i++) { if (niceFlag) { QString const &str = metric->spec(false, false, i); p = str.length() - width; if (p > 0) { for (c = (p - 1 > 0 ? p - 1 : 0); c < str.length(); c++) { if (str[c] == '.') { c++; break; } } if (c < str.length()) cout << qSetFieldWidth(width) << ((const char *)str.toAscii() + c) << qSetFieldWidth(0); else cout << qSetFieldWidth(width) << ((const char *)str.toAscii() + p) << qSetFieldWidth(0); } else { cout << qSetFieldWidth(width) << str << qSetFieldWidth(0); } } else cout << metric->spec(sourceFlag, true, i); if (v < numValues) { cout << delimiter; v++; } } } cout << endl; } if (instFlag) { if (timeFlag) { if (niceFlag) { if (len < instStr.length()) { instStr.remove(len, instStr.length() - len); } cout << qSetFieldWidth(len) << instStr << qSetFieldWidth(0) << delimiter; } else { cout << qSetFieldWidth(len) << errStr << qSetFieldWidth(0) << delimiter; } } for (m = 0, v = 1; m < metrics.size(); m++) { metric = metrics[m]; for (i = 0; i < metric->numValues(); i++) { if (metric->hasInstances()) { QString const &str = metric->instName(i); strncpy(buffer, (const char *)str.toAscii(), width); buffer[width] = '\0'; cout << qSetFieldWidth(width) << buffer << qSetFieldWidth(0); } else cout << qSetFieldWidth(width) << "n/a" << qSetFieldWidth(0); if (v < numValues) { cout << delimiter; v++; } } } cout << endl; } if (normFlag) { if (timeFlag) { if (niceFlag) { if (len < normStr.length()) { normStr.remove(len, normStr.length() - len); } cout << qSetFieldWidth(len) << normStr << qSetFieldWidth(0) << delimiter; } else cout << errStr << delimiter; } for (m = 0, v = 1; m < metrics.size(); m++) { metric = metrics[m]; for (i = 0; i < metric->numValues(); i++) { if (shortFlag) cout << qSetRealNumberPrecision(precision) << qSetFieldWidth(width) << metric->scale() << qSetFieldWidth(0); else if (descFlag) cout << qSetFieldWidth(width) << QmcMetric::formatNumber(metric->scale()) << qSetFieldWidth(0); else cout << fixed << qSetRealNumberPrecision(precision) << qSetFieldWidth(width) << metric->scale() << qSetFieldWidth(0); if (v < numValues) { cout << delimiter; v++; } } } cout << endl; } if (unitFlag) { if (timeFlag) { if (niceFlag) { if (len < unitStr.length()) { unitStr.remove(len, unitStr.length() - len); } cout << qSetFieldWidth(len) << unitStr << qSetFieldWidth(0) << delimiter; } else cout << noneStr << delimiter; } for (m = 0, v = 1; m < metrics.size(); m++) { metric = metrics[m]; QString const &str = (niceFlag ? metric->desc().shortUnits() : metric->desc().units()); for (i = 0; i < metric->numValues(); i++) { if (niceFlag) if (str.length() > width) cout << qSetFieldWidth(width) << ((const char *)str.toAscii() + str.length() - width) << qSetFieldWidth(0); else cout << qSetFieldWidth(width) << str << qSetFieldWidth(0); else cout << str; if (v < numValues) { cout << delimiter; v++; } } } cout << endl; } }