#! /usr/bin/env ruby # frozen_string_literal: true # # metrics-ping # # DESCRIPTION: # This plugin pings a host and outputs ping statistics # # OUTPUT: # .packets_transmitted 5 1437137076 # .packets_received 5 1437137076 # .packet_loss 0 1437137076 # .time 3996 1437137076 # .min 0.016 1437137076 # .max 0.017 1437137076 # .avg 0.019 1437137076 # .mdev 0.004 1437137076 # # PLATFORMS: # Linux # # DEPENDENCIES: # gem: sensu-plugin # gem: open3 # # WARNING: # This plugins requires `ping` binary from `iputils-ping` package. # `ping` binary from `inetutils-ping` package produces incompatible # output. For more info see: # https://github.com/sensu-plugins/sensu-plugins-network-checks/issues/26 # # USAGE: # ./metric-ping --host --count \ # --timeout --scheme # # NOTES: # # LICENSE: # Copyright 2015 Rob Wilson # Released under the same terms as Sensu (the MIT license); see LICENSE # for details. # require 'sensu-plugin/metric/cli' require 'socket' require 'open3' class PingMetrics < Sensu::Plugin::Metric::CLI::Graphite option :scheme, description: 'Metric naming scheme, text to prepend to metric', short: '-s SCHEME', long: '--scheme SCHEME', default: "#{Socket.gethostname}.ping" option :host, description: 'Host to ping', short: '-h HOST', long: '--host HOST', default: 'localhost' option :count, description: 'Ping count', short: '-c COUNT', long: '--count COUNT', default: 5 option :timeout, description: 'Timeout', short: '-t TIMEOUT', long: '--timeout TIMEOUT', default: 5 OVERVIEW_METRICS = %i[packets_transmitted packets_received packet_loss time].freeze STATISTIC_METRICS = %i[min avg max mdev].freeze FLOAT = '(\d+\.\d+)'.freeze def overview @ping.split("\n")[-2].scan(/^(\d+) packets transmitted, (\d+) received, (\d+)% packet loss, time (\d+)ms/)[0] end def statistics @ping.split("\n")[-1].scan(/^rtt min\/avg\/max\/mdev = #{FLOAT}\/#{FLOAT}\/#{FLOAT}\/#{FLOAT} ms/)[0] end def results Hash[OVERVIEW_METRICS.zip(overview)].merge Hash[STATISTIC_METRICS.zip(statistics)] end def timestamp @timestamp ||= Time.now.to_i end def write_output results.each { |metric, value| output "#{config[:scheme]}.#{metric} #{value} #{timestamp}" } end def ping @ping, @status = Open3.capture2e("ping -W#{config[:timeout]} -c#{config[:count]} #{config[:host]}") end def validate critical "ping error: unable to ping #{config[:host]}" unless @status.success? end def run ping validate write_output ok end end