0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SystemInfo.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
26 #include <Common/Compat.h>
27 #include <Common/Config.h>
28 #include <Common/Logger.h>
29 #include <Common/Serialization.h>
30 #include <Common/SystemInfo.h>
31 
32 #if defined(TCMALLOC) || defined(TCMALLOC_MINIMAL)
33 #include <gperftools/malloc_extension.h>
34 #endif
35 
36 #include <chrono>
37 #include <cstdlib>
38 #include <mutex>
39 #include <thread>
40 #include <utility>
41 
42 extern "C" {
43 #include <ncurses.h>
44 #include <term.h>
45 #include <sigar.h>
46 #include <sigar_format.h>
47 }
48 
49 #define HT_FIELD_NOTIMPL(_field_) (_field_ == (uint64_t)-1)
50 
51 using namespace Hypertable;
52 using namespace std;
53 
54 bool CpuInfo::operator==(const CpuInfo &other) const {
55  if (vendor == other.vendor &&
56  model == other.model &&
57  mhz == other.mhz &&
58  cache_size == other.cache_size &&
59  total_sockets == other.total_sockets &&
60  total_cores == other.total_cores &&
61  cores_per_socket == other.cores_per_socket)
62  return true;
63  return false;
64 }
65 
66 bool CpuStat::operator==(const CpuStat &other) const {
67  if (Serialization::equal(user, other.user) &&
68  Serialization::equal(sys, other.sys) &&
69  Serialization::equal(nice, other.nice) &&
70  Serialization::equal(idle, other.idle) &&
71  Serialization::equal(wait, other.wait) &&
72  Serialization::equal(irq, other.irq) &&
73  Serialization::equal(soft_irq, other.soft_irq) &&
74  Serialization::equal(stolen, other.stolen) &&
75  Serialization::equal(total, other.total))
76  return true;
77  return false;
78 }
79 
80 bool LoadAvgStat::operator==(const LoadAvgStat &other) const {
81  if (Serialization::equal(loadavg[0], other.loadavg[0]) &&
82  Serialization::equal(loadavg[1], other.loadavg[1]) &&
83  Serialization::equal(loadavg[2], other.loadavg[2]))
84  return true;
85  return false;
86 }
87 
88 bool MemStat::operator==(const MemStat &other) const {
89  if (Serialization::equal(ram, other.ram) &&
90  Serialization::equal(total, other.total) &&
91  Serialization::equal(used, other.used) &&
92  Serialization::equal(free, other.free) &&
93  Serialization::equal(actual_used, other.actual_used) &&
94  Serialization::equal(actual_free, other.actual_free))
95  return true;
96  return false;
97 }
98 
99 bool DiskStat::operator==(const DiskStat &other) const {
100  if (prefix == other.prefix &&
101  Serialization::equal(reads_rate, other.reads_rate) &&
102  Serialization::equal(writes_rate, other.writes_rate) &&
103  Serialization::equal(read_rate, other.read_rate) &&
104  Serialization::equal(write_rate, other.write_rate))
105  return true;
106  return false;
107 }
108 
109 bool SwapStat::operator==(const SwapStat &other) const {
110  if (Serialization::equal(total, other.total) &&
111  Serialization::equal(used, other.used) &&
112  Serialization::equal(free, other.free) &&
113  page_in == other.page_in &&
114  page_out == other.page_out)
115  return true;
116  return false;
117 }
118 
119 bool NetInfo::operator==(const NetInfo &other) const {
120  if (host_name == other.host_name &&
121  primary_if == other.primary_if &&
122  primary_addr == other.primary_addr &&
123  default_gw == other.default_gw)
124  return true;
125  return false;
126 }
127 
128 bool NetStat::operator==(const NetStat &other) const {
129  if (tcp_established == other.tcp_established &&
130  tcp_listen == other.tcp_listen &&
131  tcp_time_wait == other.tcp_time_wait &&
132  tcp_close_wait == other.tcp_close_wait &&
133  tcp_idle == other.tcp_idle &&
134  Serialization::equal(rx_rate, other.rx_rate) &&
135  Serialization::equal(tx_rate, other.tx_rate))
136  return true;
137  return false;
138 }
139 
140 bool OsInfo::operator==(const OsInfo &other) const {
141  if (name == other.name &&
142  version == other.version &&
143  version_major == other.version_major &&
144  version_minor == other.version_minor &&
145  version_micro == other.version_micro &&
146  arch == other.arch &&
147  machine == other.machine &&
148  description == other.description &&
149  patch_level == other.patch_level &&
150  vendor == other.vendor &&
151  vendor_version == other.vendor_version &&
152  vendor_name == other.vendor_name &&
153  code_name == other.code_name)
154  return true;
155  return false;
156 }
157 
158 bool ProcInfo::operator==(const ProcInfo &other) const {
159  if (pid == other.pid &&
160  user == other.user &&
161  exe == other.exe &&
162  cwd == other.cwd &&
163  root == other.root &&
164  args == other.args)
165  return true;
166  return false;
167 }
168 
169 bool ProcStat::operator==(const ProcStat &other) const {
170  if (cpu_user == other.cpu_user &&
171  cpu_sys == other.cpu_sys &&
172  cpu_total == other.cpu_total &&
173  Serialization::equal(cpu_pct, other.cpu_pct) &&
174  Serialization::equal(vm_size, other.vm_size) &&
175  Serialization::equal(vm_resident, other.vm_resident) &&
176  Serialization::equal(vm_share, other.vm_share) &&
177  minor_faults == other.minor_faults &&
178  major_faults == other.major_faults &&
179  page_faults == other.page_faults &&
180  heap_size == other.heap_size &&
181  heap_slack == other.heap_slack)
182  return true;
183  return false;
184 }
185 
186 bool FsStat::operator==(const FsStat &other) const {
187  if (prefix == other.prefix &&
188  total == other.total &&
189  free == other.free &&
190  used == other.used &&
191  avail == other.avail &&
192  Serialization::equal(use_pct, other.use_pct) &&
193  files == other.files &&
194  free_files == other.free_files)
195  return true;
196  return false;
197 }
198 
199 bool TermInfo::operator==(const TermInfo &other) const {
200  if (term == other.term &&
201  num_lines == other.num_lines &&
202  num_cols == other.num_cols)
203  return true;
204  return false;
205 }
206 
207 namespace {
208 
209 recursive_mutex _mutex;
210 
211 // for computing cpu percentages
212 recursive_mutex _cpu_mutex;
213 sigar_cpu_t _prev_cpu, *_prev_cpup = NULL;
214 
215 // default pause (in ms) to calcuate rates
216 const int DEFAULT_PAUSE = 500;
217 
218 // for unit conversion to/from MB/GB
219 const double KiB = 1024.;
220 const double MiB = KiB * 1024;
221 //const double GiB = MiB * 1024;
222 
223 // for computing rx/tx rate
224 recursive_mutex _net_mutex;
225 sigar_net_interface_stat_t _prev_net_stat, *_prev_net_statp = NULL;
226 Stopwatch _net_stat_stopwatch;
227 const int DEFAULT_NET_STAT_FLAGS =
228  SIGAR_NETCONN_CLIENT|SIGAR_NETCONN_SERVER|SIGAR_NETCONN_TCP;
229 
230 // info/stat singletons
231 CpuInfo _cpu_info, *_cpu_infop = NULL;
232 CpuStat _cpu_stat;
233 LoadAvgStat _loadavg_stat;
234 MemStat _mem_stat;
235 DiskStat _disk_stat;
236 OsInfo _os_info, *_os_infop = NULL;
237 SwapStat _swap_stat;
238 NetInfo _net_info, *_net_infop = NULL;
239 NetStat _net_stat;
240 ProcInfo _proc_info, *_proc_infop = NULL;
241 ProcStat _proc_stat;
242 FsStat _fs_stat;
243 TermInfo _term_info, *_term_infop = NULL;
244 
245 // sigar_t singleton to take advantage of the cache
246 sigar_t *_sigar = NULL;
247 
248 sigar_t *sigar() {
249  if (!_sigar)
250  HT_ASSERT(sigar_open(&_sigar) == SIGAR_OK);
251 
252  return _sigar;
253 }
254 
255 // we don't expect filesystem changes while the process is running
256 sigar_file_system_list_t _fs_list, *_fs_listp = NULL;
257 
258 sigar_file_system_list_t &fs_list() {
259  if (!_fs_listp) {
260  HT_ASSERT(sigar_file_system_list_get(sigar(), &_fs_list) == SIGAR_OK);
261  _fs_listp = &_fs_list;
262  }
263  return _fs_list;
264 }
265 
266 bool compute_disk_usage(const char *prefix, sigar_disk_usage_t &u) {
267  sigar_disk_usage_t t;
268  sigar_file_system_t *fs = fs_list().data, *fs_end = fs + fs_list().number;
269  size_t prefix_len = strlen(prefix);
270  u.reads = u.writes = u.write_bytes = u.read_bytes = 0;
271  size_t num_found = 0;
272 
273  for (; fs < fs_end; ++fs) {
274  if (strncmp(prefix, fs->dir_name, prefix_len) == 0
275  && sigar_disk_usage_get(sigar(), fs->dir_name, &t) == SIGAR_OK) {
276  u.reads += t.reads;
277  u.writes += t.writes;
278  u.read_bytes += t.read_bytes;
279  u.write_bytes += t.write_bytes;
280  ++num_found;
281  }
282  }
283  if (num_found > 0)
284  return true;
285 
286  return false;
287 }
288 
289 bool compute_fs_usage(const char *prefix, sigar_file_system_usage_t &u) {
290  sigar_file_system_usage_t t;
291  sigar_file_system_t *fs = fs_list().data, *fs_end = fs + fs_list().number;
292  size_t prefix_len = strlen(prefix);
293  u.use_percent = 0.;
294  u.total = u.free = u.used = u.avail = u.files = u.free_files = 0;
295  size_t num_found = 0;
296 
297  for (; fs < fs_end; ++fs) {
298  if (strncmp(prefix, fs->dir_name, prefix_len) == 0
299  && sigar_file_system_usage_get(sigar(), fs->dir_name, &t) == SIGAR_OK) {
300 
301  u.use_percent += t.use_percent * t.total; // for weighted mean;
302  u.total += t.total;
303  u.free += t.free;
304  u.used += t.used;
305  u.avail += t.avail;
306  u.files += t.files;
307  u.free_files += t.free_files;
308  ++num_found;
309  }
310  }
311  if (num_found > 0) {
312  u.use_percent /= u.total;
313  return true;
314  }
315  return false;
316 }
317 
318 } // local namespace
319 
320 namespace Hypertable {
321 
323  lock_guard<recursive_mutex> lock(_mutex);
324 
325  if (!_cpu_infop)
326  _cpu_infop = &_cpu_info.init();
327 
328  return _cpu_info;
329 }
330 
332  return _cpu_stat.refresh();
333 }
334 
336  return _loadavg_stat.refresh();
337 }
338 
340  return _mem_stat.refresh();
341 }
342 
344  return _disk_stat.refresh();
345 }
346 
348  lock_guard<recursive_mutex> lock(_mutex);
349 
350  if (!_os_infop)
351  _os_infop = &_os_info.init();
352 
353  return _os_info;
354 }
355 
357  return _swap_stat.refresh();
358 }
359 
361  lock_guard<recursive_mutex> lock(_mutex);
362 
363  if (!_net_infop)
364  _net_infop = &_net_info.init();
365 
366  return _net_info;
367 }
368 
370  return _net_stat.refresh();
371 }
372 
374  lock_guard<recursive_mutex> lock(_mutex);
375 
376  if (!_proc_infop)
377  _proc_infop = &_proc_info.init();
378 
379  return _proc_info;
380 }
381 
383  return _proc_stat.refresh();
384 }
385 
387  return _fs_stat.refresh();
388 }
389 
391  lock_guard<recursive_mutex> lock(_mutex);
392 
393  if (!_term_infop)
394  _term_infop = &_term_info.init();
395 
396  return _term_info;
397 }
398 
400  lock_guard<recursive_mutex> lock(_mutex);
401  sigar_cpu_info_list_t l;
402 
403  HT_ASSERT(sigar_cpu_info_list_get(sigar(), &l) == SIGAR_OK);
404  sigar_cpu_info_t &s = l.data[0];
405 
406  vendor = s.vendor;
407  model = s.model;
408  mhz = s.mhz;
409  cache_size = s.cache_size;
410  total_sockets = s.total_sockets;
411  total_cores = s.total_cores;
412  cores_per_socket = s.cores_per_socket;
413 
414  sigar_cpu_info_list_destroy(sigar(), &l);
415 
416  return *this;
417 }
418 
420  lock_guard<recursive_mutex> cpu_lock(_cpu_mutex);
421  bool need_pause = false;
422  {
423  lock_guard<recursive_mutex> lock(_mutex); // needed for sigar object
424 
425  if (!_prev_cpup) {
426  HT_ASSERT(sigar_cpu_get(sigar(), &_prev_cpu) == SIGAR_OK);
427  _prev_cpup = &_prev_cpu;
428  need_pause = true;
429  }
430  }
431 
432  if (need_pause)
433  this_thread::sleep_for(chrono::milliseconds(DEFAULT_PAUSE));
434 
435  {
436  lock_guard<recursive_mutex> lock(_mutex);
437  sigar_cpu_t curr;
438  HT_ASSERT(sigar_cpu_get(sigar(), &curr) == SIGAR_OK);
439 
440  sigar_cpu_perc_t p;
441  HT_ASSERT(sigar_cpu_perc_calculate(&_prev_cpu, &curr, &p) == SIGAR_OK);
442 
443  user = p.user * 100.;
444  sys = p.sys * 100.;
445  nice = p.nice * 100.;
446  idle = p.idle * 100.;
447  wait = p.wait * 100.;
448  irq = p.irq * 100.;
449  soft_irq = p.soft_irq * 100.;
450  stolen = p.stolen * 100.;
451  total = p.combined * 100.;
452 
453  _prev_cpu = curr;
454  }
455  return *this;
456 }
457 
459  lock_guard<recursive_mutex> lock(_mutex);
460  sigar_loadavg_t m;
461  HT_ASSERT(sigar_loadavg_get(sigar(), &m) == SIGAR_OK);
462 
463  loadavg[0] = m.loadavg[0];
464  loadavg[1] = m.loadavg[1];
465  loadavg[2] = m.loadavg[2];
466 
467  return *this;
468 }
469 
471  lock_guard<recursive_mutex> lock(_mutex);
472  sigar_mem_t m;
473 
474  HT_ASSERT(sigar_mem_get(sigar(), &m) == SIGAR_OK);
475 
476  ram = m.ram;
477  total = m.total / MiB;
478  used = m.used / MiB;
479  free = m.free / MiB;
480  actual_used = m.actual_used / MiB;
481  actual_free = m.actual_free / MiB;
482 
483  return *this;
484 }
485 
487  prefix = other.prefix;
488  reads_rate = other.reads_rate;
489  writes_rate = other.writes_rate;
490  read_rate = other.read_rate;
491  write_rate = other.write_rate;
492  if (prev_stat) {
493  prev_stat = new sigar_disk_usage_t();
494  memcpy(prev_stat, other.prev_stat, sizeof(sigar_disk_usage_t));
495  }
496 }
498  delete (sigar_disk_usage_t *)prev_stat;
499 }
500 
501 void DiskStat::swap (DiskStat &other) {
502  prefix.swap(other.prefix);
503  std::swap(reads_rate, other.reads_rate);
504  std::swap(writes_rate, other.writes_rate);
505  std::swap(read_rate, other.read_rate);
506  std::swap(write_rate, other.write_rate);
507  std::swap(prev_stat, other.prev_stat);
508  std::swap(stopwatch, other.stopwatch);
509 }
510 
511 DiskStat &DiskStat::refresh(const char *dir_prefix) {
512  lock_guard<recursive_mutex> lock(_mutex);
513  sigar_disk_usage_t s;
514 
515  memset(&s, 0, sizeof(s));
516 
517  if (compute_disk_usage(dir_prefix, s)) {
518  HT_DEBUGF("curr_disk_stat: reads=%llu, reads=%llu, read_bytes=%llu "
519  "write_bytes=%llu", (Llu)s.reads, (Llu)s.writes,
520  (Llu)s.read_bytes, (Llu)s.write_bytes);
521 
522  if (prev_stat) {
523  stopwatch.stop();
524  double elapsed = stopwatch.elapsed();
525  reads_rate = (s.reads - ((sigar_disk_usage_t *)prev_stat)->reads) / elapsed;
526  writes_rate = (s.writes - ((sigar_disk_usage_t *)prev_stat)->writes) / elapsed;
527  read_rate =
528  (s.read_bytes - ((sigar_disk_usage_t *)prev_stat)->read_bytes) / elapsed;
529  write_rate =
530  (s.write_bytes - ((sigar_disk_usage_t *)prev_stat)->write_bytes) / elapsed;
531  }
532  else
533  prev_stat = new sigar_disk_usage_t();
534 
535  *((sigar_disk_usage_t *)prev_stat) = s;
536  stopwatch.reset();
537  stopwatch.start();
538  }
539 
540  return *this;
541 }
542 
544  total = other.total;
545  used = other.used;
546  free = other.free;
547  page_in = other.page_in;
548  page_out = other.page_out;
549  if (other.prev_stat) {
550  prev_stat = new sigar_swap_t();
551  memcpy(prev_stat, other.prev_stat, sizeof(sigar_swap_t));
552  }
553 }
554 
556  delete (sigar_swap_t *)prev_stat;
557 }
558 
559 void SwapStat::swap (SwapStat &other) {
560  std::swap(total, other.total);
561  std::swap(used, other.used);
562  std::swap(free, other.free);
563  std::swap(page_in, other.page_in);
564  std::swap(page_out, other.page_out);
565  std::swap(prev_stat, other.prev_stat);
566 }
567 
569  lock_guard<recursive_mutex> lock(_mutex);
570  sigar_swap_t s;
571 
572  HT_ASSERT(sigar_swap_get(sigar(), &s) == SIGAR_OK);
573 
574  total = s.total / MiB;
575  used = s.used / MiB;
576  free = s.free / MiB;
577 
578  if (prev_stat) {
579  page_in = s.page_in - ((sigar_swap_t *)prev_stat)->page_in;
580  page_out = s.page_out - ((sigar_swap_t *)prev_stat)->page_out;
581  }
582  else {
583  prev_stat = new sigar_swap_t();
584  page_in = s.page_in;
585  page_out = s.page_out;
586  }
587 
588  *((sigar_swap_t *)prev_stat) = s;
589 
590  return *this;
591 }
592 
594  lock_guard<recursive_mutex> lock(_mutex);
595  sigar_sys_info_t s;
596 
597  HT_ASSERT(sigar_sys_info_get(sigar(), &s) == SIGAR_OK);
598 
599  name = s.name;
600  version = s.version;
601 
602  char *ptr = (char *)version.c_str();
603  version_major = (uint16_t)strtol(ptr, &ptr, 10);
604  ptr++;
605  version_minor = (uint16_t)strtol(ptr, &ptr, 10);
606  ptr++;
607  version_micro = (uint16_t)strtol(ptr, &ptr, 10);
608 
609  arch = s.arch;
610  machine = s.machine;
611  description = s.description;
612  patch_level = s.patch_level;
613  vendor = s.vendor;
614  vendor_version = s.vendor_version;
615  vendor_name = s.vendor_name;
616 
617  return *this;
618 }
619 
621  lock_guard<recursive_mutex> lock(_mutex);
622  sigar_net_interface_config_t ifc;
623  sigar_net_info_t ni;
624  char addrbuf[SIGAR_INET6_ADDRSTRLEN];
625  String ifname;
626 
627  HT_ASSERT(sigar_net_info_get(sigar(), &ni) == SIGAR_OK);
628  host_name = ni.host_name;
629  default_gw = ni.default_gateway;
630 
631  if (Hypertable::Config::has("Hypertable.Network.Interface"))
632  ifname = Hypertable::Config::get_str("Hypertable.Network.Interface");
633 
634  if (ifname != "") {
635  if (sigar_net_interface_config_get(sigar(), ifname.c_str(), &ifc) == SIGAR_OK) {
636  primary_if = ifc.name;
637  HT_ASSERT(sigar_net_address_to_string(sigar(), &ifc.address, addrbuf)
638  == SIGAR_OK);
639  primary_addr = addrbuf;
640  }
641  else
642  HT_FATALF("Unable to find network interface '%s'", ifname.c_str());
643  }
644  else if (sigar_net_interface_config_primary_get(sigar(), &ifc) == SIGAR_OK) {
645  primary_if = ifc.name;
646  HT_ASSERT(sigar_net_address_to_string(sigar(), &ifc.address, addrbuf)
647  == SIGAR_OK);
648  primary_addr = addrbuf;
649  }
650  if (primary_addr.empty())
651  primary_addr = "127.0.0.1";
652 
653  return *this;
654 }
655 
657  lock_guard<recursive_mutex> net_lock(_net_mutex);
658  {
659  lock_guard<recursive_mutex> lock(_mutex);
660  sigar_net_stat_t s;
661 
662  if (sigar_net_stat_get(sigar(), &s, DEFAULT_NET_STAT_FLAGS) == SIGAR_OK) {
663  tcp_established = s.tcp_states[SIGAR_TCP_ESTABLISHED];
664  tcp_listen = s.tcp_states[SIGAR_TCP_LISTEN];
665  tcp_time_wait = s.tcp_states[SIGAR_TCP_TIME_WAIT];
666  tcp_close_wait = s.tcp_states[SIGAR_TCP_CLOSE_WAIT];
667  tcp_idle = s.tcp_states[SIGAR_TCP_IDLE];
668  }
669  else {
670  tcp_established = tcp_listen = tcp_time_wait = tcp_close_wait =
671  tcp_idle = 0;
672  }
673  }
674  bool need_pause = false;
675  const char *ifname = System::net_info().primary_if.c_str();
676  {
677  lock_guard<recursive_mutex> lock(_mutex);
678 
679  if (!_prev_net_statp) {
680  if (sigar_net_interface_stat_get(sigar(), ifname, &_prev_net_stat)
681  == SIGAR_OK) {
682  _prev_net_statp = &_prev_net_stat;
683  _net_stat_stopwatch.start();
684  HT_DEBUGF("prev_net_stat: rx_bytes=%llu, tx_bytes=%llu",
685  (Llu)_prev_net_stat.rx_bytes, (Llu)_prev_net_stat.tx_bytes);
686  need_pause = true;
687  }
688  else {
689  rx_rate = tx_rate = 0;
690  }
691  }
692  }
693  if (need_pause)
694  this_thread::sleep_for(chrono::milliseconds(DEFAULT_PAUSE));
695 
696  {
697  lock_guard<recursive_mutex> lock(_mutex);
698 
699  if (_prev_net_statp) {
700  sigar_net_interface_stat_t curr;
701 
702  if (sigar_net_interface_stat_get(sigar(), ifname, &curr) == SIGAR_OK) {
703  _net_stat_stopwatch.stop();
704  double elapsed = _net_stat_stopwatch.elapsed();
705  HT_DEBUGF("curr_net_stat: rx_bytes=%llu, tx_bytes=%llu",
706  (Llu)curr.rx_bytes, (Llu)curr.tx_bytes);
707 
708  rx_rate = (curr.rx_bytes - _prev_net_stat.rx_bytes) / elapsed;
709  tx_rate = (curr.tx_bytes - _prev_net_stat.tx_bytes) / elapsed;
710 
711  _prev_net_stat = curr;
712  _net_stat_stopwatch.reset();
713  _net_stat_stopwatch.start();
714  }
715  }
716  }
717  return *this;
718 }
719 
721  lock_guard<recursive_mutex> lock(_mutex);
722  sigar_proc_exe_t exeinfo;
723  sigar_proc_args_t arginfo;
724 
725  memset(&exeinfo, 0, sizeof(exeinfo));
726  pid = sigar_pid_get(sigar());
727  HT_ASSERT(sigar_proc_exe_get(sigar(), pid, &exeinfo) == SIGAR_OK);
728  HT_ASSERT(sigar_proc_args_get(sigar(), pid, &arginfo) == SIGAR_OK);
729 
736  user = "unknown";
737  exe = exeinfo.name;
738  cwd = exeinfo.cwd;
739  root = exeinfo.root;
740 
741  for (size_t i = 0; i < arginfo.number; ++i)
742  args.push_back(arginfo.data[i]);
743 
744  sigar_proc_args_destroy(sigar(), &arginfo);
745 
746  return *this;
747 }
748 
750  lock_guard<recursive_mutex> lock(_mutex);
751  sigar_proc_cpu_t c;
752  sigar_proc_mem_t m;
753 
754  sigar_pid_t pid = sigar_pid_get(sigar());
755  HT_ASSERT(sigar_proc_cpu_get(sigar(), pid, &c) == SIGAR_OK);
756  HT_ASSERT(sigar_proc_mem_get(sigar(), pid, &m) == SIGAR_OK);
757 
758  cpu_user = c.user;
759  cpu_sys = c.sys;
760  cpu_total = c.total;
761  cpu_pct = c.percent * 100.;
762  vm_size = m.size / MiB;
763  vm_resident = m.resident / MiB;
764  vm_share = HT_FIELD_NOTIMPL(m.share) ? 0 : m.share / MiB;
765  minor_faults = HT_FIELD_NOTIMPL(m.minor_faults) ? 0 : m.minor_faults;
766  major_faults = HT_FIELD_NOTIMPL(m.major_faults) ? 0 : m.major_faults;
767  page_faults = HT_FIELD_NOTIMPL(m.page_faults) ? 0 : m.page_faults;;
768 #if defined(TCMALLOC) || defined(TCMALLOC_MINIMAL)
769  size_t tmp_heap_size, tmp_heap_slack;
770  MallocExtension::instance()->GetNumericProperty("generic.heap_size", &tmp_heap_size);
771  heap_size = tmp_heap_size;
772  MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes", &tmp_heap_slack);
773  heap_slack = tmp_heap_slack;
774 #else
775  heap_size = 0;
776  heap_slack = 0;
777 #endif
778 
779  return *this;
780 }
781 
782 FsStat &FsStat::refresh(const char *dir_prefix) {
783  lock_guard<recursive_mutex> lock(_mutex);
784  sigar_file_system_usage_t u;
785  prefix = dir_prefix;
786 
787  if (compute_fs_usage(dir_prefix, u)) {
788  use_pct = u.use_percent * 100.0;
789  total = u.total; // u.total already in KB
790  free = u.free;
791  used = u.used;
792  avail = u.avail;
793  files = u.files;
794  free_files = u.free_files;
795  }
796  return *this;
797 }
798 
800  lock_guard<recursive_mutex> lock(_mutex);
801  int err;
802 
803  if (setupterm(0, 1, &err) != ERR) {
804  term = getenv("TERM");
805  num_lines = lines;
806  num_cols = columns;
807  }
808  else {
809  term = "dumb";
810  num_lines = 24;
811  num_cols = 80;
812  }
813  return *this;
814 }
815 
816 const char *system_info_lib_version() {
817  sigar_version_t *v = sigar_version_get();
818  return v->description;
819 }
820 
821 std::ostream &operator<<(std::ostream &out, const CpuInfo &i) {
822  out <<"{CpuInfo: vendor='"<< i.vendor <<"' model='"<< i.model
823  <<"' mhz="<< i.mhz <<" cache_size="<< i.cache_size
824  <<"\n total_sockets="<< i.total_sockets <<" total_cores="<< i.total_cores
825  <<" cores_per_socket="<< i.cores_per_socket <<'}';
826  return out;
827 }
828 
829 std::ostream &operator<<(std::ostream &out, const CpuStat &s) {
830  out <<"{CpuStat: user="<< s.user <<" sys="<< s.sys <<" nice="<< s.nice
831  <<" idle="<< s.idle <<" wait="<< s.wait <<"\n irq="<< s.irq
832  <<" soft_irq="<< s.soft_irq <<" stolen="<< s.stolen
833  <<" total="<< s.total <<'}';
834  return out;
835 }
836 
837 std::ostream &operator<<(std::ostream &out, const MemStat &s) {
838  out <<"{MemStat: ram="<< s.ram <<" total="<< s.total <<" used="<< s.used
839  <<" free="<< s.free <<"\n actual_used="<< s.actual_used
840  <<" actual_free="<< s.actual_free <<'}';
841  return out;
842 }
843 
844 std::ostream &operator<<(std::ostream &out, const DiskStat &s) {
845  out <<"{DiskStat: prefix='"<< s.prefix <<"' reads_rate="<< s.reads_rate
846  <<" writes_rate="<< s.writes_rate <<"\n read_rate=" << s.read_rate
847  <<" write_rate="<< s.write_rate <<'}';
848  return out;
849 }
850 
851 std::ostream &operator<<(std::ostream &out, const OsInfo &i) {
852  out <<"{OsInfo: name="<< i.name <<" version="<< i.version <<" arch="<< i.arch
853  <<" machine="<< i.machine <<"\n description='"<< i.description
854  <<"' patch_level="<< i.patch_level <<"\n vendor="<< i.vendor
855  <<" vendor_version="<< i.vendor_version <<" vendor_name="<< i.vendor_name
856  <<" code_name="<< i.code_name <<'}';
857  return out;
858 }
859 
860 std::ostream &operator<<(std::ostream &out, const SwapStat &s) {
861  out <<"{SwapStat: total="<< s.total <<" used="<< s.used <<" free="<< s.free
862  <<" page_in="<< s.page_in <<" page_out="<< s.page_out <<'}';
863  return out;
864 }
865 
866 std::ostream &operator<<(std::ostream &out, const NetInfo &i) {
867  out <<"{NetInfo: host_name="<< i.host_name <<" primary_if="
868  << i.primary_if <<"\n primary_addr="<< i.primary_addr
869  <<" default_gw="<< i.default_gw <<'}';
870  return out;
871 }
872 
873 std::ostream &operator<<(std::ostream &out, const NetStat &s) {
874  out <<"{NetStat: rx_rate="<< s.rx_rate <<" tx_rate="<< s.tx_rate
875  <<" tcp_established="<< s.tcp_established <<" tcp_listen="
876  << s.tcp_listen <<"\n tcp_time_wait="<< s.tcp_time_wait
877  <<" tcp_close_wait="<< s.tcp_close_wait <<'}';
878  return out;
879 }
880 
881 std::ostream &operator<<(std::ostream &out, const ProcInfo &i) {
882  out <<"{ProcInfo: pid="<< i.pid <<" user="<< i.user <<" exe='"<< i.exe
883  <<"'\n cwd='"<< i.cwd <<"' root='"<< i.root <<"'\n args=[";
884 
885  for (const auto &arg : i.args)
886  out <<"'"<< arg <<"', ";
887 
888  out <<"]}";
889  return out;
890 }
891 
892 std::ostream &operator<<(std::ostream &out, const ProcStat &s) {
893  out <<"{ProcStat: cpu_user="<< s.cpu_user <<" cpu_sys="<< s.cpu_sys
894  <<" cpu_total="<< s.cpu_total <<" cpu_pct="<< s.cpu_pct
895  <<"\n vm_size="<< s.vm_size <<" vm_resident="<< s.vm_resident
896  <<" vm_share="<< s.vm_share <<"\n major_faults="<< s.major_faults
897  <<" minor_faults="<< s.minor_faults <<" page_faults="<< s.page_faults
898  <<" heap_size="<< s.heap_size <<" heap_slack="<< s.heap_slack
899  <<'}';
900  return out;
901 }
902 
903 std::ostream &operator<<(std::ostream &out, const FsStat &s) {
904  out <<"{FsStat: prefix='"<< s.prefix <<"' total="<< s.total
905  <<" free="<< s.free <<" used="<< s.used <<"\n avail="<< s.avail
906  <<" use_pct="<< s.use_pct <<'}';
907  return out;
908 }
909 
910 std::ostream &operator<<(std::ostream &out, const TermInfo &i) {
911  out <<"{TermInfo: term='"<< i.term <<"' num_lines="<< i.num_lines
912  <<" num_cols="<< i.num_cols <<'}';
913  return out;
914 }
915 
916 } // namespace Hypertable
void swap(SwapStat &other)
Definition: SystemInfo.cc:559
int32_t tcp_established
Definition: SystemInfo.h:211
bool operator==(const ProcStat &other) const
Definition: SystemInfo.cc:169
double elapsed()
Returns the elapsed time.
Definition: Stopwatch.h:72
static const NetStat & net_stat()
Retrieves updated Network statistics (see SystemInfo.h)
Definition: SystemInfo.cc:369
uint16_t version_major
Definition: SystemInfo.h:235
bool operator==(const MemStat &other) const
Definition: SystemInfo.cc:88
static const CpuInfo & cpu_info()
Retrieves updated CPU information (see SystemInfo.h)
Definition: SystemInfo.cc:322
NetInfo & init()
Definition: SystemInfo.cc:620
A structure to retrieve Swapping statistics (pages swapped in/out, aggregate total numbers etc) ...
Definition: SystemInfo.h:156
const int version_micro
Definition: Version.cc:33
bool operator==(const ProcInfo &other) const
Definition: SystemInfo.cc:158
void swap(DiskStat &other)
Definition: SystemInfo.cc:501
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
static const CpuStat & cpu_stat()
Retrieves updated CPU statistics (see SystemInfo.h)
Definition: SystemInfo.cc:331
#define HT_FIELD_NOTIMPL(_field_)
Definition: SystemInfo.cc:49
bool operator==(const NetInfo &other) const
Definition: SystemInfo.cc:119
bool operator==(const OsInfo &other) const
Definition: SystemInfo.cc:140
uint16_t version_micro
Definition: SystemInfo.h:237
uint64_t free_files
Definition: SystemInfo.h:319
A structure to retrieve CPU statistics (system wide cpu times, idle time etc).
Definition: SystemInfo.h:66
long long unsigned int Llu
Shortcut for printf formats.
Definition: String.h:50
static const ProcInfo & proc_info()
Retrieves updated Process information (see SystemInfo.h)
Definition: SystemInfo.cc:373
static const ProcStat & proc_stat()
Retrieves updated Process statistics (see SystemInfo.h)
Definition: SystemInfo.cc:382
bool operator==(const CpuInfo &other) const
Definition: SystemInfo.cc:54
const uint64_t MiB
Definition: Properties.h:157
A structure to retrieve disk statistics (read/write IOPS, transfer rates etc)
Definition: SystemInfo.h:123
STL namespace.
NetStat & refresh()
Definition: SystemInfo.cc:656
bool operator==(const LoadAvgStat &other) const
Definition: SystemInfo.cc:80
static const LoadAvgStat & loadavg_stat()
Retrieves updated Load average statistics (see SystemInfo.h)
Definition: SystemInfo.cc:335
static const DiskStat & disk_stat()
Retrieves updated Disk statistics (see SystemInfo.h)
Definition: SystemInfo.cc:343
bool has(const String &name)
Check existence of a configuration value.
Definition: Config.h:57
CpuStat & refresh()
Definition: SystemInfo.cc:419
MemStat & refresh()
Definition: SystemInfo.cc:470
#define HT_ASSERT(_e_)
Definition: Logger.h:396
A structure to retrieve terminal information (lines, columns etc)
Definition: SystemInfo.h:325
const uint64_t KiB
Definition: Properties.h:155
FsStat & refresh(const char *prefix="/")
Definition: SystemInfo.cc:782
LoadAvgStat & refresh()
Definition: SystemInfo.cc:458
Logging routines and macros.
static const OsInfo & os_info()
Retrieves updated Operating system information (see SystemInfo.h)
Definition: SystemInfo.cc:347
bool operator==(const NetStat &other) const
Definition: SystemInfo.cc:128
int32_t tcp_close_wait
Definition: SystemInfo.h:214
Compatibility Macros for C/C++.
A structure to retrieve CPU information (vendor, model, speed, number of cores etc.)
Definition: SystemInfo.h:46
std::ostream & operator<<(std::ostream &os, const crontab_entry &entry)
Helper function to write crontab_entry to an ostream.
Definition: Crontab.cc:301
bool operator==(const DiskStat &other) const
Definition: SystemInfo.cc:99
void start()
Starts the Stopwatch.
Definition: Stopwatch.h:50
DiskStat & refresh(const char *dir_prefix="/")
Definition: SystemInfo.cc:511
Functions to serialize/deserialize primitives to/from a memory buffer.
A structure to receive process statistics (CPU user time, system time, virtmal machine sizes etc) ...
Definition: SystemInfo.h:271
A structure to retrieve memory statistics (RAM size, used size, free size etc)
Definition: SystemInfo.h:103
const int version_minor
Definition: Version.cc:32
static const SwapStat & swap_stat()
Retrieves updated Swap statistics (see SystemInfo.h)
Definition: SystemInfo.cc:356
static const FsStat & fs_stat()
Retrieves updated Filesystem statistics (see SystemInfo.h)
Definition: SystemInfo.cc:386
__nat swap(__any, __any)
Hypertable definitions
#define HT_FATALF(msg,...)
Definition: Logger.h:343
#define HT_DEBUGF(msg,...)
Definition: Logger.h:260
std::vector< String > args
Definition: SystemInfo.h:264
void reset()
Resets the Stopwatch.
Definition: Stopwatch.h:66
A structure to retrieve network information (host name, primary interface, primary address...
Definition: SystemInfo.h:187
bool operator==(const CpuStat &other) const
Definition: SystemInfo.cc:66
A structure to retrieve Filesystem statistics (total size, free size, used size etc) ...
Definition: SystemInfo.h:299
A structure to retrieve load average-statistics.
Definition: SystemInfo.h:89
uint32_t cache_size
Definition: SystemInfo.h:56
bool operator==(const TermInfo &other) const
Definition: SystemInfo.cc:199
const char * system_info_lib_version()
Returns a descriptive string of the libsigar version.
Definition: SystemInfo.cc:816
ProcInfo & init()
Definition: SystemInfo.cc:720
bool equal(double a, double b)
Compare doubles that may have been serialized and unserialized.
const int version_major
Definition: Version.cc:31
The Stopwatch class measures elapsed time between instantiation (or a call to start) and a call to st...
Definition: Stopwatch.h:40
bool operator==(const SwapStat &other) const
Definition: SystemInfo.cc:109
CpuInfo & init()
Definition: SystemInfo.cc:399
static const TermInfo & term_info()
Retrieves updated Terminal information (see SystemInfo.h)
Definition: SystemInfo.cc:390
Configuration settings.
SwapStat & refresh()
Definition: SystemInfo.cc:568
ProcStat & refresh()
Definition: SystemInfo.cc:749
System information and statistics based on libsigar.
A structure to receive process information (pid, user name, exe name, working directory, program arguments etc)
Definition: SystemInfo.h:252
static const MemStat & mem_stat()
Retrieves updated Memory statistics (see SystemInfo.h)
Definition: SystemInfo.cc:339
static const NetInfo & net_info()
Retrieves updated Network information (see SystemInfo.h)
Definition: SystemInfo.cc:360
bool operator==(const FsStat &other) const
Definition: SystemInfo.cc:186
A structure to retrieve operating system information (name, version, vendor, architecture) ...
Definition: SystemInfo.h:226
uint16_t version_minor
Definition: SystemInfo.h:236
TermInfo & init()
Definition: SystemInfo.cc:799
void stop()
Stops the Stopwatch.
Definition: Stopwatch.h:58
A structure to retrieve network statistics (receiving rate, transmitting rate etc) ...
Definition: SystemInfo.h:204