PageRenderTime 57ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/backend/lib/remOcular/Plugin/Top.pm

https://github.com/oetiker/remOcular
Perl | 229 lines | 189 code | 29 blank | 11 comment | 5 complexity | e5d89ae6ba5a3c0753e08b995442968a MD5 | raw file
  1. package remOcular::Plugin::Top;
  2. use strict;
  3. use base 'remOcular::Plugin';
  4. use Sys::Hostname;
  5. =head1 NAME
  6. remOcular::Plugin::Top - Top the Process Monitor
  7. =head1 SYNOPSIS
  8. use remOcular::Plugin::Top
  9. =head1 DESCRIPTION
  10. Run the top process monitor
  11. =cut
  12. use Carp;
  13. use vars qw($VERSION);
  14. '$Revision: 363 $ ' =~ /Revision: (\S*)/;
  15. my $VERSION = "0.$1";
  16. sub get_config {
  17. my $self = shift;
  18. return {
  19. menu => 'Top',
  20. title=> "Top Process Monitor",
  21. form_type => 'top',
  22. form=> [
  23. {
  24. type=> 'Spinner',
  25. label=> 'Interval',
  26. name=> 'interval',
  27. min => 1,
  28. max => 60,
  29. initial=> 5,
  30. required=> 1,
  31. },
  32. {
  33. type=> 'CheckBox',
  34. label=> 'Show Threads',
  35. name=> 'threads',
  36. initial=> 0
  37. },
  38. ],
  39. byline => qq{Version $VERSION, 2009-12-11, by Tobi Oetiker},
  40. link => qq{http://tobi.oetiker.ch},
  41. about => <<ABOUT_END,
  42. Online variant of <code>top</code> the unix commandline process viewer.
  43. ABOUT_END
  44. }
  45. }
  46. sub check_params {
  47. my $self = shift;
  48. my $params = shift;
  49. my $error;
  50. if (int($params->{interval}||0) < 1){
  51. return "Interval must be at least 1 second";
  52. }
  53. return {
  54. table => [
  55. {
  56. label => 'PID',
  57. tooltip => 'Process ID',
  58. width => 2,
  59. },
  60. {
  61. label => 'USER',
  62. tooltip => 'User ID',
  63. width => 2,
  64. },
  65. {
  66. label => 'PR',
  67. tooltip => 'Priority',
  68. width => 1,
  69. },
  70. {
  71. label => 'NI',
  72. tooltip => 'Nice Level',
  73. width => 1,
  74. },
  75. {
  76. label => 'VIRT',
  77. tooltip => 'Virtual Memory',
  78. width => 3,
  79. },
  80. {
  81. label => 'RES',
  82. tooltip => 'Resident Memory',
  83. width => 3,
  84. },
  85. {
  86. label => 'SHR',
  87. tooltip => 'Shared Memory',
  88. width => 3,
  89. },
  90. {
  91. label => 'S',
  92. tooltip => 'State (D = uninterruptible sleep, R = running, S = sleeping, T = traced or stopped, Z = zombie',
  93. width => 1,
  94. },
  95. {
  96. label => 'CPU',
  97. tooltip => 'CPU Usage',
  98. width => 1,
  99. },
  100. {
  101. label => 'CPU Spark',
  102. width => 4,
  103. data => {
  104. processor => 'STACK',
  105. source_col => 8,
  106. key_col => 0,
  107. depth => 30
  108. },
  109. presentation => {
  110. renderer => 'SPARKLINE',
  111. line_color => '#484',
  112. spark_color => '#f00',
  113. line_width => 0.5,
  114. spark_radius => 1,
  115. single_scale => 1
  116. }
  117. },
  118. {
  119. label => 'MEM',
  120. tooltip => 'Memory Usage (RES)',
  121. width => 2,
  122. },
  123. {
  124. label => 'TIME',
  125. tooltip => 'Total CPU Time' ,
  126. width => 3,
  127. },
  128. {
  129. label => 'COMMAND',
  130. tooltip => 'Command Line',
  131. width => 4,
  132. }
  133. ],
  134. title => "Top Processes on ".hostname(),
  135. interval => int($params->{interval})*1000,
  136. }
  137. }
  138. sub start_instance {
  139. my $self = shift;
  140. my $outfile = shift;
  141. my $params = shift;
  142. open(my $fh,'-|','/usr/bin/top','-b','-d',int($params->{interval}),
  143. ($params->{threads} ? '-H' : ())) or do {
  144. $self->append_data($outfile,"#ERROR\t$!\n");
  145. return;
  146. };
  147. my $data = "#CLEAR\n";
  148. my $ok = 0;
  149. while(<$fh>){
  150. chomp;
  151. s/^\s+//;
  152. s/\s+$//;
  153. if (/^\d+/){
  154. $ok = 1;
  155. $data .= join("\t", "#PUSH", split(/\s+/,$_,12))."\n";
  156. }
  157. if ($ok and /^\s*$/){
  158. my $ratio = $self->append_data($outfile,$data);
  159. # it seems noone is reading us anymore, so stop;
  160. if ($ratio < 0.2){
  161. unlink $outfile;
  162. exit 0;
  163. }
  164. $ok = 0;
  165. $data = "#CLEAR\n";
  166. }
  167. }
  168. $self->append_data($outfile,"#STOP\n");
  169. }
  170. 1;
  171. __END__
  172. =back
  173. =head1 COPYRIGHT
  174. Copyright (c) 2009-2011 by OETIKER+PARTNER AG. All rights reserved.
  175. =head1 LICENSE
  176. This program is free software: you can redistribute it and/or modify
  177. it under the terms of the GNU General Public License as published by
  178. the Free Software Foundation, either version 3 of the License, or
  179. (at your option) any later version.
  180. This program is distributed in the hope that it will be useful,
  181. but WITHOUT ANY WARRANTY; without even the implied warranty of
  182. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  183. GNU General Public License for more details.
  184. You should have received a copy of the GNU General Public License
  185. along with this program. If not, see <http://www.gnu.org/licenses/>.
  186. =head1 AUTHOR
  187. S<Tobias Oetiker E<lt>tobi@oetiker.chE<gt>>
  188. =head1 HISTORY
  189. 2009-11-06 to 1.0 first version
  190. =cut
  191. # Emacs Configuration
  192. #
  193. # Local Variables:
  194. # mode: cperl
  195. # eval: (cperl-set-style "PerlStyle")
  196. # mode: flyspell
  197. # mode: flyspell-prog
  198. # End:
  199. #
  200. # vi: sw=4 et