class Rack::Monitor::OpenTSDB::Reporter
Constants
- MAX_CACHE
Public Class Methods
new(stats, host, port, key = 'unconfigured.rack.monitor', interval = 60, tags = {}, logger = nil)
click to toggle source
stats has the following structure:
{ 'GET /monitored/path/1': { '<httpstatus>': [<time>, ...], ... }, ... }
The stats parameter must be extended with MonitorMixin. Like this it can be accessed synchronized.
# File lib/rack/monitor/opentsdb/reporter.rb, line 20 def initialize(stats, host, port, key = 'unconfigured.rack.monitor', interval = 60, tags = {}, logger = nil) raise ArgumentError, "Interval less than zero" if interval < 0 raise ArgumentError, 'stats does not support synchronize' unless stats.respond_to? :synchronize @interval = interval @tags = tags @stats = stats @host = host @port = port @key = key @logger = logger @tosend = [] start end
Public Instance Methods
start()
click to toggle source
# File lib/rack/monitor/opentsdb/reporter.rb, line 35 def start return if @run @run = true log(:info, 'Starting Reporter-Thread') @th = Thread.new do t = Time.now while run? t += @interval (sleep(t - Time.now) rescue nil) and send_report rescue nil end end end
stop()
click to toggle source
# File lib/rack/monitor/opentsdb/reporter.rb, line 48 def stop @stats.synchronize do @run = false end @th.join end
Private Instance Methods
copy_and_clear_stats()
click to toggle source
# File lib/rack/monitor/opentsdb/reporter.rb, line 112 def copy_and_clear_stats copy = {} @stats.synchronize do @stats.each do |url, url_stats| copy[url] = url_stats end @stats.clear end copy end
log(level, message)
click to toggle source
# File lib/rack/monitor/opentsdb/reporter.rb, line 123 def log(level, message) if(@logger.respond_to? level) @logger.send level, "Rack::Monitor::OpenTSDB::Reporter - #{message}" end end
run?()
click to toggle source
# File lib/rack/monitor/opentsdb/reporter.rb, line 57 def run? @stats.synchronize do @run end end
send_report()
click to toggle source
# File lib/rack/monitor/opentsdb/reporter.rb, line 63 def send_report log(:debug, "Sending Report#{@tosend.empty? ? '' : " (#{@tosend.length} spooled entries)"}") timestamp = Time.now.to_i data = copy_and_clear_stats data.each do |url, url_stats| verb, path = url.split(/ /) url_stats.each do |status, timings| tags = @tags.merge({:status => status, :verb => verb, :path => path}).map { |key, value| "#{key}=#{value}" }.join(' ') @tosend.push("put #{@key}.min #{timestamp} #{timings.min} #{tags}") @tosend.push("put #{@key}.max #{timestamp} #{timings.max} #{tags}") @tosend.push("put #{@key}.num #{timestamp} #{timings.size} #{tags}") @tosend.push("put #{@key}.avg #{timestamp} #{timings.inject(0.0) { |sum, e| sum + e } / timings.size} #{tags}") end end # cleanup if cannot send anything, only keep MAX_CACHE entries to send if @tosend.size > MAX_CACHE @tosend.shift(@tosend.length - - MAX_CACHE) end send_to_socket end
send_to_socket()
click to toggle source
# File lib/rack/monitor/opentsdb/reporter.rb, line 87 def send_to_socket begin @tosend.delete_if do |line| # throws in first go NoMethodError: undefined method `puts' for nil:NilClass # this is rescued and the connection is opened for retry @socket.puts line true end rescue IOError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE log(:error, "Connection problem: #{$!.message}") # Don't retry immediately (preventing loops), next run will retry @socket = nil rescue begin log(:info, "Connecting to #{host}:#{port}") @socket = TCPSocket.new(@host, @port) retry rescue log(:error, "Connection problem:#{$!.message}") # will do no retry in this case end end end