sensu-plugins/sensu-plugins-aws

View on GitHub
bin/metrics-elb.rb

Summary

Maintainability
A
2 hrs
Test Coverage
#! /usr/bin/env ruby
#
# elb-metrics
#
# DESCRIPTION:
#   Gets latency metrics from CloudWatch and puts them in Graphite for longer term storage
#
# OUTPUT:
#   metric-data
#
# PLATFORMS:
#   Linux
#
# DEPENDENCIES:
#   gem: aws-sdk
#   gem: sensu-plugin
#   gem: sensu-plugin-aws
#   gem: time
#
# USAGE:
#   #YELLOW
#
# NOTES:
#   Returns latency statistics by default.  You can specify any valid ELB metric type, see
#   http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html#elb-metricscollected
#
#   By default fetches statistics from one minute ago.  You may need to fetch further back than this;
#   high traffic ELBs can sometimes experience statistic delays of up to 10 minutes.  If you experience this,
#   raising a ticket with AWS support should get the problem resolved.
#   As a workaround you can use eg -f 300 to fetch data from 5 minutes ago.
#
# LICENSE:
#   Copyright 2013 Bashton Ltd http://www.bashton.com/
#   Released under the same terms as Sensu (the MIT license); see LICENSE
#   for details.
#   Updated by Peter Hoppe <peter.hoppe.extern@bertelsmann.de> 09.11.2016
#   Using aws sdk version 2

require 'sensu-plugin/metric/cli'
require 'aws-sdk'
require 'sensu-plugins-aws'
require 'time'

class ELBMetrics < Sensu::Plugin::Metric::CLI::Graphite
  include Common
  option :elbname,
         description: 'Name of the Elastic Load Balancer',
         short: '-n ELB_NAME',
         long: '--name ELB_NAME'

  option :scheme,
         description: 'Metric naming scheme, text to prepend to metric',
         short: '-s SCHEME',
         long: '--scheme SCHEME',
         default: 'elb'

  option :fetch_age,
         description: 'How long ago to fetch metrics for',
         short: '-f AGE',
         long: '--fetch_age',
         default: 60,
         proc: proc(&:to_i)

  option :statistic,
         description: 'Statistics type',
         short: '-t STATISTIC',
         long: '--statistic',
         default: ''

  option :aws_region,
         short: '-r AWS_REGION',
         long: '--aws-region REGION',
         description: 'AWS Region (defaults to us-east-1).',
         default: ENV['AWS_REGION']

  option :end_time,
         short:       '-t T',
         long:        '--end-time TIME',
         default:     Time.now,
         proc:        proc { |a| Time.parse a },
         description: 'CloudWatch metric statistics end time'

  option :period,
         short:       '-p N',
         long:        '--period SECONDS',
         default:     60,
         proc:        proc(&:to_i),
         description: 'CloudWatch metric statistics period'

  def cloud_watch
    @cloud_watch = Aws::CloudWatch::Client.new
  end

  def loadbalancer
    @loadbalancer = Aws::ElasticLoadBalancing::Client.new
  end

  def cloud_watch_metric(metric_name, value, load_balancer_name)
    cloud_watch.get_metric_statistics(
      namespace: 'AWS/ELB',
      metric_name: metric_name,
      dimensions: [
        {
          name: 'LoadBalancerName',
          value: load_balancer_name
        }
      ],
      statistics: [value],
      start_time: config[:end_time] - config[:fetch_age] - config[:period],
      end_time: config[:end_time] - config[:fetch_age],
      period: config[:period]
    )
  end

  def print_statistics(load_balancer_name, statistics)
    result = {}
    static_value = {}
    statistics.each do |key, static|
      r = cloud_watch_metric(key, static, load_balancer_name)
      keys = if config[:scheme] == ''
               []
             else
               [config[:scheme]]
             end
      keys.concat [load_balancer_name, key, static]
      metric_key = keys.join('.')

      static_value[metric_key] = static
      result[metric_key] = r[:datapoints][0] unless r[:datapoints][0].nil?
    end
    result.each do |key, value|
      output key.downcase.to_s, value[static_value[key].downcase], value[:timestamp].to_i
    end
  end

  def run
    if config[:statistic] == ''
      default_statistic_per_metric = {
        'Latency' => 'Average',
        'RequestCount' => 'Sum',
        'UnHealthyHostCount' => 'Average',
        'HealthyHostCount' => 'Average',
        'HTTPCode_Backend_2XX' => 'Sum',
        'HTTPCode_Backend_3XX' => 'Sum',
        'HTTPCode_Backend_4XX' => 'Sum',
        'HTTPCode_Backend_5XX' => 'Sum',
        'HTTPCode_ELB_4XX' => 'Sum',
        'HTTPCode_ELB_5XX' => 'Sum',
        'BackendConnectionErrors' => 'Sum',
        'SurgeQueueLength' => 'Maximum',
        'SpilloverCount' => 'Sum'
      }
      statistic = default_statistic_per_metric
    else
      statistic = config[:statistic]
    end

    begin
      if config[:elbname].nil?
        loadbalancer.describe_load_balancers.load_balancer_descriptions.each do |elb|
          print_statistics(elb.load_balancer_name, statistic)
        end
      else
        print_statistics(config[:elbname], statistic)
      end
      ok
    end
  end
end