module Rack::Metrics

Constants

VERSION

Attributes

config[W]
start_processing[RW]

Public Class Methods

config() click to toggle source
# File lib/rack/metrics/metrics.rb, line 9
def config
  @config ||= Rack::Metrics::Config.new
end
current() click to toggle source
# File lib/rack/metrics/metrics.rb, line 13
def current
  Thread.current[:rack_metrics]
end
current=(c) click to toggle source
# File lib/rack/metrics/metrics.rb, line 17
def current=(c)
  Thread.current[:rack_metrics] = c
end
log(message) click to toggle source
# File lib/rack/metrics/metrics.rb, line 33
def log(message)
  begin
    Rails.logger.info message
  rescue
    puts message
  end
end
parse_stack(stack) click to toggle source
# File lib/rack/metrics.rb, line 11
def self.parse_stack(stack)
  parsed = []
  stack.each do |line|
    line.gsub!("#{Rails.root}/", '')
    if /^((?:app|config|lib|test).+?):(\d+)(?::in `(.*)')?/ =~ line
      parsed<< line
    end
  end
  parsed
end
push_data(data) click to toggle source
# File lib/rack/metrics/metrics.rb, line 21
def push_data(data)
  return if ENV['RACK_METRICS_API_KEY'].blank?
  log("[Rack Metrics] => Pushing metrics data")
  begin
    uri = URI(::File.join(Rack::Metrics.config.endpoint, 'api/v1'))
    res = Net::HTTP.post_form(uri, 'api_key' => ENV['RACK_METRICS_API_KEY'], 'api_version' => '1.1.0', 'data' => data)
  rescue => e
    log "[Rack Metrics] => Error while pushing metrics data: #{e.message}"
  end
  Metrics.current = nil
end
subscribe() click to toggle source
# File lib/rack/metrics.rb, line 22
def self.subscribe
  env = Rails.env || ENV['rack_env'] || ENV['RAILS_ENV']
  return unless Rack::Metrics.config.environments.include?(env.to_sym)
  ActiveSupport::Notifications.subscribe "start_processing.action_controller" do |*args|
    Metrics.current = Event.new *args
    Metrics.current.stack = Stack.new
    Metrics.current.template = Event.new *args

    ActiveSupport::Notifications.subscribe "render_template.action_view" do |name, time, finished, transaction_id, payload|
      Metrics.current.template.name = name
      Metrics.current.template.time = time
      Metrics.current.template.end = finished
      Metrics.current.template.transaction_id = transaction_id
      Metrics.current.template.payload = payload
      Metrics.current.template.payload[:identifier] = Metrics.current.template.payload[:identifier].gsub("#{Rails.root}/", '') unless Metrics.current.template.payload[:identifier].nil?
    end
  end

  ActiveSupport::Notifications.subscribe "render_template.action_view" do |name, time, finished, transaction_id, payload|
    begin
      Metrics.current.template.name = name
      Metrics.current.template.time = time
      Metrics.current.template.end = finished
      Metrics.current.template.transaction_id = transaction_id
      Metrics.current.template.payload = payload
      Metrics.current.template.payload[:identifier] = Metrics.current.template.payload[:identifier].gsub("#{Rails.root}/", '') unless Metrics.current.template.payload[:identifier].nil?
    rescue Exception => e
      Metrics.log("[Rack-Metrics] exception raised: #{e.inspect}")
    end
  end

  ActiveSupport::Notifications.subscribe "start_render_partial.action_view" do |*args|
    render_partial = Event.new *args
    Metrics.current.stack<< render_partial
  end

  ActiveSupport::Notifications.subscribe "render_partial.action_view" do |*args|
    render_partial = Metrics.current.stack.pop
    render_partial.init *args
    render_partial.payload[:identifier] = render_partial.payload[:identifier].gsub("#{Rails.root}/", '') unless render_partial.payload[:identifier].nil?
    if Metrics.current.stack.empty?
      Metrics.current.template.partials<< render_partial
    else
      Metrics.current.stack.peek.partials<< render_partial
    end
  end

  ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, time, finished, transaction_id, payload|
    Metrics.current.name = name
    Metrics.current.time = time
    Metrics.current.end = finished
    Metrics.current.transaction_id = transaction_id
    Metrics.current.payload = payload
    Metrics.current.payload['env'] = env
    memory = `ps -o rss -p #{Process::pid}`.chomp.split("\n").last.strip.to_i / 1024
    Metrics.current.payload['memory'] = memory.to_i
    begin
      data = Metrics.current.to_json
      thread = Thread.new do
        Metrics.push_data(data)
      end
    rescue Exception => e
      Metrics.log("[Rack-Metrics] exception raised: #{e.inspect}")
    end
  end

  ActiveSupport::Notifications.subscribe "sql.active_record" do |*args|
    sql = Event.new *args
    if Metrics.current.is_a?(Rack::Metrics::Event)
      unless sql.payload[:name] == 'SCHEMA'
        sql.payload['stacktrace'] = Metrics.parse_stack(caller(2)).join("\r\n")
        if Metrics.current.stack.empty?
          Metrics.current.template.queries<< sql
        else
          Metrics.current.stack.peek.queries<< sql
        end
      end
    end
  end

  ActiveSupport::Notifications.subscribe "query.moped" do |*args|
    query = Event.new *args
    if Metrics.current.is_a?(Rack::Metrics::Event)
      query.payload['stacktrace'] = Metrics.parse_stack(caller(2)).join("\r\n")
      query.payload['sql'] = query.payload[:ops][0].log_inspect unless query.payload[:ops].nil? or !query.payload[:ops][0].respond_to?(:log_inspect)
      if Metrics.current.stack.empty?
        Metrics.current.template.queries<< query
      else
        Metrics.current.stack.peek.queries<< query
      end
    end
  end
end

Public Instance Methods

current() click to toggle source
# File lib/rack/metrics/metrics.rb, line 42
def current
  Metrics.current
end
current=(c) click to toggle source
# File lib/rack/metrics/metrics.rb, line 46
def current=(c)
  Metrics.current = c
end