|
require 'rubygems' |
|
require 'aws-sdk' |
|
require 'optparse' |
|
|
|
namespace = nil |
|
metric_name = nil |
|
dimensions = {:exist => true, :filters => [], :no_keys => []} |
|
endpoint = 'monitoring.us-east-1.amazonaws.com' |
|
ENDPOINTS = ["us-east-1", "us-west-2", "us-west-1", "eu-west-1", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", "sa-east-1"] |
|
stat = {:end_time => Time.now, :statistics => ['Average'], :period => 60} |
|
stat[:start_time] = stat[:end_time] - 3600 |
|
|
|
opt = OptionParser.new |
|
opt.on('--endpoint=VAL', "default:us-east-1, #{ENDPOINTS.join("/")}") { |v| |
|
raise ArgumentError.new("Specify valid endpoint") unless ENDPOINTS.include?(v) |
|
endpoint = "monitoring.#{v}.amazonaws.com" |
|
} |
|
opt.on('--namespace=VAL') { |v| namespace = v } |
|
opt.on('--metric-name=VAL') { |v| metric_name = v } |
|
opt.on('--no-exist-dimensions') { dimensions[:exist] = false } |
|
opt.on('--dimension=VAL', 'format:<key>:<value> or ~<key>') { |v| |
|
if v.include?(":") |
|
key, value = v.split(":", 2) |
|
dimensions[:filters] << {:name => key, :value => value} |
|
else |
|
dimensions[:no_keys] << v.sub(/^\~/, "") |
|
end |
|
} |
|
opt.on('--stat-term=VAL', "default:3600(s)") { |v| stat[:start_time] = stat[:end_time] - v.to_i } |
|
opt.on('--stat=VAL', "default:#{stat[:statistics][0]}") { |v| stat[:statistics] = [v] } |
|
opt.on('--stat-period', "default:#{stat[:period]}") { |v| stat[:period] << v.to_i } |
|
opt.parse!(ARGV) |
|
|
|
cw = AWS::CloudWatch.new(:proxy_uri => ENV['HTTP_PROXY'] || ENV['http_proxy'], :cloud_watch_endpoint => endpoint) |
|
metrics = cw.metrics |
|
metrics = metrics.filter('namespace', namespace) if namespace |
|
metrics = metrics.filter('metric_name', metric_name) if metric_name |
|
metrics = metrics.filter('dimensions', dimensions[:filters]) if dimensions[:exist] && !dimensions[:filters].empty? |
|
|
|
unless dimensions[:exist] |
|
empty_dims = metrics.enum.select { |x| x.dimensions.empty? } |
|
raise ArgumentError.new("target isn't only one, can't select\n#{empty_dims.map { |x| x.inspect }.join("\n")}") if empty_dims.count != 1 |
|
else |
|
dims = metrics.enum.select { |x| |
|
(x.dimensions.map { |y| y[:name] } & dimensions[:no_keys]).empty? |
|
} |
|
raise ArgumentError.new("target isn't only one, can't select\n#{metrics.map { |x| x.inspect }.join("\n")}") if dims.count != 1 |
|
end |
|
|
|
metrics.each do |metric| |
|
next if !dimensions[:exist] && !metric.dimensions.empty? |
|
next if dimensions[:exist] && !((metric.dimensions.map { |x| x[:name] } & dimensions[:no_keys]).empty?) |
|
|
|
datapoints = metric.statistics(stat).datapoints.sort { |x, y| x[:timestamp] <=> y[:timestamp] } |
|
datapoints.each do |datapoint| |
|
data_value = datapoint[stat[:statistics][0].gsub(/[a-z][A-Z]/) { |x| x.split("").join("_") }.downcase.to_sym] |
|
puts "#{datapoint[:timestamp].to_i} #{data_value}" |
|
end |
|
end |