class AppMonit::Rails::Worker

Constants

MAX_MULTIPLIER
MUTEX

Attributes

errors[RW]
requests[RW]

Public Class Methods

instance() click to toggle source
# File lib/app_monit/rails/worker.rb, line 10
def instance
  return @instance if @instance
  MUTEX.synchronize do
    return @instance if @instance
    @instance = new.start
  end
end
new() click to toggle source
# File lib/app_monit/rails/worker.rb, line 19
def initialize
  @queue      = Queue.new
  @multiplier = 1
  @flush_rate = 60
  reset
end

Public Instance Methods

convert_errors_to_events() click to toggle source
# File lib/app_monit/rails/worker.rb, line 107
def convert_errors_to_events
  @errors.flat_map do |minute, endpoints|
    endpoints.collect do |endpoint, duration|
      payload = duration.merge(application: Config.name, endpoint: endpoint)
      { created_at: Time.at(minute), name: 'page_error', payload: payload }
    end
  end
end
convert_requests_to_events() click to toggle source
# File lib/app_monit/rails/worker.rb, line 98
def convert_requests_to_events
  @requests.flat_map do |minute, endpoints|
    endpoints.collect do |endpoint, durations|
      payload = durations.merge(application: Config.name, endpoint: endpoint)
      { application: Config.name, created_at: Time.at(minute), name: 'page_load', payload: payload }
    end
  end
end
current_minute() click to toggle source
# File lib/app_monit/rails/worker.rb, line 41
def current_minute
  time = Time.now.to_i
  time - (time % 60)
end
events() click to toggle source
# File lib/app_monit/rails/worker.rb, line 116
def events
  convert_requests_to_events + convert_errors_to_events
end
push(event) click to toggle source
# File lib/app_monit/rails/worker.rb, line 94
def push(event)
  @queue << event
end
reset() click to toggle source
# File lib/app_monit/rails/worker.rb, line 26
def reset
  @requests = Hash.new do |requests, minutes|
    requests[minutes] = Hash.new do |minute, endpoints|
      minute[endpoints] = Hash.new do |endpoint, duration|
        endpoint[duration] = { sum: 0, count: 0, average: 0 }
      end
    end
  end
  @errors   = Hash.new do |errors, minutes|
    errors[minutes] = Hash.new do |minute, endpoint|
      minute[endpoint] = { sum: 0, count: 0, average: 0 }
    end
  end
end
send_to_collector() click to toggle source
# File lib/app_monit/rails/worker.rb, line 120
def send_to_collector
  AppMonit::Rails.logger.debug "Sending to collector"

  if events.any?
    begin
      AppMonit::Http.post('/v1/events', event: events)
    rescue Net::ReadTimeout
      AppMonit::Rails.logger.debug "Response took to longer than #{AppMonit::Config.timeout} second(s), but we assume it's been send"
    end
    @requests.clear
    @errors.clear
  end

  reset
end
start() click to toggle source
# File lib/app_monit/rails/worker.rb, line 46
def start
  Thread.new do
    while (event = @queue.pop)
      begin
        case event
          when Error
            update_error(event)
          when Event
            update_event(event)
          when :flush
            send_to_collector
        end
      rescue Exception => e
        AppMonit::Rails.logger.debug ["Event error:", event.inspect, e.message]
      end
    end
  end
  start_flusher

  self
end
start_flusher() click to toggle source
# File lib/app_monit/rails/worker.rb, line 85
def start_flusher
  Thread.new do
    loop do
      sleep @multiplier * @flush_rate
      push(:flush)
    end
  end
end
update_error(event) click to toggle source
# File lib/app_monit/rails/worker.rb, line 68
def update_error(event)
  bucket           = @errors[event.minute][event.endpoint]
  bucket[:sum]     += event.duration
  bucket[:count]   += 1
  bucket[:average] = (bucket[:sum] / bucket[:count].to_f)
end
update_event(event) click to toggle source

@param [AppMonit::Rails::Event] event

# File lib/app_monit/rails/worker.rb, line 76
def update_event(event)
  event.durations.each do |duration, value|
    bucket           = @requests[event.minute][event.endpoint][duration]
    bucket[:sum]     += value
    bucket[:count]   += 1
    bucket[:average] = (bucket[:sum] / bucket[:count].to_f)
  end
end