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.