#include #include #include #include #include #include #include #include #include #include "JSystem/JShell.hh" #include "Jeep/JPrint.hh" #include "Jeep/JParser.hh" #include "Jeep/JMessage.hh" namespace { struct zbuf : std::filebuf { void rewind() { std::filebuf::seekpos(0, std::ios_base::out); } }; } /** * \file * * Auxiliary program to continually monitor processes. * \author mdejong */ int main(int argc, char **argv) { using namespace std; using namespace JPP; vector process; string outputFile; unsigned int T_us; long int prescale; string master; int debug; try { JParser<> zap("Auxiliary program to continually monitor processes."); zap['P'] = make_field(process, "name of process"); zap['o'] = make_field(outputFile, "output file") = ""; zap['T'] = make_field(T_us, "interval time [us]") = 1000; zap['n'] = make_field(prescale, "pre-scale for logging") = 1000; zap['M'] = make_field(master, "stop when master does") = ""; zap['d'] = make_field(debug) = 1; zap(argc, argv); } catch(const exception &error) { FATAL(error.what() << endl); } if (process.empty()) { FATAL("No process." << endl); } JShell shell; string ps; { ostringstream os; os << "ps -o comm= -o pid="; for (vector::const_iterator i = process.begin(); i != process.end(); ++i) { os << " -C " << *i; } if (master != "") { os << " -C " << master; } ps = os.str(); DEBUG(ps << endl); } zbuf buffer; if (outputFile != "") { buffer.open(outputFile.c_str(), ios::out); } ostream os(outputFile != "" ? &buffer : cout.rdbuf()); enum { UNDEFINED = 0, STOPPED = +1, RUNNING = +2 }; int monitor = (master != "" ? UNDEFINED : RUNNING); const auto start = chrono::system_clock::now(); map top; for (long int count = 1; monitor != STOPPED; usleep(T_us)) { if (master != "" && monitor == RUNNING) { monitor = STOPPED; } shell << ps << endl; for (string buffer; shell.getline(buffer); ) { string command; int pid; istringstream is(buffer); if (is >> command >> pid) { top[command] += 1; if (command == master) { monitor = RUNNING; } } else { ERROR("Error reading \"" << buffer << "\"" << endl); } } if (monitor == RUNNING) { ++count; } if (count%prescale == 0) { buffer.rewind(); os << "top " << FIXED(9,1) << chrono::duration(chrono::system_clock::now() - start).count() << " [s]" << endl; long int total = 0; for (vector::const_iterator i = process.begin(); i != process.end(); ++i) { const long int value = top[*i]; os << setw(24) << left << *i << ' ' << FIXED(5,3) << (double) value / (double) count << endl; total += value; } { os << setw(24) << left << "Total" << ' ' << FIXED(5,3) << (double) total / (double) count << endl; } } } buffer.close(); }