Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
process-state-info.cc
Go to the documentation of this file.
1 // Copyright 2015 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
17 #include <stdlib.h>
18 #include <unistd.h>
19 
20 #include <iostream>
21 #include <fstream>
22 #include <sstream>
23 #include <boost/algorithm/string.hpp>
24 #include <gutil/strings/substitute.h>
25 
26 #include "util/pretty-printer.h"
27 #include "util/debug-util.h"
28 #include "util/string-parser.h"
29 
30 #include "common/names.h"
31 
32 using boost::algorithm::is_any_of;
33 using boost::algorithm::join;
34 using boost::algorithm::split;
35 using boost::algorithm::token_compress_on;
36 using boost::algorithm::trim;
37 
38 using namespace strings;
39 
40 namespace impala {
41 
42 int ProcessStateInfo::GetInt(const string& state_key) const {
43  ProcessStateMap::const_iterator it = process_state_map_.find(state_key);
44  if (it != process_state_map_.end()) return atoi(it->second.c_str());
45  return -1;
46 }
47 
48 int64_t ProcessStateInfo::GetInt64(const string& state_key) const {
49  ProcessStateMap::const_iterator it = process_state_map_.find(state_key);
50  if (it != process_state_map_.end()) {
52  int64_t state_value = StringParser::StringToInt<int64_t>(it->second.data(),
53  it->second.size(), &result);
54  if (result == StringParser::PARSE_SUCCESS) return state_value;
55  }
56  return -1;
57 }
58 
59 string ProcessStateInfo::GetString(const string& state_key) const {
60  ProcessStateMap::const_iterator it = process_state_map_.find(state_key);
61  if (it != process_state_map_.end()) return it->second;
62  return string();
63 }
64 
65 int64_t ProcessStateInfo::GetBytes(const string& state_key) const {
66  ProcessStateMap::const_iterator it = process_state_map_.find(state_key);
67  if (it != process_state_map_.end()) {
68  vector<string> fields;
69  split(fields, it->second, is_any_of(" "), token_compress_on);
70  // We expect state_value such as, e.g., '16129508', '16129508 kB', '16129508 mB'
72  int64_t state_value = StringParser::StringToInt<int64_t>(fields[0].data(),
73  fields[0].size(), &result);
74  if (result == StringParser::PARSE_SUCCESS) {
75  if (fields.size() < 2) return state_value;
76  if (fields[1].compare("kB") == 0) return state_value * 1024L;
77  }
78  }
79  return -1;
80 }
81 
82 void ProcessStateInfo::ReadProcIO() {
83  const string& path = Substitute("/proc/$0/io", getpid());
84  ifstream ioinfo(path.c_str(), ios::in);
85  string line;
86  while (ioinfo.good() && !ioinfo.eof()) {
87  getline(ioinfo, line);
88  vector<string> fields;
89  split(fields, line, is_any_of(" "), token_compress_on);
90  if (fields.size() < 2) continue;
91  string key = fields[0].substr(0, fields[0].size() - 1);
92  process_state_map_[Substitute("io/$0", key)] = fields[1];
93  }
94 
95  if (ioinfo.is_open()) ioinfo.close();
96 }
97 
98 void ProcessStateInfo::ReadProcCgroup() {
99  const string& path = Substitute("/proc/$0/cgroup", getpid());
100  ifstream cgroupinfo(path.c_str(), ios::in);
101  string line;
102  while (cgroupinfo.good() && !cgroupinfo.eof()) {
103  getline(cgroupinfo, line);
104  vector<string> fields;
105  split(fields, line, is_any_of(":"), token_compress_on);
106  if (fields.size() < 3) continue;
107  process_state_map_["cgroup/hierarchy_id"] = fields[0];
108  process_state_map_["cgroup/subsystems"] = fields[1];
109  process_state_map_["cgroup/control_group"] = fields[2];
110  break;
111  }
112 
113  if (cgroupinfo.is_open()) cgroupinfo.close();
114 }
115 
116 void ProcessStateInfo::ReadProcSched() {
117  const string& path = Substitute("/proc/$0/sched", getpid());
118  ifstream schedinfo(path.c_str(), ios::in);
119  string line;
120  while (schedinfo.good() && !schedinfo.eof()) {
121  getline(schedinfo, line);
122  vector<string> fields;
123  split(fields, line, is_any_of(":"), token_compress_on);
124  if (fields.size() < 2) continue;
125  trim(fields[0]);
126  trim(fields[1]);
127  process_state_map_[Substitute("sched/$0", fields[0])] = fields[1];
128  }
129 
130  if (schedinfo.is_open()) schedinfo.close();
131 }
132 
133 void ProcessStateInfo::ReadProcStatus() {
134  const string& path = Substitute("/proc/$0/status", getpid());
135  ifstream statusinfo(path.c_str(), ios::in);
136  string line;
137  while (statusinfo.good() && !statusinfo.eof()) {
138  getline(statusinfo, line);
139  vector<string> fields;
140  split(fields, line, is_any_of("\t"), token_compress_on);
141  if (fields.size() < 2) continue;
142  trim(fields[1]);
143  string key = fields[0].substr(0, fields[0].size() - 1);
144  process_state_map_[Substitute("status/$0", key)] = fields[1];
145  }
146 
147  if (statusinfo.is_open()) statusinfo.close();
148 }
149 
150 void ProcessStateInfo::ReadProcFileDescriptorInfo() {
151  const string& command = Substitute("ls -l /proc/$0/fd | awk '{print $$(NF-2), $$NF}'",
152  getpid());
153  FILE* fp = popen(command.c_str(), "r");
154  if (fp) {
155  int max_buffer = 1024;
156  char buf[max_buffer];
157  while (!feof(fp)) {
158  if (fgets(buf, max_buffer, fp) != NULL) {
159  string line;
160  line.append(buf);
161  vector<string> fields;
162  split(fields, line, is_any_of(" "), token_compress_on);
163  if (fields.size() < 2) continue;
164  fd_desc_[atoi(fields[0].c_str())] = fields[1];
165  }
166  }
167  pclose(fp);
168  }
169 }
170 
171 ProcessStateInfo::ProcessStateInfo() {
172  ReadProcIO();
173  ReadProcCgroup();
174  ReadProcSched();
175  ReadProcStatus();
176  ReadProcFileDescriptorInfo();
177 }
178 
180  stringstream stream;
181  stream << "Process State: " << endl
182  << " I/O: " << endl
183  << " Read: "
184  << PrettyPrinter::Print(GetBytes("io/read_bytes"), TUnit::BYTES) << endl
185  << " Write: "
186  << PrettyPrinter::Print(GetBytes("io/write_bytes"), TUnit::BYTES) << endl
187  << " Read I/O: " << GetInt64("io/syscr") << endl
188  << " Write I/O: " << GetInt64("io/syscw") << endl
189  << " CGroups: " << endl
190  << " Hierarchy: " << GetString("cgroup/hierarchy_id") << endl
191  << " Subsystems: " << GetString("cgroup/subsystems") <<endl
192  << " Control Group: " << GetString("cgroup/control_group") << endl
193  << " Schedule: " << endl
194  << " Sum Execute Time: " << GetString("sched/se.sum_exec_runtime") << endl
195  << " Max Wait Time: " << GetString("sched/se.statistics.wait_max") << endl
196  << " Sum Wait Time: " << GetString("sched/se.statistics.wait_sum") << endl
197  << " Wait Count: " << GetInt64("sched/se.statistics.wait_count") << endl
198  << " Sum I/O Wait Time: "
199  << GetString("sched/se.statistics.iowait_sum") << endl
200  << " I/O Wait Count: "
201  << GetInt64("sched/se.statistics.iowait_count") << endl
202  << " Wakeup Count with cpu migration: "
203  << GetInt64("sched/se.statistics.nr_wakeups_migrate") << endl
204  << " Switches: " << GetInt64("sched/nr_switches") << endl
205  << " Voluntary Switches: " << GetInt("sched/nr_voluntary_switches") << endl
206  << " Involuntary Switches: "
207  << GetInt("sched/nr_involuntary_switches") << endl
208  << " Process Priority: " << GetInt("sched/prio") << endl
209  << " Status: " << endl
210  << " Process ID: " << getpid() << endl
211  << " Thread Number: " << GetInt("status/Threads") << endl
212  << " VM Peak: "
213  << PrettyPrinter::Print(GetBytes("status/VmPeak"), TUnit::BYTES) << endl
214  << " VM Size: "
215  << PrettyPrinter::Print(GetBytes("status/VmSize"), TUnit::BYTES) << endl
216  << " VM Lock: "
217  << PrettyPrinter::Print(GetBytes("status/VmLck"), TUnit::BYTES) << endl
218  << " VM Pin: "
219  << PrettyPrinter::Print(GetBytes("status/VmPin"), TUnit::BYTES) << endl
220  << " VM HWM: "
221  << PrettyPrinter::Print(GetBytes("status/VmHWM"), TUnit::BYTES) << endl
222  << " VM RSS: "
223  << PrettyPrinter::Print(GetBytes("status/VmRSS"), TUnit::BYTES) << endl
224  << " VM Data: "
225  << PrettyPrinter::Print(GetBytes("status/VmData"), TUnit::BYTES) << endl
226  << " VM Stk: "
227  << PrettyPrinter::Print(GetBytes("status/VmStk"), TUnit::BYTES) << endl
228  << " VM Exe: "
229  << PrettyPrinter::Print(GetBytes("status/VmExe"), TUnit::BYTES) << endl
230  << " VM Lib: "
231  << PrettyPrinter::Print(GetBytes("status/VmLib"), TUnit::BYTES) << endl
232  << " VM PTE: "
233  << PrettyPrinter::Print(GetBytes("status/VmPTE"), TUnit::BYTES) << endl
234  << " VM Swap: "
235  << PrettyPrinter::Print(GetBytes("status/VmSwap"), TUnit::BYTES) << endl
236  << " Cpus Allowed List: " << GetString("status/Cpus_allowed_list") << endl
237  << " Mems Allowed List: " << GetString("status/Mems_allowed_list") << endl
238  << " File Descriptors: " << endl
239  << " Number of File Descriptors: " << fd_desc_.size() << endl;
240  stream << endl;
241  return stream.str();
242 }
243 
244 }
string path("/usr/lib/sasl2:/usr/lib64/sasl2:/usr/local/lib/sasl2:/usr/lib/x86_64-linux-gnu/sasl2")
std::string DebugString(const T &val)
Definition: udf-debug.h:27