#! /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