void onTrace(ObjectMap::value_type ov, const qi::EventTrace& trace) { static qi::int64_t secStart = 0; if (!secStart && !full) secStart = trace.timestamp().tv_sec; static unsigned int maxLen = 0; std::string name = boost::lexical_cast<std::string>(trace.slotId()); if (!numeric) { qi::MetaObject mo = ov.second.metaObject(); qi::MetaMethod* m = mo.method(trace.slotId()); if (m) name = m->name(); else { qi::MetaSignal* s = mo.signal(trace.slotId()); if (s) name = s->name(); else name = name + "(??" ")"; // trigraph protect mode on } } if (!full && name.size() > 25) { name = name.substr(0, 22) + "..."; } std::string serviceName = ov.first; if (!full && serviceName.size() > 17) serviceName = serviceName.substr(0, 14) + "..."; maxLen = std::max(maxLen, (unsigned int)name.size()); unsigned int traceKind = trace.kind(); if (traceKind > 4) traceKind = 0; std::string spacing(maxLen + 2 - name.size(), ' '); std::string spacing2((full?maxServiceLength:17) + 2 - ov.first.size(), ' '); if (trace.kind() == qi::EventTrace::Event_Result || qi::EventTrace::Event_Error) { std::cout << serviceName << spacing2 << trace.id() << ' ' << ThreadFormat(trace.callerContext()) << ' ' << ThreadFormat(trace.calleeContext()) << ' ' << callType[traceKind] << ' ' << name << spacing << (trace.timestamp().tv_sec - secStart) << '.' << trace.timestamp().tv_usec << ' ' << trace.userUsTime() << ' ' << trace.systemUsTime() << ' ' << qi::encodeJSON(trace.arguments()) << std::endl; } else { std::cout << serviceName << spacing2 << trace.id() << ' ' << ThreadFormat(trace.callerContext()) << ' ' << ThreadFormat(trace.calleeContext()) << ' ' << callType[traceKind] << ' ' << name << spacing << (trace.timestamp().tv_sec - secStart) << '.' << trace.timestamp().tv_usec << ' ' << qi::encodeJSON(trace.arguments()) << std::endl; } }
void main_loop() { while (true) { unsigned int maxLen = 4; // Reset all counters for (auto& ov: objectMap) ov.second.call<void>("clearStats"); qi::os::msleep(interval * 1000); Stats stats; // Fetch stats from monitored objects and fill stats for(ObjectMap::value_type& ov: objectMap) { qi::ObjectStatistics os = ov.second.call<qi::ObjectStatistics>("stats"); const std::string& serviceName = ov.first; for(qi::ObjectStatistics::value_type& s: os) { if (s.first == 83) continue; // hide clearstats std::string name = boost::lexical_cast<std::string>(s.first); if (!numeric) { qi::MetaObject mo = ov.second.metaObject(); qi::MetaMethod* m = mo.method(s.first); if (m) name = m->name(); else { qi::MetaSignal* sig = mo.signal(s.first); if (sig) name = sig->name(); else name = name + "(??" ")"; // trigraph protect mode on } } maxLen = std::max(maxLen, (unsigned int)name.size()); stats.push_back(std::make_pair(std::make_pair(serviceName, name), s.second)); } } if (!full) maxLen = std::min(maxLen, 25u); // Now, sort std::sort(stats.begin(), stats.end(), StatCompare()); // display std::cout << "MODULE" << std::string(maxLen + 2 - 6, ' ') << "METHOD" << std::string((full?maxServiceLength:17) + 2 - 6, ' ') << " %CPU " << "COUNT " << "USER" << std::string(6*3 - 2, ' ') << "SYS " << std::string(6*3 - 2, ' ') << "WALL" << std::endl; for(const Stat& s: stats) { const qi::MethodStatistics& ms = s.second; std::string serviceName = s.first.first; std::string methodName = s.first.second; if (!full && serviceName.size() > 17) serviceName = serviceName.substr(0, 14) + "..."; if (!full && methodName.size() > 25) methodName = methodName.substr(0, 22) + "..."; std::string spacing(maxLen + 2 - methodName.size(), ' '); std::string spacing2((full?maxServiceLength:17) + 2 - serviceName.size(), ' '); std::cout << serviceName << spacing2 << methodName << spacing << std::setw(6) << (((ms.user().cumulatedValue() + ms.system().cumulatedValue()) * 100) / interval) << "% " << std::setw(3) << ms.count() << "x " << us(ms.user().cumulatedValue() / (float)ms.count()) << ' ' << us(ms.user().minValue()) << ' ' << us(ms.user().maxValue()) << " " << us(ms.system().cumulatedValue() / (float)ms.count()) << ' ' << us(ms.system().minValue()) << ' ' << us(ms.system().maxValue()) << " " << us(ms.wall().cumulatedValue() / (float)ms.count()) << ' ' << us(ms.wall().minValue()) << ' ' << us(ms.wall().maxValue()) << " " << std::endl; } } }