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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +1 -0
- data.tar.gz.sig +2 -0
- data/CHANGELOG.md +8 -0
- data/LICENSE +22 -0
- data/README.md +71 -0
- data/bin/check-banner.rb +88 -0
- data/bin/check-multicast-groups.rb +77 -0
- data/bin/check-netstat-tcp.rb +128 -0
- data/bin/check-ping.rb +105 -0
- data/bin/check-ports.rb +91 -0
- data/bin/check-rbl.rb +102 -0
- data/bin/metrics-interface.rb +83 -0
- data/bin/metrics-net.rb +92 -0
- data/bin/metrics-netif.rb +55 -0
- data/bin/metrics-netstat-tcp.rb +110 -0
- data/bin/metrics-sockstat.rb +75 -0
- data/lib/sensu-plugins-network-checks.rb +7 -0
- metadata +287 -0
- metadata.gz.sig +2 -0
data/bin/check-ports.rb
ADDED
@@ -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
|
data/bin/check-rbl.rb
ADDED
@@ -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
|
data/bin/metrics-net.rb
ADDED
@@ -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
|