Projet

Général

Profil

Révision b71bbedc

IDb71bbedc1631eac8cdefeab0712f7467a1913200
Parent 96996d28
Enfant 6462587e

Ajouté par Chris Hastie il y a presque 14 ans

Initial version

Voir les différences:

plugins/other/ntp_peers
1
#!/usr/bin/perl -w
2

  
3
# Plugin to monitor offsets to multiple NTP peers.
4
# NB currently only works for IPv4 peers
5
#
6
# (c)2008 Chris Hastie: chris (at) oak (hyphen) wood (dot) co (dot) uk
7
#
8
# Parameters understood:
9
#
10
# 	config   (required)
11
# 	autoconf (optional - used by munin-node-configure)
12
#
13
# Config variables:
14
#
15
#       ntpq            - path to ntpq program
16
#       statedir        - directory in which to place state file
17
#       hostname_<key>  - override hostname for peer <key>. <key> is
18
#                         an IPv4 address with dots replaced by underscores.
19
#                         Useful for reference clocks, eg
20
#                         env.hostname_127_127_43_0  .GPS.
21
#
22
#
23
# This program is free software: you can redistribute it and/or modify
24
# it under the terms of the GNU General Public License as published by
25
# the Free Software Foundation, either version 3 of the License, or
26
# (at your option) any later version.
27
#
28
# This program is distributed in the hope that it will be useful,
29
# but WITHOUT ANY WARRANTY; without even the implied warranty of
30
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31
# GNU General Public License for more details.
32
#
33
# You should have received a copy of the GNU General Public License
34
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
35
#
36
# Change log
37
# v1.0.0    2008-07-21        Chris Hastie
38
# initial release 
39
#
40
#
41
#
42
# Magic markers - optional - used by installation scripts and
43
# munin-node-configure:
44
#
45
#%# family=contrib
46
#%# capabilities=autoconf
47
#
48

  
49
use strict;
50
use Socket;
51

  
52
my $NTPQ = $ENV{ntpq} || "ntpq";
53
my $COMMAND    =      "$NTPQ -np";
54

  
55
my $statedir = $ENV{statedir} || '/usr/local/var/munin/plugin-state';
56
my $statefile = "$statedir/ntp_peers.state";
57

  
58
# autoconf
59
if ($ARGV[0] and $ARGV[0] eq "autoconf") {
60
	`$NTPQ -c help >/dev/null 2>/dev/null`;
61
	if ($? eq "0") {
62
		if (`$NTPQ -np | wc -l` > 0) {
63
			print "yes\n";
64
			exit 0;
65
		} else {
66
			print "no (unable to list peers)\n";
67
			exit 1;
68
		}
69
	} else {
70
		print "no (ntpq not found)\n";
71
		exit 1;
72
	}
73
}
74

  
75
my %peers;
76

  
77
# retrieve cached list of IPs and hostnames
78
if (-f "$statefile") {
79
    open (IN, "$statefile") or exit 4;
80
    while (<IN>) {
81
      if (/^([0-9\.]+):(.*)$/) {
82
        $peers{$1}{'name'} = $2;
83
      }
84
    }
85
    close IN;
86
}
87

  
88

  
89
# do custom IP lookups
90
for my $key (map {/^hostname_(.+)/} keys %ENV) {
91
    my $ip = &desanitize_field($key);
92
    $peers{$ip}{'name'} = $ENV{"hostname_$key"}
93
}
94

  
95
# get data from ntpq
96
open(SERVICE, "$COMMAND |")
97
  or die("Could not execute '$COMMAND': $!");
