Get EC2 CloudWatch stats and graph them in Dashing.
-
-
Save sunnycmf/e73c0fa16c8b9c3cfa85 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Get the Rickshawgraph widget from https://gist.github.com/jwalton/6614023 --> | |
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1"> | |
<div data-id="ec2-cpu" data-view="Rickshawgraph" data-title="CPU Usage" | |
data-moreinfo="" | |
style="background-color:#333A52;" | |
data-renderer="line" | |
data-min="0" | |
data-max="100" | |
data-summary-method="none" | |
data-legend="true" | |
data-colors="rgba(192,132,255,1):rgba(96,170,255,1)" | |
></div> | |
</li> | |
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1"> | |
<div data-id="ec2-cpugraph" data-view="Graph" data-title="CPU Usage" | |
data-moreinfo="" | |
style="background-color:#333A52;" | |
></div> | |
</li> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
#jobs/ec2.rb | |
require './lib/dashing-ec2' | |
dashing_ec2 = DashingEC2.new({ | |
:access_key_id => "YOUR KEY ID HERE", | |
:secret_access_key => "YOUR SECRET HERE", | |
}) | |
# See documentation here for cloud watch API here: https://github.com/aws/aws-sdk-ruby/blob/af638994bb7d01a8fd0f8a6d6357567968638100/lib/aws/cloud_watch/client.rb | |
# See documentation on various metrics and dimensions here: http://docs.aws.amazon.com/AWSEC2/2011-07-15/UserGuide/index.html?using-cloudwatch.html | |
# Note that Amazon charges [$0.01 per 1000 reqeuests](http://aws.amazon.com/pricing/cloudwatch/), | |
# so: | |
# | |
# | frequency | $/month/stat | | |
# |:---------:|:------------:| | |
# | 1m | $0.432 | | |
# | 10m | $0.043 | | |
# | 1h | $0.007 | | |
# | |
# In the free tier, stats are only available for 5m intervals, so querying more often than | |
# once every 5 minutes is kind of pointless. You've been warned. :) | |
# | |
SCHEDULER.every '10m', :first_in => 0 do |job| | |
cpu_usage = [ | |
{name: 'server1', instance_id: "i-xxxxxxxx", region: 'us-east-1'}, | |
{name: 'server2', instance_id: "i-yyyyyyyy", region: 'us-east-1'}, | |
{name: 'server3', instance_id: "i-zzzzzzzz", region: 'us-east-1'} | |
] | |
cpu_series = [] | |
cpu_usage.each do |item| | |
cpu_data = dashing_ec2.getInstanceStats(item[:instance_id], item[:region], "CPUUtilization", :average) | |
cpu_data[:name] = item[:name] | |
cpu_series.push cpu_data | |
end | |
# If you're using the Rickshaw Graph widget: https://gist.github.com/jwalton/6614023 | |
send_event "ec2-cpu", { series: cpu_series } | |
# If you're just using the regular Dashing graph widget: | |
send_event "ec2-cpu-server1", { points: cpu_series[0][:data] } | |
send_event "ec2-cpu-server2", { points: cpu_series[1][:data] } | |
send_event "ec2-cpu-server3", { points: cpu_series[2][:data] } | |
end # SCHEDULER |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lib/dashing_ec2.rb | |
require 'aws-sdk' | |
require 'time' | |
class DashingEC2 | |
def initialize(options) | |
@access_key_id = options[:access_key_id] | |
@secret_access_key = options[:secret_access_key] | |
@clientCache = {} | |
end | |
# Get statistics for an instance | |
# | |
# * `instance_id` is the instance to get data about. | |
# * `region` is the name of the region the instance is from (e.g. 'us-east-1'.) See | |
# [monitoring URIs](http://docs.aws.amazon.com/general/latest/gr/rande.html#cw_region). | |
# * `metric_name` is the metric to get. See | |
# [the list of build in metrics](http://docs.aws.amazon.com/AWSEC2/2011-07-15/UserGuide/index.html?using-cloudwatch.html). | |
# * `type` is `:average` or `:maximum`. | |
# * `options` are [:start_time, :end_time, :period, :dimensions] as per | |
# `get_metric_statistics()`, although all are optional. Also: | |
# * `:duration` - If supplied, and no start_time or end_time are supplied, then start_time | |
# and end_time will be computed based on this value in seconds. Defaults to 6 hours. | |
def getInstanceStats(instance_id, region, metric_name, type=:average, options={}) | |
if type == :average | |
statName = "Average" | |
elsif type == :maximum | |
statName = "Maxmimum" | |
end | |
statKey = type | |
# Get an API client instance | |
cw = @clientCache[region] | |
if not cw | |
cw = @clientCache[region] = AWS::CloudWatch::Client.new({ | |
server: "https://monitoring.#{region}.amazonaws.com", | |
access_key_id: @access_key_id, | |
secret_access_key: @secret_access_key | |
}) | |
end | |
# Build a default set of options to pass to get_metric_statistics | |
duration = (options[:duration] or (60*60*6)) # Six hours | |
start_time = (options[:start_time] or (Time.now - duration)) | |
end_time = (options[:end_time] or (Time.now)) | |
get_metric_statistics_options = { | |
namespace: "AWS/EC2", | |
metric_name: metric_name, | |
statistics: [statName], | |
start_time: start_time.utc.iso8601, | |
end_time: end_time.utc.iso8601, | |
period: (options[:period] or (60 * 5)), # Default to 5 min stats | |
dimensions: (options[:dimensions] or [{name: "InstanceId", value: instance_id}]) | |
} | |
# Go get stats | |
result = cw.get_metric_statistics(get_metric_statistics_options) | |
if ((not result[:datapoints]) or (result[:datapoints].length == 0)) | |
# TODO: What kind of errors can I get back? | |
puts "\e[33mWarning: Got back no data for instanceId: #{region}:#{instance_id} for metric #{metric_name}\e[0m" | |
answer = nil | |
else | |
# Turn the result into a Rickshaw-style series | |
data = [] | |
result[:datapoints].each do |datapoint| | |
point = { | |
x: (datapoint[:timestamp].to_i), # time in seconds since epoch | |
y: datapoint[statKey] | |
} | |
data.push point | |
end | |
data.sort! { |a,b| a[:x] <=> b[:x] } | |
answer = { | |
name: "#{metric_name} for #{instance_id}", | |
data: data | |
} | |
end | |
return answer | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment