author | Mahlon E. Smith <mahlon@martini.nu> |
Tue, 27 Mar 2018 14:27:31 -0700 | |
changeset 5 | 6cf2c60c80f7 |
parent 4 | 1801334b8dc4 |
child 6 | f82534b40e06 |
permissions | -rw-r--r-- |
0 | 1 |
# -*- ruby -*- |
2 |
# vim: set noet nosta sw=4 ts=4 : |
|
3 |
# encoding: utf-8 |
|
4 |
# |
|
5 |
# This library parses fping output when provided a list of nodes to |
|
6 |
# monitor. Require it from your monitor file(s), and call the Arborist |
|
7 |
# exec() with this class -- that's it. |
|
8 |
# |
|
9 |
# require 'arborist/monitor/fping' |
|
10 |
# |
|
11 |
# Arborist::Monitor 'ping check' do |
|
12 |
# every 20.seconds |
|
13 |
# match type: 'host' |
|
14 |
# exec 'fping', '-e', '-t', '150' |
|
15 |
# exec_callbacks( Arborist::Monitor::FPing ) |
|
16 |
# end |
|
17 |
||
18 |
||
19 |
require 'loggability' |
|
20 |
require 'arborist/monitor' unless defined?( Arborist::Monitor ) |
|
21 |
||
22 |
# Parse Fping output for better batch ICMP checks. |
|
23 |
# |
|
24 |
module Arborist::Monitor::FPing |
|
25 |
extend Loggability |
|
26 |
log_to :arborist |
|
27 |
||
28 |
# The version of this library. |
|
5
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
29 |
VERSION = '0.2.0' |
1
69f2ba4d4d93
Use the new #node_properties method.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
30 |
|
69f2ba4d4d93
Use the new #node_properties method.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
31 |
# Always request the node addresses. |
69f2ba4d4d93
Use the new #node_properties method.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
32 |
USED_PROPERTIES = [ :addresses ].freeze |
69f2ba4d4d93
Use the new #node_properties method.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
33 |
|
69f2ba4d4d93
Use the new #node_properties method.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
34 |
### Return the properties used by this monitor. |
69f2ba4d4d93
Use the new #node_properties method.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
35 |
def self::node_properties |
69f2ba4d4d93
Use the new #node_properties method.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
36 |
return USED_PROPERTIES |
69f2ba4d4d93
Use the new #node_properties method.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
37 |
end |
0 | 38 |
|
39 |
attr_accessor :identifiers |
|
40 |
||
5
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
41 |
### Arborist::Monitor API: Send addresses to the fping binary, after |
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
42 |
### creating a map to re-associate them back to identifiers. |
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
43 |
### |
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
44 |
def exec_input( nodes, io ) |
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
45 |
self.log.debug "Building fping input for %d nodes" % [ nodes.size ] |
0 | 46 |
self.identifiers = nodes.each_with_object({}) do |(identifier, props), hash| |
47 |
next unless props.key?( 'addresses' ) |
|
48 |
address = props[ 'addresses' ].first |
|
49 |
hash[ address ] = identifier |
|
5
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
50 |
self.log.debug "%s -> %s" % [ identifier, address ] |
0 | 51 |
end |
52 |
||
5
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
53 |
return if self.identifiers.empty? |
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
54 |
|
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
55 |
self.identifiers.keys.each{|ip| io.puts(ip) } |
0 | 56 |
end |
57 |
||
5
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
58 |
|
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
59 |
### Parse fping output, return a hash of RTT data, along |
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
60 |
### with any detected errors. |
6cf2c60c80f7
Provide fping addresses via pipe, instead of an argument list.
Mahlon E. Smith <mahlon@martini.nu>
parents:
4
diff
changeset
|
61 |
### |
0 | 62 |
def handle_results( pid, stdout, stderr ) |
63 |
# 8.8.8.8 is alive (32.1 ms) |
|
64 |
# 8.8.4.4 is alive (14.9 ms) |
|
65 |
# 8.8.0.1 is unreachable |
|
66 |
||
67 |
return stdout.each_line.with_object({}) do |line, hash| |
|
68 |
address, remainder = line.split( ' ', 2 ) |
|
69 |
identifier = self.identifiers[ address ] or next |
|
70 |
||
71 |
if remainder =~ /is alive \((\d+\.\d+) ms\)/ |
|
72 |
hash[ identifier ] = { rtt: Float( $1 ) } |
|
73 |
else |
|
74 |
hash[ identifier ] = { error: remainder.chomp } |
|
75 |
end |
|
76 |
end |
|
77 |
end |
|
78 |
end # Arborist::Monitor::FPing |
|
79 |