-
-
Save j1n6/b1ea9784a9350a08c65d 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
#!/usr/bin/env ruby | |
require 'socket' | |
require 'optparse' | |
# Collect INFO from Redis, report it to Graphite | |
opts = OptionParser.new do |opts| | |
opts.banner = "Usage: redis-graphite.rb redis_host[:port] graphite_host [graphite_prefix(e.g. redis.cluster-name.server-identifier)]" | |
opts.on( '-h', '--help', 'Display this screen' ) do | |
puts opts | |
exit | |
end | |
end | |
opts.parse! | |
redis_server = ARGV.shift | |
graphite_host = ARGV.shift | |
graphite_namespace = ARGV.shift | |
unless graphite_host && redis_server | |
puts opts | |
exit 1 | |
end | |
class Graphite | |
def initialize(host) | |
@host = host | |
end | |
def socket | |
return @socket if @socket && !@socket.closed? | |
@socket = TCPSocket.new(@host, 2003) | |
end | |
def report(key, value, time = Time.now) | |
begin | |
socket.write("#{key} #{value.to_f} #{time.to_i}\n") | |
rescue Errno::EPIPE, Errno::EHOSTUNREACH, Errno::ECONNREFUSED | |
@socket = nil | |
nil | |
end | |
end | |
def close_socket | |
@socket.close if @socket | |
@socket = nil | |
end | |
end | |
class String | |
def numeric? | |
return true if self =~ /^\d+$/ | |
true if Float(self) rescue false | |
end | |
end | |
redis_host, redis_port = *redis_server.split(':') | |
redis_port ||= 6379 | |
info = `redis-cli -h #{redis_host} -p #{redis_port} INFO` | |
# if namespace is not given, it uses redis.host_port as defaut namespace | |
graphite_namespace = graphite_namespace || "redis.#{redis_host.gsub('.', '_')}_#{redis_port}" | |
exit 2 unless $?.success? | |
begin | |
graphite_client = Graphite.new(graphite_host) | |
info.each_line do |line| | |
next if line.length < 4 || line.start_with?("#") | |
key, value = *line.split(':') | |
# Parse db* and slave* | |
if(key.rindex(/(db|slave)[\d]+/) == 0) | |
tmp_info = value.split(',') | |
tmp_info.each do |tmp_detail| | |
tmp_key, tmp_value = *tmp_detail.split('=') | |
tmp_key = "#{key}-#{tmp_key}" | |
graphite_key = "#{graphite_namespace}.#{tmp_key}" | |
graphite_client.report(graphite_key, tmp_value) if tmp_value.numeric? | |
end | |
else | |
graphite_key = "#{graphite_namespace}.#{key}" | |
graphite_client.report(graphite_key, value) if value.numeric? | |
end | |
end | |
graphite_client.close_socket | |
rescue => err | |
puts "Error: #{err}" | |
exit 4 | |
graphite_client.close_socket | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment