Guest User

Untitled

a guest
Dec 13th, 2012
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.72 KB | None | 0 0
  1. Скрипт для xymon. Мониторит состояние агентов puppet. Запускаться должен на хосте с puppet master'ом.
  2. http://www.linux.org.ru/forum/admin/8588141
  3.  
  4. #!/usr/bin/perl
  5.  
  6. # author: Oleg Korchagin
  7. # license: GPL v2 or newer
  8.  
  9. use strict;
  10. use Storable;
  11. use Data::Dumper;
  12. use Time::Local;
  13. use Getopt::Std;
  14. use Getopt::Long;
  15.  
  16. my $store_file='/usr/lib/xymon/client/data/check_puppet_log.store';
  17. my $puppet_log_file='/var/log/messages';
  18.  
  19. # $data - data to load from and safe to $store_file
  20. # structure:
  21. # {
  22. #   pos - last position in $puppet_log_file
  23. #   agents  => {
  24. #       $agent  => {
  25. #           last_manifest_require   - last request of manifest, in unixtime
  26. #           last_compile_time   - last catalog coptile time for this node
  27. #           last_apply_time - last manifest apply time on this node
  28. #       }
  29. #   }
  30. # }
  31. my $data;
  32.  
  33. my $warn_last_require = 3600;
  34. my $err_last_require = 5400;
  35.  
  36. my $warn_compile = 10;
  37. my $err_compile = 60;
  38.  
  39. my $warn_apply = 200;
  40. my $err_apply = 600;
  41.  
  42. my $host = $ENV{'MACHINE'} ? $ENV{'MACHINE'} : 'vml-puppet';
  43. my $test = "puppet_agents";
  44.  
  45. my $version = '0.1a';
  46.  
  47. # - file
  48. # - position
  49. sub go_last_pos($$) {
  50.    my ( $FILE, $pos ) = @_;
  51.  
  52.    # check size
  53.    seek( $FILE, 0, 2); # go to end of file
  54.  
  55.    seek( $FILE, tell($FILE) < $pos ? 0 : $pos, 0); # go to last position, if no logrotate. Or to start of file
  56. }
  57.  
  58. # convert time to unixtime. string example:
  59. #  Dec  9 03:33:01 vml-puppet-test rsyslogd:
  60. sub str2ut($) {
  61.    my $time_shift = 0;
  62.    my %m=(
  63.        "Jan" => 0, "Feb"=>1,"Mar"=>2,"Apr"=>3,"May"=>4,"Jun"=>5,"Jul"=>6, "Aug"=>7,"Sep"=>8,"Oct"=>9,"Nov"=>10,"Dec"=>11,
  64.        "Янв"   => 0, "Фев" => 1, "Мар" => 2, "Апр" => 3, "Май" => 4, "Июн" => 5, "Июл" => 6, "Авг" => 7, "Сен" => 8, "Окт" => 9, "Ноя" => 10, "Дек" => 11
  65.    );
  66.    $_[0] =~ /^(\S{3,6})\s+([0-9]{1,2})\s+([0-9]{2}):([0-9]{2}):([0-9]{2})\s/ || print "can't decode date$_[0]";
  67.    my ( $year, $month, $day, $hour, $min, $sec ) = (0,$m{$1},$2,$3,$4,$5);
  68.  
  69.    my ( $now_year, $now_month ) = ( localtime())[5,4];
  70.    $year = $now_year;
  71.    if ( $now_month != $month ) {
  72.        $year--;
  73.    }
  74.  
  75.    return timelocal($sec,$min,$hour,$day,$month,$year) + $time_shift * 60 * 60;
  76. }
  77.  
  78. sub ut2str ($) {
  79.    my @tmp_time=(localtime $_[0])[5,4,3,2,1,0];
  80.    $tmp_time[0]+=1900;
  81.    $tmp_time[1]+=1;
  82.    #if ( $_[1] ) { $tmp_time[3] += $_[1] }
  83.    return sprintf("%.4d/%.2d/%.2d %.2d:%.2d:%.2d", @tmp_time);
  84. }
  85.  
  86. # - delta
  87. # - err
  88. # - warn
  89. sub check_val($$$) {
  90.    my ( $val, $err, $warn) = @_;
  91.    my $color = 'green';
  92.  
  93.    if ( $val > $err ) {
  94.        $color = 'red';
  95.    } elsif ( $val > $warn ) {
  96.        $color = 'yellow';
  97.    }
  98.  
  99.    return $color;
  100. }
  101.  
  102. # - list of colors
  103. sub worst_color(@) {
  104.    my $color='green';
  105.    while (my $tmp_color = shift) {
  106.        if ( $tmp_color eq 'red' ) {
  107.            $color = 'red'
  108.        } elsif ( ( $tmp_color eq 'yellow' ) and ( $color ne 'red' ) ) {
  109.            $color = 'yellow'
  110.        }
  111.    }
  112.    return $color;
  113. }
  114.  
  115. # - hostname
  116. sub init_agent_data($) {
  117.    my $agent = shift;
  118.    if ( not exists $data->{'agents'}->{$agent} ){
  119.        $data->{'agents'}->{$agent}  = {
  120.            'last_manifest_require' => 0,
  121.            'last_compile_time' => 0,
  122.            'last_apply_time'   => 0,
  123.        }
  124.    }
  125. }
  126.  
  127. sub init_data() {
  128.    print "WARN: initialize data\n";
  129.    $data = {
  130.        'pos'   => '0',
  131.        'agents'    => {
  132.        }
  133.    };
  134. }
  135.  
  136. sub send_xymon($){
  137.    my $report = $_[0];
  138.    my $xymon = $ENV{'XYMON'} ? $ENV{'XYMON'} : '/usr/lib/xymon/server/bin/xymon';
  139.    my $xymsrv = $ENV{'XYMSRV'} ? $ENV{'XYMSRV'} : '10.1.200.35';
  140.    system "$xymon $xymsrv \"$report\""
  141. }
  142.  
  143. die "must be run from xymon" if not $ENV{'XYMON'};
  144.  
  145. # parse cli options
  146. my $agent_to_delete;
  147. Getopt::Long::Configure ('bundling');
  148. GetOptions (
  149.     'd=s'   => \$agent_to_delete,
  150. );
  151.  
  152. # load data
  153. if ( not -f $store_file ) {
  154.     # file does not exist, initialize $data
  155.     init_data();
  156.     store($data, $store_file);
  157. }
  158. $data = retrieve($store_file);
  159. init_data unless $data; # load was not successfull, initialize data
  160.  
  161. # delete node data, if required
  162. if ( $agent_to_delete ) {
  163.     delete $data->{'agents'}->{$agent_to_delete};
  164. }
  165.  
  166. # parse log
  167. open my $LOG, $puppet_log_file;
  168. go_last_pos($LOG, $data->{'pos'});
  169.  
  170. while ($_=<$LOG>) {
  171.     if ( m/Compiled catalog for (\S+) .* in ([0-9\.]+) seconds$/  ) {
  172.         my $agent = $1;
  173.         init_agent_data($agent);
  174.         $data->{'agents'}->{$agent}->{'last_compile_time'} = $2;
  175.         $data->{'agents'}->{$agent}->{'last_manifest_require'} = str2ut($_);
  176.     } elsif ( m/\(\/\/(\S+?)\/Puppet\) Finished catalog run in ([0-9\.]+) seconds$/ ) {
  177.         my $agent = $1;
  178.         init_agent_data($agent);
  179.         $data->{'agents'}->{$agent}->{'last_apply_time'} = $2;
  180.     }
  181. }
  182.  
  183. # save position
  184. $data->{'pos'} = tell($LOG);
  185. close $LOG;
  186.  
  187. #print (Dumper($data), "\n");
  188.  
  189. # analyze data and print result;
  190. my $now = time();
  191. my @colors;
  192. my $message;
  193.  
  194. $message .= "<table border=1 cellpadding=5>\n<tr><td>agent</td><td>last catalog request</td><td>catalog compile time</td><td>manifest apply time</td></tr>\n";
  195. foreach my $agent ( sort  keys %{ $data->{'agents'} } ) {
  196.     my ($color_req, $color_cmp, $color_apl) = ('green', 'green', 'green');
  197.     my $val;
  198.  
  199.     $val = $now - $data->{'agents'}->{$agent}->{'last_manifest_require'};
  200.     $color_req = check_val($val, $err_last_require, $warn_last_require);
  201.  
  202.     $val = $data->{'agents'}->{$agent}->{'last_compile_time'};
  203.     $color_cmp = check_val($val, $err_compile, $warn_compile);
  204.  
  205.     $val = $data->{'agents'}->{$agent}->{'last_apply_time'};
  206.     $color_apl = check_val($val, $err_apply, $warn_apply);
  207.  
  208.     my $color = worst_color($color_req, $color_cmp, $color_apl);
  209.     push @colors, $color;
  210.  
  211.     $message .= sprintf ("<tr><td>%s</td>", $agent);
  212.     $message .= sprintf ("<td>&%s %10d sec ago (%-20s)</td>",
  213.         $color_req,
  214.         $now - $data->{'agents'}->{$agent}->{'last_manifest_require'} ,
  215.         ut2str ( $data->{'agents'}->{$agent}->{'last_manifest_require'} )
  216.     );
  217.     $message .= sprintf ( "<td>&%s %s</td>",
  218.         $color_cmp, $data->{'agents'}->{$agent}->{'last_compile_time'}
  219.     );
  220.     $message .= sprintf ("<td>&%s %s</td></tr>\n",
  221.         $color_apl, $data->{'agents'}->{$agent}->{'last_apply_time'}
  222.     );
  223.  
  224. }
  225. $message .= "</table>\n";
  226. $message .= "check_puppet_log.pl, v$version";
  227.  
  228. #send_xymon sprintf ( "status %s.%s %s %s\n%s", $host, $test, worst_color(@colors), ut2str($now), $message  );
  229. send_xymon sprintf ( "status %s.%s %s %s\n%s", $host, $test, worst_color(@colors), ut2str($now), $message  );
  230.  
  231. # save data
  232. store($data, $store_file);
Advertisement
Add Comment
Please, Sign In to add comment