PageRenderTime 77ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm

https://github.com/ceph/collectd
Perl | 190 lines | 117 code | 39 blank | 34 comment | 10 complexity | c4656da882fc8697a9bbfb42a54d8f97 MD5 | raw file
  1. #
  2. # collectd - OpenVZ collectd plugin
  3. # Copyright (C) 2009 Jonathan Kolb
  4. #
  5. # This program is free software; you can redistribute it and/or modify it under
  6. # the terms of the GNU General Public License as published by the Free Software
  7. # Foundation; either version 2 of the License, or (at your option) any later
  8. # version.
  9. #
  10. # This program is distributed in the hope that it will be useful, but
  11. # WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License along
  16. # with this program; if not, write to the Free Software Foundation, Inc.,
  17. # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. #
  19. # Author:
  20. # Jonathan Kolb <jon at b0g.us>
  21. #
  22. package Collectd::Plugins::OpenVZ;
  23. use strict;
  24. use warnings;
  25. use Collectd qw( :all );
  26. my @cpu_instances = ('user', 'nice', 'system', 'idle', 'wait', 'interrupt', 'softirq', 'steal');
  27. my @if_instances = ('if_octets', 'if_packets', 'if_errors');
  28. my $vzctl = '/usr/sbin/vzctl';
  29. my $vzlist = '/usr/sbin/vzlist';
  30. my $last_stat = {};
  31. sub openvz_read
  32. {
  33. my %v = (time => time(), interval => $interval_g);
  34. my (@veids, $veid, $name, $key, $val, $i, @lines, @parts, @counters);
  35. @veids = map { s/ //g; $_; } split(/\n/, `$vzlist -Ho veid`);
  36. foreach $veid (@veids)
  37. {
  38. ($name = `$vzlist -Ho name $veid`) =~ s/^\s*(.*?)\s*$/$1/;
  39. $name = $veid if ($name =~ /^-$/);
  40. $v{'host'} = $name;
  41. #####################################################################
  42. # interface
  43. $v{'plugin'} = 'interface';
  44. delete $v{'plugin_instance'};
  45. @lines = split(/\n/, `$vzctl exec $veid cat /proc/net/dev`);
  46. foreach (@lines)
  47. {
  48. next if (!/:/);
  49. @parts = split(/:/);
  50. ($key = $parts[0]) =~ s/^\s*(.*?)\s*$/$1/;
  51. ($val = $parts[1]) =~ s/^\s*(.*?)\s*$/$1/;
  52. @counters = split(/ +/, $val);
  53. $v{'type_instance'} = $key;
  54. for ($key = 0; $key <= $#if_instances; ++$key)
  55. {
  56. $v{'type'} = $if_instances[$key];
  57. $v{'values'} = [ $counters[$key], $counters[$key + 8] ];
  58. plugin_dispatch_values(\%v);
  59. }
  60. }
  61. #####################################################################
  62. # cpu
  63. $v{'plugin'} = 'cpu';
  64. $v{'type'} = 'cpu';
  65. $i = 0;
  66. @lines = split(/\n/, `$vzctl exec $veid cat /proc/stat`);
  67. foreach (@lines)
  68. {
  69. next if (!/^cpu[0-9]/);
  70. @counters = split(/ +/);
  71. shift(@counters);
  72. # Remove once OpenVZ bug 1376 is resolved
  73. if (48485 == $counters[3])
  74. {
  75. $counters[3] = $last_stat->{"$veid-$i-idle"};
  76. $counters[4] = $last_stat->{"$veid-$i-wait"};
  77. }
  78. else
  79. {
  80. $last_stat->{"$veid-$i-idle"} = $counters[3];
  81. $last_stat->{"$veid-$i-wait"} = $counters[4];
  82. }
  83. $v{'plugin_instance'} = $i++;
  84. for ($key = 0; $key <= $#counters; ++$key)
  85. {
  86. $v{'type_instance'} = $cpu_instances[$key];
  87. $v{'values'} = [ $counters[$key] ];
  88. plugin_dispatch_values(\%v);
  89. }
  90. }
  91. #####################################################################
  92. # df
  93. $v{'plugin'} = 'df';
  94. delete $v{'plugin_instance'};
  95. $v{'type'} = 'df';
  96. $val = join(' ', map { (split)[1] } split(/\n/, `$vzctl exec $veid cat /proc/mounts`));
  97. @lines = split(/\n/, `$vzctl exec $veid stat -tf $val`);
  98. foreach (@lines)
  99. {
  100. @parts = split(/ /);
  101. next if (0 == $parts[7]);
  102. $val = substr($parts[0], 1);
  103. $val = 'root' if ($val =~ /^$/);
  104. $val =~ s#/#-#g;
  105. $v{'type_instance'} = $val;
  106. $v{'values'} = [ $parts[5] * ($parts[6] - $parts[7]), $parts[5] * $parts[7] ];
  107. plugin_dispatch_values(\%v);
  108. }
  109. #####################################################################
  110. # load
  111. $v{'plugin'} = 'load';
  112. delete $v{'plugin_instance'};
  113. $v{'type'} = 'load';
  114. delete $v{'type_instance'};
  115. @parts = split(/ +/, `$vzctl exec $veid cat /proc/loadavg`);
  116. $v{'values'} = [ $parts[0], $parts[1], $parts[2] ];
  117. plugin_dispatch_values(\%v);
  118. #####################################################################
  119. # processes
  120. my $ps_states = { 'paging' => 0, 'blocked' => 0, 'zombies' => 0, 'stopped' => 0,
  121. 'running' => 0, 'sleeping' => 0 };
  122. my $state_map = { 'R' => 'running', 'S' => 'sleeping', 'D' => 'blocked',
  123. 'Z' => 'zombies', 'T' => 'stopped', 'W' => 'paging' };
  124. $v{'plugin'} = 'processes';
  125. delete $v{'plugin_instance'};
  126. $v{'type'} = 'ps_state';
  127. @lines = map { (split)[2] } split(/\n/, `$vzctl exec $veid cat '/proc/[0-9]*/stat'`);
  128. foreach $key (@lines)
  129. {
  130. ++$ps_states->{$state_map->{$key}};
  131. }
  132. foreach $key (keys %{$ps_states})
  133. {
  134. $v{'type_instance'} = $key;
  135. $v{'values'} = [ $ps_states->{$key} ];
  136. plugin_dispatch_values(\%v);
  137. }
  138. #####################################################################
  139. # users
  140. $v{'plugin'} = 'users';
  141. delete $v{'plugin_instance'};
  142. $v{'type'} = 'users';
  143. delete $v{'type_instance'};
  144. @lines = split(/\n/, `$vzctl exec $veid w -h`);
  145. $v{'values'} = [ scalar(@lines) ];
  146. plugin_dispatch_values(\%v);
  147. }
  148. return 1;
  149. }
  150. plugin_register(TYPE_READ, 'OpenVZ', 'openvz_read');
  151. return 1;