2
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2018-11-08 00:59:34 +01:00

netstat_bsd_s: adding Linux support

* limited Linux support: TCP only, a few stats yet
This commit is contained in:
Artem Sheremet 2013-04-04 10:00:56 +03:00
parent 6efcb06dd9
commit 302641b091
6 changed files with 67 additions and 25 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View file

@ -1,14 +1,15 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
# netstat_bsd_s revision 2 (Mar 2012) # netstat_s revision 4 (Apr 2013)
# #
# This plugin shows various statistics from 'netstat -s' # This plugin shows various statistics from 'netstat -s'
# #
# Required privileges: none # Required privileges: none
# #
# OS: # OS:
# Supposed: BSD # Supposed: BSD, Linux
# Tested: FreeBSD 8.2 # Tested: FreeBSD: 8.2, 8.3
# Linux : Debian 6 (kernel 2.6.32), Arch (kernel 3.8.3), CentOS 6
# #
# Author: Artem Sheremet <dot.doom@gmail.com> # Author: Artem Sheremet <dot.doom@gmail.com>
# #
@ -17,8 +18,9 @@
#%# capabilities=autoconf suggest #%# capabilities=autoconf suggest
# original filename # original filename
PLUGIN_NAME = 'netstat_bsd_s_' PLUGIN_NAME = 'netstat_s_'
$os = `uname -s`.strip.downcase.to_sym
$debug_mode = ARGV.first == 'debug' $debug_mode = ARGV.first == 'debug'
class String class String
@ -31,6 +33,12 @@ class String
self[0...str.size] == str self[0...str.size] == str
end end
end end
unless method_defined? :lines
def lines
self.split($/).to_enum
end
end
end end
class Graph class Graph
@ -46,8 +54,8 @@ class Graph
multigraphs = {} multigraphs = {}
@parse_expr.each { |expr, descr| @parse_expr.each { |expr, descr|
descr.each { |entry| descr.each { |entry|
labels_array = (multigraphs[entry.first] ||= []) labels_array = (multigraphs[entry[0]] ||= [])
labels_array.push entry.last labels_array.push entry[1]
} }
} }
@ -112,15 +120,42 @@ end
def graphs_for(protocol) def graphs_for(protocol)
case protocol case protocol
# order of the graps in each section is important for parsing. # Order of the graps in each section is important for parsing.
# At the same time, it is not important for munin, so we are OK placing it in parsing order here. # At the same time, it is not important for munin, so we are OK placing it in parsing order here.
when 'tcp' when 'tcp'
[ $os == :linux ? [
Graph.new('sent', protocol, [ Graph.new('sent', protocol, [
# for each match of the regexp, there is a matching entry in the array. # Description of the elements of arrays below:
# First element of an entry is unit name, and the second is label. # 0: regexp to parse the line
# 1: Array<Array[2]> for each matching group in the regular expression.
# The first element for a group is unit name, the second is the label.
# It could be reasonable to add third etc as warning and critical values. # It could be reasonable to add third etc as warning and critical values.
[ /(\d+) segments send out$/, [ [ :segments, 'total' ] ] ],
[ /(\d+) segments retransmited$/, [ [ :segments, 'retransmitted' ] ] ]
]),
Graph.new('received', protocol, [
[ /(\d+) segments received$/, [ [ :segments, 'total' ] ] ],
[ /(\d+) bad segments received.$/, [ [ :segments, 'bad' ] ] ]
]),
Graph.new('connections', protocol, [
[ /(\d+) active connections openings$/, [ [ :connections, 'active openings' ] ] ],
[ /(\d+) passive connection openings$/, [ [ :connections, 'passive openings' ] ] ],
[ /(\d+) failed connection attempts$/, [ [ :connections, 'failed attempts' ] ] ],
[ /(\d+) connection resets received$/, [ [ :connections, 'RST received' ] ] ],
[ /(\d+) connections established$/, [ [ :connections, 'established' ] ] ],
[ /(\d+) resets sent$/, [ [ :connections, 'RST sent' ] ] ]
]),
Graph.new('timeouts', protocol, [
[ /(\d+) timeouts after SACK recovery$/, [ [ :segments, 'after SACK recovery' ] ] ],
[ /(\d+) other TCP timeouts$/, [ [ :segments, 'other TCP' ] ] ],
[ /(\d+) timeouts in loss state$/, [ [ :segments, 'in a loss state' ] ] ]
])
] : [
Graph.new('sent', protocol, [
[ /(\d+) packets sent$/, [ [ :packets, 'total' ] ] ], [ /(\d+) packets sent$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) data packets \((\d+) bytes\)$/, [ [ :packets, 'data' ], [ :bytes, 'data' ] ] ], [ /(\d+) data packets \((\d+) bytes\)$/, [ [ :packets, 'data' ], [ :bytes, 'data' ] ] ],
[ /(\d+) data packets \((\d+) bytes\) retransmitted$/, [ [ :packets, 'retransmitted' ], [ :bytes, 'retransmitted' ] ] ], [ /(\d+) data packets \((\d+) bytes\) retransmitted$/, [ [ :packets, 'retransmitted' ], [ :bytes, 'retransmitted' ] ] ],
@ -148,7 +183,7 @@ def graphs_for(protocol)
[ /(\d+) window update packets$/, [ [ :packets, 'window update' ] ] ], [ /(\d+) window update packets$/, [ [ :packets, 'window update' ] ] ],
[ /(\d+) packets received after close$/, [ [ :packets, 'after close' ] ] ], [ /(\d+) packets received after close$/, [ [ :packets, 'after close' ] ] ],
[ /(\d+) discarded for bad checksums$/, [ [ :packets, 'bad checksums' ] ] ], [ /(\d+) discarded for bad checksums$/, [ [ :packets, 'bad checksums' ] ] ],
[ /(\d+) discarded for bad header offset field$/, [ [ :packets, 'bad header offset flds' ] ] ], [ /(\d+) discarded for bad header offset fields?$/, [ [ :packets, 'bad header offset flds' ] ] ],
[ /(\d+) discarded because packet too short$/, [ [ :packets, 'too short' ] ] ], [ /(\d+) discarded because packet too short$/, [ [ :packets, 'too short' ] ] ],
[ /(\d+) discarded due to memory problems$/, [ [ :packets, 'discarded: memory problems' ] ] ], [ /(\d+) discarded due to memory problems$/, [ [ :packets, 'discarded: memory problems' ] ] ],
[ /(\d+) ignored RSTs in the windows$/, [ [ :packets, 'ignored RSTs in windows' ] ] ], [ /(\d+) ignored RSTs in the windows$/, [ [ :packets, 'ignored RSTs in windows' ] ] ],
@ -200,6 +235,8 @@ def graphs_for(protocol)
[ /(\d+) badack$/, [ [ :entries, 'bad ACK' ] ] ], [ /(\d+) badack$/, [ [ :entries, 'bad ACK' ] ] ],
[ /(\d+) unreach$/, [ [ :entries, 'unreachable' ] ] ], [ /(\d+) unreach$/, [ [ :entries, 'unreachable' ] ] ],
[ /(\d+) zone failures$/, [ [ :entries, 'zone failures' ] ] ], [ /(\d+) zone failures$/, [ [ :entries, 'zone failures' ] ] ],
[ /(\d+) hostcache entries added$/, [ [ :entries, 'hostcache added' ] ] ],
[ /(\d+) bucket overflow$/, [ [ :entries, 'hostcache overflow' ] ] ]
]), ]),
Graph.new('SACK', protocol, [ Graph.new('SACK', protocol, [
@ -220,7 +257,8 @@ def graphs_for(protocol)
]) ])
] ]
when 'udp' when 'udp'
[ $os == :linux ? [
] : [
Graph.new('received', protocol, [ Graph.new('received', protocol, [
[ /(\d+) datagrams received$/, [ [ :packets, 'total' ] ] ], [ /(\d+) datagrams received$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) with incomplete header$/, [ [ :packets, 'incomplete header' ] ] ], [ /(\d+) with incomplete header$/, [ [ :packets, 'incomplete header' ] ] ],
@ -240,7 +278,8 @@ def graphs_for(protocol)
]) ])
] ]
when 'ip' when 'ip'
[ $os == :linux ? [
] : [
Graph.new('received', protocol, [ Graph.new('received', protocol, [
[ /(\d+) total packets received$/, [ [ :packets, 'total' ] ] ], [ /(\d+) total packets received$/, [ [ :packets, 'total' ] ] ],
[ /(\d+) bad header checksums$/, [ [ :packets, 'bad header checksum' ] ] ], [ /(\d+) bad header checksums$/, [ [ :packets, 'bad header checksum' ] ] ],
@ -276,7 +315,7 @@ def graphs_for(protocol)
]) ])
] ]
when 'arp' when 'arp'
[ $os == :linux ? [] : [
Graph.new('sent', protocol, [ Graph.new('sent', protocol, [
[ /(\d+) ARP requests sent$/, [ [ :packets, 'requests' ] ] ], [ /(\d+) ARP requests sent$/, [ [ :packets, 'requests' ] ] ],
[ /(\d+) ARP replies sent$/, [ [ :packets, 'replies' ] ] ] [ /(\d+) ARP replies sent$/, [ [ :packets, 'replies' ] ] ]
@ -302,21 +341,21 @@ proto_name.slice! 0, PLUGIN_NAME.size if proto_name.start_with? PLUGIN_NAME
proto_name = 'tcp' if proto_name.empty? proto_name = 'tcp' if proto_name.empty?
def netstat_s_protocols
`netstat -s`.select { |line|
line =~ /^\w+:$/
}.map! { |proto| proto.strip[0..-2] }
end
def netstat_s(protocol) def netstat_s(protocol)
`netstat -sp #{protocol}`.select { |line| not line.start_with? protocol } if $os == :linux
%w(tcp udp).include?(protocol) ?
`netstat -s --#{protocol}` :
`netstat -s --raw`
else
`netstat -sp #{protocol}`
end.lines.reject { |line| line =~ /^\w+:/ }
end end
case ARGV.first case ARGV.first
when 'autoconf' when 'autoconf'
puts `uname -s`.include?('FreeBSD') ? 'yes' : 'no' puts [:linux, :freebsd].include?($os) ? 'yes' : 'no'
when 'suggest' when 'suggest'
puts netstat_s_protocols.map(&:escape).join $/ puts $os == :linux ? %w(tcp) : %w(tcp udp ip arp)
when 'config' when 'config'
graphs_for(proto_name).each { |graph| graphs_for(proto_name).each { |graph|
puts graph.config.join $/ puts graph.config.join $/
@ -329,3 +368,6 @@ else
warn "not parsed:\n#{data.join}" unless data.empty? if $debug_mode warn "not parsed:\n#{data.join}" unless data.empty? if $debug_mode
end end
# awful performance when scrolling through those regexps above
# vim: syntax=none

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB