Created
May 17, 2012 10:57
-
-
Save rubiojr/2718141 to your computer and use it in GitHub Desktop.
Munin Graphite Bridge
This file contains hidden or 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
# Ubuntu Upstart service file | |
description "munin-graphite" | |
start on (filesystem and net-device-up) | |
stop on runlevel [!2345] | |
env DAEMON=/usr/local/bin/munin-graphite | |
expect fork | |
respawn | |
pre-start exec $DAEMON start <%= config['carbon_cache_ip'] %> | |
post-stop exec $DAEMON stop <%= config['carbon_cache_ip'] %> |
This file contains hidden or 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 | |
# | |
# munin-graphite.rb | |
# | |
# A Munin-Node to Graphite bridge | |
# | |
# Original code from: | |
# Author:: Adam Jacob (<[email protected]>) | |
# Copyright:: Copyright (c) 2008 HJK Solutions, LLC | |
# License:: GNU General Public License version 2 or later | |
# | |
# Tweaked by Sergio Rubio <[email protected]> | |
# | |
# This program and entire repository is free software; you can | |
# redistribute it and/or modify it under the terms of the GNU | |
# General Public License as published by the Free Software | |
# Foundation; either version 2 of the License, or any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software | |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
# | |
require 'socket' | |
require 'rubygems' | |
require 'daemon_spawn' | |
class Munin | |
def initialize(host='localhost', port=4949) | |
@munin = TCPSocket.new(host, port) | |
@munin.gets | |
end | |
def get_response(cmd) | |
@munin.puts(cmd) | |
stop = false | |
response = Array.new | |
while stop == false | |
line = @munin.gets | |
line.chomp! | |
if line == '.' | |
stop = true | |
else | |
response << line | |
stop = true if cmd == "list" | |
end | |
end | |
response | |
end | |
def close | |
@munin.close | |
end | |
end | |
class Carbon | |
def initialize(host='localhost', port=2003) | |
@host = host | |
@port = port | |
puts "[#{Time.now}] Contacting Carbon host at #{host}:#{port}" | |
@carbon = TCPSocket.new(host, port) | |
end | |
def send(msg) | |
puts "[#{Time.now}] Sending to Carbon at #{@host}:#{@port}" | |
@carbon.puts(msg) | |
end | |
def close | |
@carbon.close | |
end | |
end | |
class MGDaemon < DaemonSpawn::Base | |
def start(args) | |
while true | |
metric_base = "servers." | |
all_metrics = Array.new | |
begin | |
munin = Munin.new | |
munin.get_response("nodes").each do |node| | |
metric_base << node.split(".").reverse.join(".") | |
puts "[#{Time.now}] Doing #{metric_base}" | |
munin.get_response("list")[0].split(" ").each do |metric| | |
puts "[#{Time.now}] Grabbing #{metric}" | |
mname = "#{metric_base}" | |
has_category = false | |
base = false | |
munin.get_response("config #{metric}").each do |configline| | |
if configline =~ /graph_category (.+)/ | |
mname << ".#{$1}" | |
has_category = true | |
end | |
if configline =~ /graph_args.+--base (\d+)/ | |
base = $1 | |
end | |
end | |
mname << ".other" unless has_category | |
# Get rid off spaces, graphite does not like them | |
mname.gsub(" ", "_") | |
munin.get_response("fetch #{metric}").each do |line| | |
line =~ /^(.+)\.value\s+(.+)$/ | |
field = $1 | |
value = $2 | |
all_metrics << "#{mname}.#{metric}.#{field} #{value} #{Time.now.to_i}" | |
end | |
end | |
end | |
rescue Exception => e | |
$stderr.puts "[#{Time.now}] Error fetching data from munin" | |
$stderr.puts e.message | |
end | |
begin | |
port = 2003 | |
host = ARGV[0] | |
if host =~ /(.*?):(.+)/ | |
port = $2 | |
host = $1 | |
end | |
carbon = Carbon.new(host, port) | |
all_metrics.each do |m| | |
puts "[#{Time.now}] Sending #{m}" | |
begin | |
carbon.send(m) | |
rescue Exception => e | |
$stderr.puts "[#{Time.now}] Error sending data to Carbon #{host}:#{port}, #{e.message}" | |
end | |
end | |
sleep 60 | |
rescue Exception => e | |
$stderr.puts "[#{Time.now}] Error connecting to Carbon host #{host}:#{port}" | |
$stderr.puts "[#{Time.now}] Retry in 10 seconds" | |
sleep 10 | |
end | |
end | |
end | |
def stop | |
# stop your bad self | |
end | |
end | |
if ARGV[1].nil? | |
puts "Missing graphite host." | |
puts "Usage: munin-graphite start|stop <graphite-host>" | |
exit 1 | |
end | |
MGDaemon.spawn!(:log_file => '/var/log/munin-graphite.log', | |
:pid_file => '/var/run/munin-graphite.pid', | |
:sync_log => true, | |
:working_dir => "/tmp") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment