#include "piintrospector.h" #include "ccm_piintrospector.h" #include "pichunkstream.h" #include "pidir.h" #include "pifile.h" #include "pitime.h" #include #include QPIIntrospector::QPIIntrospector(QWidget * parent): EMainWindow(parent), peer("__introspection_client__") { setupUi(this); request_timer = 0; session.setFile("qpiintrospector_session.conf"); #if QT_VERSION >= 0x050000 // treeContainers->header()->setSectionResizeMode(QHeaderView::ResizeToContents); #else // treeContainers->header()->setResizeMode(QHeaderView::ResizeToContents); #endif CONNECTU_QUEUED(&peer, peerConnectedEvent, this, peersChanged, this); CONNECTU_QUEUED(&peer, peerDisconnectedEvent, this, peersChanged, this); CONNECTU_QUEUED(&peer, dataReceivedEvent, this, peerReceived, this); // CONNECTU(&peer, peerConnectedEvent, this, reqProcPIEvents); // CONNECTU(&peer, peerDisconnectedEvent, this, reqProcPIEvents); // CONNECTU(&peer, dataReceivedEvent, this, reqProcPIEvents); session.addEntry(this); session.addEntry(tabWidgetMain); PICodeInfo::EnumInfo * ei = PICODEINFO->enums().value("PIIntrospection::InfoTypes"); if (ei) { piForeachC(PICodeInfo::EnumeratorInfo & e, ei->members) { #if PIP_VERSION >= PIP_MAKE_VERSION(2, 39, 0) QCheckBox * cb = new QCheckBox(PI2QString(e.name.mid(2).toString())); #else QCheckBox * cb = new QCheckBox(PI2QString(e.name.mid(2))); #endif cb->setObjectName(QString("checkRequest%1").arg(e.value)); cb->setProperty("__value__", e.value); layoutRequestFlags->addWidget(cb); session.addEntry(cb); } } pip_timer = startTimer(10); session.load(); peer.start(); } QPIIntrospector::~QPIIntrospector() { session.save(); peer.stop(); } void QPIIntrospector::changeEvent(QEvent * e) { EMainWindow::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: retranslateUi(this); break; default: break; } } void QPIIntrospector::timerEvent(QTimerEvent * e) { if (e->timerId() == pip_timer) callQueuedEvents(); if (e->timerId() == request_timer) buttonRequest->click(); } void QPIIntrospector::savingSession(QPIConfig & conf) { conf.setValue("treeStat_header", treeStat->header()->saveState()); } void QPIIntrospector::loadingSession(QPIConfig & conf) { treeStat->header()->restoreState(conf.getValue("treeStat_header").toByteArray()); } void QPIIntrospector::buildTree(QByteArray d) { /*PIVector threads; PIByteArray pd = Q2PIByteArray(d); pd >> threads; treeContainers->clear(); piForeachC (PIIntrospectionThreads::ThreadInfo & t, threads) { QTreeWidgetItem * ti = new QTreeWidgetItem(); ti->setText(0, QString(PI2QString(t.name) + " (%1)").arg(t.id)); treeContainers->addTopLevelItem(ti); }*/ } void QPIIntrospector::procRequestTimer() { if (request_timer != 0) killTimer(request_timer); request_timer = 0; if (!checkRequestTimer->isChecked()) return; request_timer = startTimer(1000 / spinRequestTimerHz->value()); } void QPIIntrospector::buildDumpSection(QTreeWidgetItem * pi, PIString & str) {} void QPIIntrospector::showInfo() { PIString s; s += info.execCommand + "\n"; s += info.execDateTime.toString() + "\n"; s += info.OS_name + "(" + info.OS_version + ", " + info.architecture + ")\n"; s += info.user + "\n"; s += info.build_options.join(", ") + "\n"; s += "\n"; s += "load k: " + PIString::fromNumber(stat.proc.cpu_load_system, 'f', 2) + " %\n"; s += "load u: " + PIString::fromNumber(stat.proc.cpu_load_user, 'f', 2) + " %\n"; s += "threads: " + PIString::fromNumber(stat.proc.threads) + "\n"; s += "memory usage: " + stat.proc.physical_memsize_readable; labelInfo->setText(PI2QString(s)); int tlic = treeStat->topLevelItemCount(); for (int i = tlic; i < stat.threads.size_s(); ++i) treeStat->addTopLevelItem(new QTreeWidgetItem()); for (int i = tlic - 1; i >= stat.threads.size_s(); --i) delete treeStat->topLevelItem(i); tlic = piMini(treeStat->topLevelItemCount(), stat.threads.size_s()); for (int i = 0; i < tlic; ++i) { QTreeWidgetItem * ti = treeStat->topLevelItem(i); PISystemMonitor::ThreadStats & ts(stat.threads[i]); ti->setText(0, QString::number(i + 1)); ti->setText(1, QString::number(ts.id)); ti->setText(2, PI2QString(ts.name)); ti->setText(3, durationStr(ts.work_time)); ti->setText(4, QString::number(ts.cpu_load_kernel, 'f', 2)); ti->setText(5, QString::number(ts.cpu_load_user, 'f', 2)); } } QString QPIIntrospector::durationStr(PISystemTime t) { QString ret; double s = t.toSeconds(); int d, h, m; d = piFloor(s / (24 * 60 * 60)); if (d > 0) { ret += QString::number(d) + " d "; s -= d * (24 * 60 * 60); } h = piFloor(s / (60 * 60)); if (h > 0) { ret += QString::number(h) + " h "; s -= h * (60 * 60); } m = piFloor(s / 60); if (m > 0) { ret += QString::number(m).rightJustified(2, '0') + " m "; s -= m * 60; } ret += QString::number(piFloor(s)).rightJustified(2, '0') + " s"; return ret; } #if PIP_VERSION >= PIP_MAKE_VERSION(2, 35, 0) void QPIIntrospector::prepareContainers(PIVector & data) { for (PIIntrospectionContainers::TypeInfo & i: data) { i.allocated_bytes = i.allocated * i.item_size; i.used_bytes = i.used * i.item_size; i.item_size_str.setReadableSize(i.item_size); i.allocated_str.setReadableSize(i.allocated_bytes); i.used_str.setReadableSize(i.used_bytes); } } #endif void QPIIntrospector::on_listApp_currentRowChanged(int r) { PIString cs; if (r < 0) cs.clear(); else cs = Q2PIString(listApp->item(r)->data(Qt::UserRole).toString()); if (cur_server != cs) widgetContainers->clear(); cur_server = cs; } void QPIIntrospector::peerReceived(const PIString & from, const PIByteArray & data) { if (from != cur_server) return; // piCout << "rec" << data.size(); PIByteArray ba(data); if (ba.size_s() < 4) return; uint sign(0); ba >> sign; if (sign != PIIntrospection::sign) return; PIChunkStream cs(ba); PIByteArray pba; while (!cs.atEnd()) { switch (cs.read()) { case PIIntrospection::itInfo: { pba.clear(); cs.get(pba); PIIntrospection::unpackInfo(pba, info); } break; case PIIntrospection::itProcStat: { pba.clear(); cs.get(pba); PIIntrospection::unpackProcStat(pba, stat); widgetThreads->setStat(stat.threads); // showInfo(info); } break; case PIIntrospection::itContainers: { pba.clear(); cs.get(pba); PIVector data; PIIntrospection::unpackContainers(pba, data); #if PIP_VERSION >= PIP_MAKE_VERSION(2, 35, 0) prepareContainers(data); #endif widgetContainers->showContainers(data); } break; case PIIntrospection::itObjects: { pba.clear(); cs.get(pba); PIVector objects; PIIntrospection::unpackObjects(pba, objects); widgetObjects->showObjects(objects); } break; case PIIntrospection::itThreads: { pba.clear(); cs.get(pba); PIVector threads; PIIntrospection::unpackThreads(pba, threads); widgetThreads->showThreads(threads); } break; default: break; } } showInfo(); } void QPIIntrospector::peersChanged(const PIString & name) { static QString tag = "__introspection__server_"; listApp->blockSignals(true); QString cs = listApp->currentItem() ? listApp->currentItem()->text() : ""; listApp->clear(); peer.lock(); piForeachC(PIPeer::PeerInfo & p, peer.allPeers()) { QString pn = PI2QString(p.name); if (!pn.contains(tag)) continue; QListWidgetItem * li = new QListWidgetItem(pn.left(pn.indexOf(tag))); li->setData(Qt::UserRole, pn); listApp->addItem(li); if (pn == cs) listApp->setCurrentRow(listApp->count() - 1); } peer.unlock(); listApp->blockSignals(false); } void QPIIntrospector::on_buttonRequest_clicked() { if (cur_server.isEmpty()) return; PIIntrospection::RequiredInfo info; for (int i = 0; i < layoutRequestFlags->count(); ++i) { QCheckBox * cb = qobject_cast(layoutRequestFlags->itemAt(i)->widget()); if (!cb) continue; if (!cb->isChecked()) continue; info.types |= cb->property("__value__").toInt(); } PIByteArray ba; ba << PIIntrospection::sign << info; peer.send(cur_server, ba); }