#include "piintrospector.h" #include #include #include "pifile.h" #include "pitime.h" #include "pidir.h" #include "pichunkstream.h" #include "ccm_piintrospector.h" 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::enumsInfo->value("PIIntrospection::InfoTypes"); if (ei) { piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) { QCheckBox * cb = new QCheckBox(PI2QString(e.name.mid(2))); 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: " << 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; } 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); 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); }