source: noc/ng/bin/insert.pl @ 965

Last change on this file since 965 was 42, checked in by presbrey, 18 years ago
scripts.mit.edu NOC graphing
File size: 4.7 KB
Line 
1#!/usr/bin/perl
2
3# File:    $Id: insert.pl,v 1.17 2005/10/26 14:42:57 sauber Exp $
4# Author:  (c) Soren Dossing, 2005
5# License: OSI Artistic License
6#          http://www.opensource.org/licenses/artistic-license.php
7
8use strict;
9use RRDs;
10
11# Configuration
12my $configfile = '/home/noc/ng/etc/nagiosgraph.conf';
13
14# Main program - change nothing below
15
16my %Config;
17
18# Read in config file
19#
20sub readconfig {
21  die "config file not found" unless -r $configfile;
22
23  # Read configuration data
24  open FH, $configfile;
25    while (<FH>) {
26      s/\s*#.*//;    # Strip comments
27      /^(\w+)\s*=\s*(.*?)\s*$/ and do {
28        $Config{$1} = $2;
29        debug(5, "INSERT Config $1:$2");
30      };
31    }
32  close FH;
33
34  # Make sure log file can be written to
35  die "Log file $Config{logfile} not writable" unless -w $Config{logfile};
36
37  # Make sure rrddir exist and is writable
38  unless ( -w $Config{rrddir} ) {
39    mkdir $Config{rrddir};
40    die "rrd dir $Config{rrddir} not writable" unless -w $Config{rrddir};
41  }
42}
43
44# Parse performance data from input
45#
46sub parseinput {
47  my $data = shift;
48  #debug(5, "INSERT perfdata: $data");
49  my @d = split( /\|\|/, $data);
50  return ( lastcheck    => $d[0],
51           hostname     => $d[1],
52           servicedescr => $d[2],
53           output       => $d[3],
54           perfdata     => $d[4],
55         );
56}
57
58# Write debug information to log file
59#
60sub debug { 
61  my($l, $text) = @_;
62  if ( $l <= $Config{debug} ) {
63    $l = qw(none critical error warn info debug)[$l];
64    $text =~ s/(\w+)/$1 $l:/;
65    open LOG, ">>$Config{logfile}";
66      print LOG scalar localtime;
67      print LOG " $text\n";
68    close LOG;
69  }
70}
71
72# Dump to log the files read from Nagios
73#
74sub dumpperfdata {
75  my %P = @_;
76  for ( keys %P ) {
77    debug(4, "INSERT Input $_:$P{$_}");
78  }
79}
80
81# URL encode a string
82#
83sub urlencode {
84  $_[0] =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
85  return $_[0];
86}
87
88# Create new rrd databases if necessary
89#
90sub createrrd {
91  my($host,$service,$start,$labels) = @_;
92  my($f,$v,$t,$ds,$db);
93
94  $db = shift @$labels;
95  $f = urlencode("${host}_${service}_${db}") . '.rrd';
96  debug(5, "INSERT Checking $Config{rrddir}/$f");
97  unless ( -e "$Config{rrddir}/$f" ) {
98    $ds = "$Config{rrddir}/$f --start $start";
99    for ( @$labels ) {
100      ($v,$t) = ($_->[0],$_->[1]);
101      my $u = $t eq 'DERIVE' ? '0' : 'U' ;
102      $ds .= " DS:$v:$t:$Config{heartbeat}:$u:U";
103    }
104    $ds .= " RRA:AVERAGE:0.5:1:600";
105    $ds .= " RRA:AVERAGE:0.5:6:700";
106    $ds .= " RRA:AVERAGE:0.5:24:775";
107    $ds .= " RRA:AVERAGE:0.5:288:797";
108
109    my @ds = split /\s+/, $ds;
110    debug(4, "INSERT RRDs::create $ds");
111    RRDs::create(@ds);
112    debug(2, "INSERT RRDs::create ERR " . RRDs::error) if RRDs::error;
113  }
114  return $f;
115}
116
117# Use RRDs to update rrd file
118#
119sub rrdupdate {
120  my($file,$time,$values) = @_;
121  my($ds,$c);
122
123  $ds = "$Config{rrddir}/$file $time";
124  for ( @$values ) {
125    $_->[2] ||= 0;
126    $ds .= ":$_->[2]";
127  }
128
129  my @ds = split /\s+/, $ds;
130  debug(4, "INSERT RRDs::update ". join ' ', @ds);
131  RRDs::update(@ds);
132  debug(2, "INSERT RRDs::update ERR " . RRDs::error) if RRDs::error;
133}
134
135# See if we can recognize any of the data we got
136#
137sub parseperfdata {
138  my %P = @_;
139
140  $_="servicedescr:$P{servicedescr}\noutput:$P{output}\nperfdata:$P{perfdata}";
141  evalrules($_);
142}
143
144# Check that we have some data to work on
145#
146sub inputdata {
147  my @inputlines;
148  if ( $ARGV[0] ) {
149    @inputlines = $ARGV[0];
150  } elsif ( defined $Config{perflog} ) {
151    open PERFLOG, $Config{perflog};
152      @inputlines = <PERFLOG>;
153    close PERFLOG
154  }
155
156  # Quit if there are no data to process
157  unless ( @inputlines ) {
158    debug(4, 'INSERT No inputdata. Exiting.');
159    exit 1;
160  }
161  return @inputlines;
162}
163
164# Process all input performance data
165#
166sub processdata {
167  my @perfdatalines = @_;
168  for my $l ( @perfdatalines ) {
169    debug(5, "INSERT processing perfdata: $l");
170    my %P = parseinput($l);
171    dumpperfdata(%P);
172    my $S = parseperfdata(%P);
173    for my $s ( @$S ) {
174      my $rrd = createrrd($P{hostname}, $P{servicedescr}, $P{lastcheck}-1, $s);
175      rrdupdate($rrd, $P{lastcheck}, $s);
176    }
177  }
178}
179
180### Main loop
181#  - Read config and input
182#  - Update rrd files
183#  - Create them first if necesary.
184
185readconfig();
186debug(5, 'INSERT nagiosgraph spawned');
187my @perfdata = inputdata();
188
189# Read the map file and define a subroutine that parses performance data
190my($rules);
191undef $/;
192open FH, $Config{mapfile};
193  $rules = <FH>;
194close FH;
195$rules = '
196sub evalrules {
197  $_=$_[0];
198  my @s;
199  no strict "subs";
200' . $rules . '
201  use strict "subs";
202  debug(3, "INSERT perfdata not recognized") unless @s;
203  return \@s;
204}';
205undef $@;
206eval $rules;
207debug(2, "INSERT Map file eval error: $@") if $@;
208
209processdata( @perfdata );
210debug(5, 'INSERT nagiosgraph exited');
Note: See TracBrowser for help on using the repository browser.