sensu-plugins/sensu-plugins-ceph

View on GitHub
bin/metrics-ceph.rb

Summary

Maintainability
A
1 hr
Test Coverage
#! /usr/bin/env ruby
#
# metrics-ceph
#
# DESCRIPTION:
#   Overall ceph throughput
#
# OUTPUT:
#   metric data
#
# PLATFORMS:
#   Linux
#
# DEPENDENCIES:
#   gem: sensu-plugin
#   gem: english
#   ceph client
#
# USAGE:
#   #YELLOW
#
# NOTES:
#   Runs 'ceph status' command to output cluster status and metrics,
#   May need read access to ceph keyring and/or root access for
#   authentication.
#
# LICENSE:
#   Released under the same terms as Sensu (the MIT license); see LICENSE
#   for details.
#

require 'sensu-plugin/metric/cli'
require 'json'
require 'timeout'
require 'English'
require 'socket'

class CephMetrics < Sensu::Plugin::Metric::CLI::Graphite
  option :keyring,
         description: 'Path to cephx authentication keyring file',
         short: '-k KEY',
         long: '--keyring',
         proc: proc { |k| " -k #{k}" }

  option :monitor,
         description: 'Optional monitor IP',
         short: '-m MON',
         long: '--monitor',
         proc: proc { |m| " -m #{m}" }

  option :cluster,
         description: 'Optional cluster name',
         short: '-c NAME',
         long: '--cluster',
         proc: proc { |c| " --cluster=#{c}" }

  option :name,
         description: 'Optional client name',
         short: '-n NAME',
         long: '--name',
         proc: proc { |n| " --name=#{n}" }

  option :timeout,
         description: 'Timeout (default 10)',
         short: '-t SEC',
         long: '--timeout',
         proc: proc(&:to_i),
         default: 10

  option :prefix,
         description: 'Metric prefix',
         short: '-p PREFIX',
         long: '--prefix',
         default: "#{Socket.gethostname}.ceph"

  def run_cmd(cmd)
    pipe, status = nil
    begin
      cmd += config[:cluster] if config[:cluster]
      cmd += config[:keyring] if config[:keyring]
      cmd += config[:monitor] if config[:monitor]
      cmd += config[:name] if config[:name]
      Timeout.timeout(config[:timeout]) do
        pipe = IO.popen(cmd)
        Process.wait(pipe.pid)
        status = $CHILD_STATUS.exitstatus
      end
    rescue Timeout::Error
      begin
        Process.kill(9, pipe.pid)
        Process.wait(pipe.pid)
      rescue Errno::ESRCH, Errno::EPERM
        # Catch errors from trying to kill the timed-out process
        # We must do something here to stop travis complaining
        critical 'Execution timed out'
      ensure
        critical 'Execution timed out'
      end
    end
    output = pipe.read
    critical "Command '#{cmd}' returned no output" if output.to_s == ''
    critical output unless status == 0
    output
  end

  def run
    result = run_cmd('ceph status --format=json')
    data = ::JSON.parse(result)
    ignore_keys = %w(pgs_by_state version)
    timestamp = Time.now.to_i
    data['pgmap'].each do |key, val|
      output "#{config[:prefix]}.#{key}", val, timestamp unless ignore_keys.include? key
    end
    ok
  end
end