#!/usr/bin/env ruby require 'pathname' ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath) $LOAD_PATH << File.expand_path("../../lib", Pathname.new(__FILE__).realpath) require 'rubygems' require 'bundler' require 'bundler/setup' require "optparse" require "rest-client" require "json" EXIT_OK = 0 EXIT_WARNING = 1 EXIT_CRITICAL = 2 EXIT_UNKNOWN = 3 options = {} optparse = OptionParser.new do |opts| opts.banner = "Usage: check_graphite.rb [options]" options[:name] = 'value' opts.on("-n", "--name NAME", "Descriptive name") do |name| options[:name] = name end options[:url] = nil opts.on("-u", "--url URL", "Target url") do |url| options[:url] = url end options[:metric] = nil opts.on("-m", "--metric NAME", "Metric path string") do |metric| options[:metric] = metric end options[:duration] = 5 opts.on("-d", "--duration LENGTH", "Length, in minute of data to parse (default: 5)") do |duration| options[:duration] = duration end options[:warning] = nil opts.on("-w", "--warning VALUE", "Warning threshold") do |warning| options[:warning] = warning end options[:critical] = nil opts.on("-c", "--critical VALUE", "Critical threshold") do |critical| options[:critical] = critical end opts.on( "-h", "--help", "Display this screen" ) do puts opts exit end end begin optparse.parse! mandatory = [:url, :metric, :warning, :critical] missing = mandatory.select { |param| options[param].nil? } if not missing.empty? puts "Missing options: #{missing.join(', ')}" puts optparse exit 3 end rescue OptionParser::InvalidOption, OptionParser::MissingArgument puts $!.to_s puts optparse exit 3 end base_url = options[:url] metric = options[:metric] duration = options[:duration].to_s url = base_url + "/render/?target=" + metric + "&format=json&from=-" + duration + "mins" data = {} data["total"] = 0 begin JSON.parse(RestClient.get(url)).each do |cache| data["#{cache['target']}"] = 0 count = 0 cache["datapoints"].each do |point| unless (point[0].nil?) data["#{cache['target']}"] += point[0] count += 1 end end data["#{cache['target']}"] /= count data["total"] += data["#{cache['target']}"] end rescue ZeroDivisionError => e puts "UNKNOWN metric not in graphite!" exit EXIT_UNKNOWN rescue => e puts e.message exit EXIT_CRITICAL end total = data["total"].to_f formatted_total = sprintf("%.2f", total) if (options[:critical].to_f > options[:warning].to_f) if (total >= options[:critical].to_f) puts "CRITICAL #{options[:name]}: #{formatted_total}" exit EXIT_CRITICAL elsif (total >= options[:warning].to_f) puts "WARNING #{options[:name]}: #{formatted_total}" exit EXIT_WARNING else puts "OK #{options[:name]}: #{formatted_total}" exit EXIT_OK end else if (total <= options[:critical].to_f) puts "CRITICAL #{options[:name]}: #{formatted_total}" exit EXIT_CRITICAL elsif (total <= options[:warning].to_f) puts "WARNING #{options[:name]}: #{formatted_total}" exit EXIT_WARNING else puts "OK #{options[:name]}: #{formatted_total}" exit EXIT_OK end end