require 'uuid' require 'yajl' require 'socket' module Caliper class Tracer attr_accessor :uuid, :http_method, :uri, :path, :remote_ip, :samples, :host, :reqs, :extra_info def initialize(env) @uuid = UUID.generate @http_method = env['REQUEST_METHOD'] @uri = env['REQUEST_URI'] # full URI @path = env['PATH_INFO'] # user path_info because it's in the rack spec rather than REQUEST_PATH @remote_ip = env["action_dispatch.remote_ip"] #requesting ip @remote_ip = @remote_ip.first if @remote_ip.is_a?(Array) @host = Socket.gethostname @samples = [] end def record(event) event.payload.delete(:caliper_tracer) if event.payload[:caliper_tracer] return if event.name[/active_record/] && (event.payload[:name] == nil || event.payload[:name][/SCHEMA/]) # strip un-required payload data for activerecord notifications if event.name[/active_record/] ["binds", "connection_id"].each do |key| event.payload.delete(key) end end #Caliper.logger.debug [event.name, event.time, event.end, event.transaction_id, event.payload].join("||") @samples << event end def add_to_trace(data = {}) @extra_info = data end def finish return true if samples.size == 0 trace_data = { "uuid" => uuid, "http_method" => http_method, "uri" => uri, "path" => path, "remote_ip" => remote_ip.to_s, "host" => host, "reqs" => reqs, "extra_info" => extra_info, "samples" => [] } samples.each do |sample| trace_data["samples"] << { "name" => sample.name, "duration" => sample.duration, #"start" => sample.time, #"end" => sample.end, "payload" => sample.payload } if sample.name[/process_action.action_controller/] trace_data["view_runtime"] = sample.payload[:view_runtime] trace_data["db_runtime"] = sample.payload[:db_runtime] trace_data["duration"] = sample.duration end end CaliperApi.create_trace( Yajl::Encoder.encode({ "trace" => trace_data }) ) end end end