bin/cloudwatch_to_graphite
#!/usr/bin/env ruby
# _*_ coding: utf-8 _*_
# frozen_string_literal: true
#
# == Synopsis
# CloudwatchToGraphite retrieves metrics from the Amazon CloudWatch APIs
# and passes them on to a graphite server
#
# == Author
# S. Zachariah Sprackett <zac@sprackett.com>
#
# == License
# The MIT License (MIT)
#
# == Copyright
# Copyright (C) 2013 - S. Zachariah Sprackett <zac@sprackett.com>
#
require 'optparse'
require 'pp'
require 'log4r'
logger = Log4r::Logger.new('cloudwatchtographite')
logger.level = Log4r::ERROR
f = Log4r::Outputter.stderr
f.formatter = Log4r::PatternFormatter.new(pattern: '[%d] %C: %m')
logger.outputters = f
begin
require 'cloudwatchtographite'
rescue LoadError
dev_path = File.join(File.dirname(__FILE__), '..', 'lib')
$LOAD_PATH.unshift(dev_path)
require 'cloudwatchtographite'
end
# default options
options = {
protocol: 'udp',
region: ENV.key?('AWS_DEFAULT_REGION') ?
ENV['AWS_DEFAULT_REGION'] : 'us-east-1',
access_key: ENV['AWS_ACCESS_KEY_ID'],
secret_key: ENV['AWS_SECRET_ACCESS_KEY'],
graphite_server: 'localhost',
graphite_port: 2003,
carbon_prefix: 'cloudwatch'
}
opt_parser = OptionParser.new do |opt|
opt.banner = 'Usage: %s [OPTIONS]' % File.basename($PROGRAM_NAME)
opt.separator ''
opt.on('-a', '--access-key=KEY', "AWS Access Key (Falls back to ENV['AWS_ACCESS_KEY_ID'])") do |key|
options[:access_key] = key
end
opt.on('-s', '--secret-key=KEY', "AWS Secret Access Key (Falls back to ENV['AWS_SECRET_ACCESS_KEY'])") do |key|
options[:secret_key] = key
end
opt.on('-j', '--json-metrics=FILE', 'Path to JSON metrics file') do |file|
options[:json_metrics] = file
end
opt.on('-y', '--yaml-metrics=FILE', 'Path to YAML metrics file') do |file|
options[:yaml_metrics] = file
end
opt.on('-p', '--protocol=udp', "TCP or UDP (Default: #{options[:protocol]})") do |protocol|
options[:protocol] = protocol
end
opt.on('-r', '--region=us-east-1', "AWS Region (Default: #{options[:region]})") do |region|
options[:region] = region
end
opt.on('-g', '--graphite-server=host', "Graphite Server (Default: #{options[:graphite_server]})") do |server|
options[:graphite_server] = server
end
opt.on('-P', '--graphite-port=port', Integer, "Graphite Port (Default: #{options[:graphite_port]})") do |port|
options[:graphite_port] = port
end
opt.on('-c', '--carbon-prefix=prefix', "Carbon Prefix (Default: #{options[:carbon_prefix]})") do |prefix|
options[:carbon_prefix] = prefix
end
opt.on('-l', '--logfile=prefix', 'Log file (Default: stderr)') do |logfile|
f = Log4r::FileOutputter.new(
'logfile',
filename: logfile,
trunc: false
)
f.formatter = Log4r::PatternFormatter.new(pattern: '[%l] %d %C: %m')
logger.outputters = f
end
opt.on('-v', '--verbose', 'Increase verbosity') do
logger.level = Log4r::DEBUG
end
opt.on('-V', '--version', 'Print version and exit') do
puts File.basename($PROGRAM_NAME) + ' ' + CloudwatchToGraphite::VERSION::STRING
exit 0
end
opt.on('-h', '--help', 'help') do
puts opt_parser
exit 1
end
end
begin
opt_parser.parse!
mandatory = [:access_key, :secret_key]
missing = mandatory.select { |param| options[param].nil? }
unless missing.empty?
puts "Missing options: #{missing.join(', ')}"
puts opt_parser
exit 1
end
if options[:json_metrics].nil? && options[:yaml_metrics].nil?
puts 'No metric file specified.'
puts opt_parser
exit 1
elsif !options[:json_metrics].nil? && !options[:yaml_metrics].nil?
puts 'Only one metric file should be specified.'
puts opt_parser
exit 1
end
rescue OptionParser::InvalidOption => e
puts "Error: #{e}"
puts
puts opt_parser
exit 1
end
metrics = nil
begin
if !options[:json_metrics].nil?
logger.debug('Parsing JSON metrics')
metrics = CloudwatchToGraphite::LoadMetrics.from_json_file(options[:json_metrics])
else
logger.debug('Parsing YAML metrics')
metrics = CloudwatchToGraphite::LoadMetrics.from_yaml_file(options[:yaml_metrics])
end
rescue CloudwatchToGraphite::ParseError
logger.fatal('Failed to parse option file')
exit 1
end
if metrics.empty?
logger.fatal('Exiting due to lack of metric definitions')
exit 1
end
logger.debug('Initializing CloudwatchToGraphite::Base')
cwtg = CloudwatchToGraphite::Base.new(
options[:access_key],
options[:secret_key],
options[:region]
)
cwtg.carbon_prefix = options[:carbon_prefix]
cwtg.protocol = options[:protocol]
cwtg.graphite_server = options[:graphite_server]
cwtg.graphite_port = options[:graphite_port]
logger.debug('Fetching and forwarding metrics')
if cwtg.fetch_and_forward(metrics)
logger.info('Exiting Success')
exit 0
else
logger.info('Exiting Failure')
exit 1
end