class Riemann::Tools::Net

Constants

FREEBSD_MAPPING

Public Class Methods

new() click to toggle source
# File lib/riemann/tools/net.rb, line 14
def initialize
  @old_state = nil
  @interfaces = if opts[:interfaces]
                  opts[:interfaces].reject(&:empty?).map(&:dup)
                else
                  []
                end
  @ignore_interfaces = opts[:ignore_interfaces].reject(&:empty?).map(&:dup)

  ostype = `uname -s`.chomp.downcase
  case ostype
  when 'freebsd'
    @state = method :freebsd_state
  else
    puts "WARNING: OS '#{ostype}' not explicitly supported. Falling back to Linux" unless ostype == 'linux'
    @state = method :linux_state
  end
end

Public Instance Methods

freebsd_state() click to toggle source
# File lib/riemann/tools/net.rb, line 52
def freebsd_state
  require 'json'

  state = {}

  all_stats = JSON.parse(`netstat -inb --libxo=json`)
  all_stats.dig('statistics', 'interface').select { |s| s['mtu'] }.each do |interface_stats|
    next unless report_interface?(interface_stats['name'])

    FREEBSD_MAPPING.each do |key, service|
      state["#{interface_stats['name']} #{service}"] = interface_stats[key]
    end
  end

  state
end
linux_state() click to toggle source
# File lib/riemann/tools/net.rb, line 69
def linux_state
  f = File.read('/proc/net/dev')
  state = {}
  f.split("\n").each do |line|
    next unless line =~ /\A\s*([[:alnum:]-]+?):\s*([\s\d]+)\s*/

    iface = Regexp.last_match(1)

    next unless report_interface?(iface)

    ['rx bytes',
     'rx packets',
     'rx errs',
     'rx drop',
     'rx fifo',
     'rx frame',
     'rx compressed',
     'rx multicast',
     'tx bytes',
     'tx packets',
     'tx errs',
     'tx drop',
     'tx fifo',
     'tx colls',
     'tx carrier',
     'tx compressed',].map do |service|
      "#{iface} #{service}"
    end.zip( # rubocop:disable Style/MultilineBlockChain
      Regexp.last_match(2).split(/\s+/).map(&:to_i),
    ).each do |service, value|
      state[service] = value
    end
  end

  state
end
report_interface?(iface) click to toggle source
# File lib/riemann/tools/net.rb, line 33
def report_interface?(iface)
  if !@interfaces.empty?
    @interfaces.any? { |pattern| iface.match?(pattern) }
  else
    @ignore_interfaces.none? { |pattern| iface.match?(pattern) }
  end
end
tick() click to toggle source
# File lib/riemann/tools/net.rb, line 106
def tick
  state = @state.call

  if @old_state
    # Report services from `@old_state` that don't exist in `state` as expired
    @old_state.reject { |k| state.key?(k) }.each_key do |service|
      report(service: service.dup, state: 'expired')
    end

    # Report delta for services that have values in both `@old_state` and `state`
    state.each do |service, metric|
      next unless @old_state.key?(service)

      delta = metric - @old_state[service]
      svc_state = case service
                  when /drop$/
                    if delta.positive?
                      'warning'
                    else
                      'ok'
                    end
                  when /errs$/
                    if delta.positive?
                      'warning'
                    else
                      'ok'
                    end
                  else
                    'ok'
                  end

      report(
        service: service.dup,
        metric: (delta.to_f / opts[:interval]),
        state: svc_state,
      )
    end
  end

  @old_state = state
end