31{
   34 
   37  unsigned int   T_us;
   38  long int       prescale;
   39  string         master;
   41 
   42  try {
   43 
   44    JParser<> zap(
"Auxiliary program to continually monitor processes.");
 
   45 
   46    zap[
'P'] = 
make_field(process,     
"name of process");
 
   48    zap[
'T'] = 
make_field(T_us,        
"interval time [us]")    =  1000;
 
   49    zap[
'n'] = 
make_field(prescale,    
"pre-scale for logging") =  1000;
 
   50    zap[
'M'] = 
make_field(master,      
"stop when master does") =  
"";
 
   52 
   53    zap(argc, argv);
   54  }
   55  catch(const exception &error) {
   56    FATAL(error.what() << endl);
 
   57  }
   58 
   59  if (process.empty()) {
   60    FATAL(
"No process." << endl);
 
   61  }
   62  
   64  string ps;
   65  {
   66    ostringstream os;
   67 
   68    os << "ps -o comm= -o pid=";
   69 
   70    for (vector<string>::const_iterator i = process.begin(); i != process.end(); ++i) {
   71      os << " -C " << *i;
   72    }
   73 
   74    if (master != "") {
   75      os << " -C " << master;
   76    }
   77 
   78    ps = os.str();
   79 
   81  }
   82 
   83  zbuf buffer;
   84 
   87  }
   88 
   89  ostream os(
outputFile != 
"" ? &buffer : cout.rdbuf());
 
   90 
   91  enum {
   93    STOPPED   = +1,
   94    RUNNING   = +2
   95  };
   96  
   98 
   99  const auto start = chrono::system_clock::now();
  100  
  102 
  103  for (
long int count = 1; 
monitor != STOPPED; usleep(T_us)) {
 
  104 
  105    if (master != 
"" && 
monitor == RUNNING) {
 
  107    }
  108 
  109    shell << ps << endl;
  110 
  111    for (
string buffer; shell.
getline(buffer); ) {
 
  112 
  113      string command;
  114      int    pid;
  115      
  116      istringstream is(buffer);
  117 
  118      if (is >> command >> pid) {
  119 
  120        top[command] += 1;
  121 
  122        if (command == master) {
  124        }
  125        
  126      } else {
  127 
  128        ERROR(
"Error reading \"" << buffer << 
"\"" << endl);
 
  129      }
  130    }
  131 
  133      ++count;
  134    }
  135 
  136    if (count%prescale == 0) {
  137 
  138      buffer.rewind();
  139      
  140      os << 
"top " << 
FIXED(9,1) << chrono::duration<double>(chrono::system_clock::now() - start).count() << 
" [s]" << endl;
 
  141 
  142      long int total  = 0;
  143 
  144      for (vector<string>::const_iterator i = process.begin(); i != process.end(); ++i) {
  145        
  146        const long int value = top[*i];
  147 
  148        os << setw(24) << left << *i      << 
' ' << 
FIXED(5,3) << (double) value / (
double) count << endl;
 
  149 
  150        total += value;
  151      }
  152      {
  153        os << setw(24) << left << 
"Total" << 
' ' << 
FIXED(5,3) << (double) total / (
double) count << endl;
 
  154      }
  155    }
  156  }
  157 
  158  buffer.close();
  159}
#define DEBUG(A)
Message macros.
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
 
Utility class to parse command line options.
 
The JShell clas can be used to interact with the shell via I/O streams.
 
bool getline(std::string &buffer, const char eol='\n')
Get line of text.
 
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
 
Auxiliary data structure for floating point format specification.