98

  
99
while (<SERVICE>) {
100
    if (/^[-+*#](\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\s+\S+){7}\s+(\S+)/) {
101
      my $name  = &lookupname($1);
102
      $peers{$1}{'value'} = $3;      
103
    }
104
}
105
close(SERVICE);
106

  
107
# config
108
if ($ARGV[0] and $ARGV[0] eq 'config') {
109
  print "graph_title NTP peer offsets\n";
110
  print "graph_args --base 1000\n";
111
  print "graph_vlabel ms\n";
112
  print "graph_category ntp\n";
113
  print "graph_info Offset (in ms) to the server's NTP peers\n";
114
  print "graph_order ";
115
  foreach my $key (sort by_name keys %peers) {
116
    print &sanitize_field($peers{$key}{'name'}) . " ";
117
  }
118
  print "\n";
119
  foreach my $peer (keys %peers) {
120
    print &sanitize_field($peers{$peer}{'name'}) . ".label " . $peers{$peer}{'name'} . "\n";
121
  }
122
  exit 0;
123
}
124

  
125
# send output
126
foreach my $peer (keys %peers) {
127
  print &sanitize_field($peers{$peer}{'name'}) . ".value " . &getpeeroffset($peer) . "\n";
128
}
129

  
130
# save list of peer IPs and hostnames
131
if(-l $statefile) {
132
	die("$statefile is a symbolic link, refusing to touch it.");
133
}				
134
open (OUT, ">$statefile") or exit 4;
135
foreach my $i (keys %peers) {
136
  print OUT "$i:" . $peers{$i}{'name'} .  "\n";
137
}
138
close OUT;
139

  
140
# sorts by hostname
141
sub by_name {
142
	return $peers{$a}{'name'} cmp $peers{$b}{'name'};
143
}
144

  
145
# create a valid munin field name from the hostname
146
sub sanitize_field () {
147
  my $field = shift;
148
  
149
  # replace illegal characters with an underscore
150
  $field =~ s/[^A-Za-z0-9_]/_/g;
151
  # prepend an underscore if name starts with a number
152
  $field =~ s/^([^A-Za-z_])/_$1/;
153
  
154
  # truncate to 19 characters
155
  if (length($field) > 19) {
156
    $field = substr($field, 0, 19);
157
  }
158
  return $field
159
}
160

  
161
# get an IP address from the underscore escaped
162
# value of env.hostname_<key>
163
sub desanitize_field () {
164
  my $field = shift;
165
  $field =~ s/_/\./g;
166
  return $field
167
}
168

  
169
# lookup hostnames
170
sub lookupname () {
171
  my $ip = shift;
172
  # have we already got it?
173
  if ($peers{$ip}{'name'}) {
174
    return $peers{$ip}{'name'};    
175
  }
176
  # else look it up
177
  my $iaddr = inet_aton($ip); 
178
  my $name  = gethostbyaddr($iaddr, AF_INET) || $ip; 
179
  # add to cache
180
  $peers{$ip}{'name'} = $name;
181
  return $name;
182
}
183

  
184
# returns the offset, or U if it is undefined
185
sub getpeeroffset() {
186
  my $ip = shift;
187
  my $rtn = 'U';
188
  if (exists($peers{$ip}{'value'})) {
189
    $rtn = $peers{$ip}{'value'};
190
  }
191
  return $rtn
192
}
193

  
194
=pod
195

  
196
=head1 Description
197

  
198
ntp_peers - A munin plugin to monitor offsets to multiple NTP peers and
199
graph them on a single graph
200

  
201
=head1 Parameters understood:
202

  
203
  config   (required)
204
  autoconf (optional - used by munin-node-configure)
205

  
206
=head1 Configuration variables:
207

  
208
All configuration parameters are optional
209

  
210
  ntpq            - path to ntpq program
211
  statedir        - directory in which to place state file
212
  hostname_<key>  - override hostname for peer <key>. <key> is
213
                    an IPv4 address with dots replaced by underscores.
214
                    Useful for reference clocks, eg
215
                    env.hostname_127_127_43_0  .GPS.
216

  
217
=head1 Known issues
218

  
219
ntp_peers will not monitor IPv6 peers
220

  
221
=cut

Formats disponibles : Unified diff