sensu-plugins-network-checks 0.0.1.alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,91 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-ports
4
+ #
5
+ # DESCRIPTION:
6
+ # Fetch port status using nmap. This check is good for catching bad network ACLs
7
+ # or service down events for network resources.
8
+ #
9
+ # OUTPUT:
10
+ # plain text
11
+ #
12
+ # PLATFORMS:
13
+ # Linux, Windows, BSD, Solaris, etc
14
+ #
15
+ # DEPENDENCIES:
16
+ # gem: sensu-plugin
17
+ # gem: open3
18
+ # gem: json
19
+ # nmap
20
+ #
21
+ # USAGE:
22
+ # $ ./check-ports.rb --host some_server --ports 5671,5672 --level crit
23
+ #
24
+ # NOTES:
25
+ # #YELLOW
26
+ # Look at rewriting this using the namp library to not depend on external tools
27
+ #
28
+ # LICENSE:
29
+ # Copyright 2013 GoDaddy.com, LLC <jjmanzer@godaddy.com>
30
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
31
+ # for details.
32
+ #
33
+
34
+ require 'open3'
35
+ require 'sensu-plugin/check/cli'
36
+ require 'json'
37
+
38
+ # CheckPorts
39
+ class CheckPorts < Sensu::Plugin::Check::CLI
40
+ option :host,
41
+ description: 'Resolving name or IP address of target host',
42
+ short: '-h HOST',
43
+ long: '--host HOST',
44
+ default: 'localhost'
45
+
46
+ option :ports,
47
+ description: 'TCP port(s) you wish to get status for',
48
+ short: '-t PORT,PORT...',
49
+ long: '--ports PORT,PORT...'
50
+
51
+ option :level,
52
+ description: 'Alert level crit(critical) or warn(warning)',
53
+ short: '-l crit|warn',
54
+ long: '--level crit|warn',
55
+ default: 'WARN'
56
+
57
+ def run # rubocop:disable all
58
+ stdout, stderr = Open3.capture3(
59
+ ENV,
60
+ "nmap -P0 -p #{ config[:ports] } #{ config[:host] }"
61
+ )
62
+
63
+ case stderr
64
+ when /Failed to resolve/
65
+ critical 'cannot resolve the target hostname'
66
+ end
67
+
68
+ port_checks = {}
69
+ check_pass = true
70
+
71
+ stdout.split("\n").each do |line|
72
+ line.scan(/(\d+).tcp\s+(\w+)\s+(\w+)/).each do |status|
73
+ port_checks[status[1]] ||= []
74
+ port_checks[status[1]].push status[0]
75
+ check_pass = false unless status[1]['open']
76
+ end
77
+ end
78
+
79
+ result = port_checks.map { |state, ports| "#{ state }:#{ ports.join(',') }" }.join(' ')
80
+
81
+ if check_pass
82
+ ok result
83
+ elsif config[:level].upcase == 'WARN'
84
+ warning result
85
+ elsif config[:level].upcase == 'CRIT'
86
+ critical result
87
+ else
88
+ unknown "Unknown alert level #{config[:level]}"
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,102 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # check-rbl
4
+ #
5
+ # DESCRIPTION:
6
+ # Checks if a ip is blacklisted in the common dns blacklists. You can
7
+ # add a list
8
+ #
9
+ # OUTPUT:
10
+ # plain text
11
+ #
12
+ # PLATFORMS:
13
+ # Linux
14
+ #
15
+ # DEPENDENCIES:
16
+ # gem: sensu-plugin
17
+ # gem: dnsbl-client
18
+ #
19
+ # USAGE:
20
+ #
21
+ # NOTES:
22
+ # A list of DNS blacklists to not be checked can be passed with -I as a
23
+ # comma-separated list.
24
+ #
25
+ # LICENSE:
26
+ # Copyright 2012 Sarguru Nathan <sarguru90@gmail.com>
27
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
28
+ # for details.
29
+ #
30
+
31
+ require 'sensu-plugin/check/cli'
32
+ require 'dnsbl-client'
33
+ require 'set'
34
+
35
+ #
36
+ # Rbl Check
37
+ #
38
+ class RblCheck < Sensu::Plugin::Check::CLI
39
+ option :ip,
40
+ short: '-i IPADDRESS',
41
+ long: '--ip IPADDRESS',
42
+ description: 'IP of the server to check'
43
+
44
+ option :ignored_bls,
45
+ short: '-I BLACKLISTNAME',
46
+ long: '--ignored_bls BLACKLISTNAME',
47
+ description: 'Comma Separated String of ignored blacklists from default list',
48
+ default: 'null'
49
+
50
+ option :critical_bls,
51
+ short: '-C BLACKLISTNAME',
52
+ long: '--critical_bls BLACKLISTNAME',
53
+ description: 'Comma Separated String of critical blacklists from default list',
54
+ default: 'null'
55
+
56
+ def run # rubocop:disable all
57
+ c = DNSBL::Client.new
58
+
59
+ if config[:ip]
60
+ ip_add = config[:ip]
61
+ else
62
+ critical 'plugin failed. Required Argument -i (ip address of the client)'
63
+ end
64
+
65
+ if config[:ignored_bls]
66
+ ignored_bls = config[:ignored_bls]
67
+ ignored_bls_set = ignored_bls.split(',').to_set
68
+ end
69
+
70
+ if config[:critical_bls]
71
+ critical_bls = config[:critical_bls]
72
+ critical_bls_set = critical_bls.split(',').to_set
73
+ end
74
+
75
+ dnsbl_ret = c.lookup("#{ip_add}")
76
+ msg_string = ''
77
+ criticality = 0
78
+
79
+ # #YELLOW
80
+ dnsbl_ret.each do |dnsbl_result| # rubocop:disable Style/Next
81
+ if dnsbl_result.meaning =~ /spam/i || dnsbl_result.meaning =~ /blacklist/i
82
+ unless ignored_bls_set.member?(dnsbl_result.dnsbl)
83
+ msg_string = "#{msg_string} #{dnsbl_result.dnsbl}"
84
+ end
85
+
86
+ criticality += 1 if critical_bls_set.member?(dnsbl_result.dnsbl)
87
+ end
88
+ end
89
+
90
+ # YELLOW
91
+ unless msg_string.empty? # rubocop:disable UnlessElse
92
+ if criticality > 0
93
+ critical "#{ip_add} Blacklisted in#{msg_string}"
94
+ else
95
+ warning "#{ip_add} Blacklisted in#{msg_string}"
96
+ end
97
+ else
98
+ msg_txt = "All is well. #{ip_add} has good reputation."
99
+ ok "#{msg_txt}"
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,83 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ #
4
+ # interface-metrics
5
+ #
6
+ # DESCRIPTION:
7
+ #
8
+ # OUTPUT:
9
+ # metric data
10
+ #
11
+ # PLATFORMS:
12
+ # Linux
13
+ #
14
+ # DEPENDENCIES:
15
+ # gem: sensu-plugin
16
+ # gem: socket
17
+ #
18
+ # USAGE:
19
+ #
20
+ # NOTES:
21
+ #
22
+ # LICENSE:
23
+ # Copyright 2012 Sonian, Inc <chefs@sonian.net>
24
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
25
+ # for details.
26
+ #
27
+
28
+ require 'sensu-plugin/metric/cli'
29
+ require 'socket'
30
+
31
+ #
32
+ # Interface Graphite
33
+ #
34
+ class InterfaceGraphite < Sensu::Plugin::Metric::CLI::Graphite
35
+ option :scheme,
36
+ description: 'Metric naming scheme, text to prepend to metric',
37
+ short: '-s SCHEME',
38
+ long: '--scheme SCHEME',
39
+ default: "#{Socket.gethostname}.interface"
40
+
41
+ option :excludeinterface,
42
+ description: 'List of interfaces to exclude',
43
+ short: '-x INTERFACE[,INTERFACE]',
44
+ long: '--exclude-interface',
45
+ proc: proc { |a| a.split(',') }
46
+
47
+ def run # rubocop:disable all
48
+ # Metrics borrowed from hoardd: https://github.com/coredump/hoardd
49
+
50
+ metrics = %w(rxBytes
51
+ rxPackets
52
+ rxErrors
53
+ rxDrops
54
+ rxFifo
55
+ rxFrame
56
+ rxCompressed
57
+ rxMulticast
58
+ txBytes
59
+ txPackets
60
+ txErrors
61
+ txDrops
62
+ txFifo
63
+ txColls
64
+ txCarrier
65
+ txCompressed)
66
+
67
+ File.open('/proc/net/dev', 'r').each_line do |line|
68
+ interface, stats_string = line.scan(/^\s*([^:]+):\s*(.*)$/).first
69
+ next if config[:excludeinterface] && config[:excludeinterface].find { |x| line.match(x) }
70
+ next unless interface
71
+ if interface.is_a?(String)
72
+ interface = interface.gsub('.', '_')
73
+ end
74
+
75
+ stats = stats_string.split(/\s+/)
76
+ next if stats == ['0'].cycle.take(stats.size)
77
+
78
+ metrics.size.times { |i| output "#{config[:scheme]}.#{interface}.#{metrics[i]}", stats[i] }
79
+ end
80
+
81
+ ok
82
+ end
83
+ end
@@ -0,0 +1,92 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # metrics-net
4
+ #
5
+ # DESCRIPTION:
6
+ # Simple plugin that fetchs metrics from all interfaces
7
+ # on the box using the /sys/class interface.
8
+ #
9
+ # Use the data with graphite's `nonNegativeDerivative()` function
10
+ # to construct per-second graphs for your hosts.
11
+ #
12
+ # Loopback iface (`lo`) is ignored.
13
+ #
14
+ # Compat
15
+ # ------
16
+ #
17
+ # This plugin uses the `/sys/class/net/<iface>/statistics/{rx,tx}_*`
18
+ # files to fetch stats. On older linux boxes without /sys, this same
19
+ # info can be fetched from /proc/net/dev but additional parsing
20
+ # will be required.
21
+ #
22
+ # OUTPUT:
23
+ # metric data
24
+ #
25
+ # PLATFORMS:
26
+ # Linux
27
+ #
28
+ # DEPENDENCIES:
29
+ # gem: sensu-plugin
30
+ # gem: <?>
31
+ #
32
+ # USAGE:
33
+ # $ ./metrics-packets.rb --scheme servers.web01
34
+ # servers.web01.eth0.tx_packets 982965 1351112745
35
+ # servers.web01.eth0.rx_packets 1180186 1351112745
36
+ # servers.web01.eth1.tx_packets 273936669 1351112745
37
+ # servers.web01.eth1.rx_packets 563787422 1351112745
38
+ #
39
+ # NOTES:
40
+ # Does it behave differently on specific platforms, specific use cases, etc
41
+ #
42
+ # LICENSE:
43
+ # Copyright 2012 Joe Miller <https://github.com/joemiller>
44
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
45
+ # for details.
46
+ #
47
+
48
+ require 'sensu-plugin/metric/cli'
49
+ require 'socket'
50
+
51
+ #
52
+ # Linux Packet Metrics
53
+ #
54
+ class LinuxPacketMetrics < Sensu::Plugin::Metric::CLI::Graphite
55
+ option :scheme,
56
+ description: 'Metric naming scheme, text to prepend to metric',
57
+ short: '-s SCHEME',
58
+ long: '--scheme SCHEME',
59
+ default: "#{Socket.gethostname}.net"
60
+
61
+ def run # rubocop:disable all
62
+ timestamp = Time.now.to_i
63
+
64
+ Dir.glob('/sys/class/net/*').each do |iface_path|
65
+ next if File.file?(iface_path)
66
+ iface = File.basename(iface_path)
67
+ next if iface == 'lo'
68
+
69
+ tx_pkts = File.open(iface_path + '/statistics/tx_packets').read.strip
70
+ rx_pkts = File.open(iface_path + '/statistics/rx_packets').read.strip
71
+ tx_bytes = File.open(iface_path + '/statistics/tx_bytes').read.strip
72
+ rx_bytes = File.open(iface_path + '/statistics/rx_bytes').read.strip
73
+ tx_errors = File.open(iface_path + '/statistics/tx_errors').read.strip
74
+ rx_errors = File.open(iface_path + '/statistics/rx_errors').read.strip
75
+
76
+ begin
77
+ if_speed = File.open(iface_path + '/speed').read.strip
78
+ rescue
79
+ if_speed = 0
80
+ end
81
+
82
+ output "#{config[:scheme]}.#{iface}.tx_packets", tx_pkts, timestamp
83
+ output "#{config[:scheme]}.#{iface}.rx_packets", rx_pkts, timestamp
84
+ output "#{config[:scheme]}.#{iface}.tx_bytes", tx_bytes, timestamp
85
+ output "#{config[:scheme]}.#{iface}.rx_bytes", rx_bytes, timestamp
86
+ output "#{config[:scheme]}.#{iface}.tx_errors", tx_errors, timestamp
87
+ output "#{config[:scheme]}.#{iface}.rx_errors", rx_errors, timestamp
88
+ output "#{config[:scheme]}.#{iface}.if_speed", if_speed, timestamp
89
+ end
90
+ ok
91
+ end
92
+ end
@@ -0,0 +1,55 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # netif-metrics
4
+ #
5
+ # DESCRIPTION:
6
+ # Network interface throughput
7
+ #
8
+ # OUTPUT:
9
+ # metric data
10
+ #
11
+ # PLATFORMS:
12
+ # Linux
13
+ #
14
+ # DEPENDENCIES:
15
+ # gem: sensu-plugin
16
+ # gem: socket
17
+ #
18
+ # USAGE:
19
+ # #YELLOW
20
+ #
21
+ # NOTES:
22
+ #
23
+ # LICENSE:
24
+ # Copyright 2014 Sonian, Inc. and contributors. <support@sensuapp.org>
25
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
26
+ # for details.
27
+ #
28
+
29
+ require 'sensu-plugin/metric/cli'
30
+ require 'socket'
31
+
32
+ #
33
+ # Netif Metrics
34
+ #
35
+ class NetIFMetrics < Sensu::Plugin::Metric::CLI::Graphite
36
+ option :scheme,
37
+ description: 'Metric naming scheme, text to prepend to .$parent.$child',
38
+ long: '--scheme SCHEME',
39
+ default: "#{Socket.gethostname}"
40
+
41
+ def run # rubocop:disable all
42
+ # #YELLOW
43
+ `sar -n DEV 1 1 | grep Average | grep -v IFACE`.each_line do |line| # rubocop:disable Style/Next
44
+ stats = line.split(/\s+/)
45
+ unless stats.empty?
46
+ stats.shift
47
+ nic = stats.shift
48
+ output "#{config[:scheme]}.#{nic}.rx_kB_per_sec", stats[2].to_f if stats[3]
49
+ output "#{config[:scheme]}.#{nic}.tx_kB_per_sec", stats[3].to_f if stats[3]
50
+ end
51
+ end
52
+
53
+ ok
54
+ end
55
+ end
@@ -0,0 +1,110 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # metrics-netstat-tcp
4
+ #
5
+ # DESCRIPTION:
6
+ # Fetch metrics on TCP socket states from netstat. This is particularly useful
7
+ # on high-traffic web or proxy servers with large numbers of short-lived TCP
8
+ # connections coming and going.
9
+ #
10
+ # OUTPUT:
11
+ # metric data
12
+ #
13
+ # PLATFORMS:
14
+ # Linux
15
+ #
16
+ # DEPENDENCIES:
17
+ # gem: sensu-plugin
18
+ # gem: <?>
19
+ #
20
+ # USAGE:
21
+ # $ ./metrics-netstat-tcp.rb --scheme servers.hostname
22
+ # servers.hostname.UNKNOWN 0 1350496466
23
+ # servers.hostname.ESTABLISHED 235 1350496466
24
+ # servers.hostname.SYN_SENT 0 1350496466
25
+ # servers.hostname.SYN_RECV 1 1350496466
26
+ # servers.hostname.FIN_WAIT1 0 1350496466
27
+ # servers.hostname.FIN_WAIT2 53 1350496466
28
+ # servers.hostname.TIME_WAIT 10640 1350496466
29
+ # servers.hostname.CLOSE 0 1350496466
30
+ # servers.hostname.CLOSE_WAIT 7 1350496466
31
+ # servers.hostname.LAST_ACK 1 1350496466
32
+ # servers.hostname.LISTEN 16 1350496466
33
+ # servers.hostname.CLOSING 0 1350496466
34
+ #
35
+ # NOTES:
36
+ # - Code for parsing Linux /proc/net/tcp from Anthony Goddard's ruby-netstat:
37
+ # https://github.com/agoddard/ruby-netstat
38
+ #
39
+ # LICENSE:
40
+ # Copyright 2012 Joe Miller <https://github.com/joemiller>
41
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
42
+ # for details.
43
+ #
44
+
45
+ require 'sensu-plugin/metric/cli'
46
+ require 'socket'
47
+
48
+ TCP_STATES = {
49
+ '00' => 'UNKNOWN', # Bad state ... Impossible to achieve ...
50
+ 'FF' => 'UNKNOWN', # Bad state ... Impossible to achieve ...
51
+ '01' => 'ESTABLISHED',
52
+ '02' => 'SYN_SENT',
53
+ '03' => 'SYN_RECV',
54
+ '04' => 'FIN_WAIT1',
55
+ '05' => 'FIN_WAIT2',
56
+ '06' => 'TIME_WAIT',
57
+ '07' => 'CLOSE',
58
+ '08' => 'CLOSE_WAIT',
59
+ '09' => 'LAST_ACK',
60
+ '0A' => 'LISTEN',
61
+ '0B' => 'CLOSING'
62
+ }
63
+
64
+ #
65
+ # Netstat TCP Metrics
66
+ #
67
+ class NetstatTCPMetrics < Sensu::Plugin::Metric::CLI::Graphite
68
+ option :scheme,
69
+ description: 'Metric naming scheme, text to prepend to metric',
70
+ short: '-s SCHEME',
71
+ long: '--scheme SCHEME',
72
+ default: "#{Socket.gethostname}.tcp"
73
+
74
+ option :port,
75
+ description: 'Port you wish to get metrics for',
76
+ short: '-p PORT',
77
+ long: '--port PORT',
78
+ proc: proc(&:to_i)
79
+
80
+ def netstat(protocol = 'tcp') # rubocop:disable all
81
+ state_counts = Hash.new(0)
82
+ TCP_STATES.each_pair { |_hex, name| state_counts[name] = 0 }
83
+
84
+ # #YELLOW
85
+ File.open('/proc/net/' + protocol).each do |line| # rubocop:disable Style/Next
86
+ line.strip!
87
+ if m = line.match(/^\s*\d+:\s+(.{8}):(.{4})\s+(.{8}):(.{4})\s+(.{2})/) # rubocop:disable AssignmentInCondition
88
+ connection_state = m[5]
89
+ connection_port = m[2].to_i(16)
90
+ connection_state = TCP_STATES[connection_state]
91
+ if config[:port] && config[:port] == connection_port
92
+ state_counts[connection_state] += 1
93
+ elsif !config[:port]
94
+ state_counts[connection_state] += 1
95
+ end
96
+ end
97
+ end
98
+ state_counts
99
+ end
100
+
101
+ def run
102
+ timestamp = Time.now.to_i
103
+ netstat('tcp').each do |state, count|
104
+ graphite_name = config[:port] ? "#{config[:scheme]}.#{config[:port]}.#{state}" :
105
+ "#{config[:scheme]}.#{state}"
106
+ output "#{graphite_name}", count, timestamp
107
+ end
108
+ ok
109
+ end
110
+ end