Repository
Munin (contrib)
Last change
2020-08-25
Graph Categories
Family
auto
Capabilities
Keywords
Language
Ruby
Authors

netstat_bsd_m_

Example graph: day

Sadly there is no documentation for this plugin.

#!/usr/bin/env ruby

=begin

netstat_bsd_m revision 1 (Feb 2012)

This plugin shows various statistics from 'netstat -m'

Required privileges: none

OS:
  Supposed: BSD
  Tested:   FreeBSD 8.2

Author: Artem Sheremet <dot.doom@gmail.com>

#%# family=auto
#%# capabilities=autoconf suggest

=end

# original filename
PLUGIN_NAME = 'netstat_bsd_m_'.freeze

class String
  def escape
    gsub(/[^\w]/, '_')
  end

  unless method_defined? :start_with?
    def start_with?(str)
      self[0...str.size] == str
    end
  end
end

def netstat_m(filter = nil)
  Hash[`netstat -m`.split($/).map do |line|
    if line =~ %r{^([\d/K]+) (.*) \(([\w/+]+)\)$}
      # 7891K/22385K/30276K bytes allocated to network (current/cache/total)
      values = Regexp.last_match(1)
      desc = Regexp.last_match(2)
      names = Regexp.last_match(3)
      [desc, names.split('/').zip(values.split('/'))] if filter.nil? || (desc.escape == filter)
    elsif line =~ /^(\d+) (.*)$/
      # 12327 requests for I/O initiated by sendfile
      value = Regexp.last_match(1)
      desc = Regexp.last_match(2)
      [desc, [[:value, value]]] if filter.nil? || (desc.escape == filter)
    end
  end.compact]
end

stat_name = File.basename($0, '.*').escape
stat_name.slice! 0, PLUGIN_NAME.size if stat_name.start_with? PLUGIN_NAME

case ARGV.first
when 'autoconf'
  puts `uname -s`.include?('FreeBSD') ? 'yes' : 'no'
when 'suggest'
  puts netstat_m.keys.map(&:escape).join $/
when 'config'
  data = netstat_m(stat_name)
  if data.empty?
    warn "no data for <#{stat_name}>. Try running with 'suggest'"
  else
    desc, values = data.first
    stack = values.size > 1
    first = true
    puts <<~CONFIG
      graph_title Netstat: #{desc}
      graph_category network
      graph_vlabel current
      graph_order #{values.map { |name, _| name.to_s.escape }.join ' '}
    CONFIG
    puts values.map { |name, _|
      esc_name = name.to_s.escape
      "#{esc_name}.draw " + if %w[total max].include? name
                              'LINE'
                            elsif stack
                              if first
                                first = false
                                'AREA'
                              else
                                'STACK'
                              end
                            else
                              'LINE2'
      end + "\n#{esc_name}.label #{name}"
    }.join $/
  end
when nil # fetch
  data = netstat_m(stat_name)
  unless data.empty?
    puts data.first.last.map { |name, value|
      value = value.to_i * 1024 if value.end_with? 'K'
      "#{name.to_s.escape}.value #{value}"
    }.join $/
  end
else
  warn "unrecognized argument <#{ARGV.first}>"
end