class OpticsAgent::Agent
Attributes
logger[RW]
report_traces[R]
schema[R]
Public Class Methods
new()
click to toggle source
# File lib/optics-agent/agent.rb, line 24 def initialize @stats_reporting_thread = nil @query_queue = [] @semaphone = Mutex.new # set defaults @configuration = Configuration.new end
Public Instance Methods
add_query(*args)
click to toggle source
# File lib/optics-agent/agent.rb, line 166 def add_query(*args) @semaphone.synchronize { debug { "adding query to queue, queue length was #{@query_queue.length}" } @query_queue << args } end
clear_query_queue()
click to toggle source
# File lib/optics-agent/agent.rb, line 173 def clear_query_queue @semaphone.synchronize { debug { "clearing query queue, queue length was #{@query_queue.length}" } queue = @query_queue @query_queue = [] queue } end
configure(&block)
click to toggle source
# File lib/optics-agent/agent.rb, line 33 def configure(&block) @configuration.instance_eval(&block) if @configuration.schema && @schema != @configuration.schema instrument_schema(@configuration.schema) end end
debug(message = nil) { || ... }
click to toggle source
Should we be using built in debug levels rather than our own “debug” flag?
# File lib/optics-agent/agent.rb, line 220 def debug(message = nil) if @configuration.debug message = yield unless message self.class.logger.info "optics-agent: DEBUG: #{message} <#{Process.pid} | #{Thread.current.object_id}>" end end
disabled?()
click to toggle source
# File lib/optics-agent/agent.rb, line 41 def disabled? @configuration.disable_reporting || !@configuration.api_key || !@schema end
ensure_reporting!()
click to toggle source
@deprecated Use ensure_reporting_stats! instead
# File lib/optics-agent/agent.rb, line 95 def ensure_reporting! ensure_reporting_stats! end
ensure_reporting_stats!()
click to toggle source
We call this method on every request to ensure that the reporting thread is active in the correct process for pre-forking webservers like unicorn
# File lib/optics-agent/agent.rb, line 81 def ensure_reporting_stats! unless @schema warn """No schema instrumented. Use the `schema` configuration setting, or call `agent.instrument_schema` """ return end unless reporting_stats? || disabled? schedule_report end end
graphql_middleware()
click to toggle source
# File lib/optics-agent/agent.rb, line 189 def graphql_middleware warn "You no longer need to pass the optics agent middleware, it now attaches itself" end
instrument_schema(schema)
click to toggle source
# File lib/optics-agent/agent.rb, line 49 def instrument_schema(schema) unless @configuration.api_key warn """No api_key set. Either configure it or use the OPTICS_API_KEY environment variable. """ return end if @schema warn """Agent has already instrumented a schema. Perhaps you are calling both `agent.configure { schema YourSchema }` and `agent.instrument_schema YourSchema`? """ return end @schema = schema @schema._attach_optics_agent(self) unless disabled? debug "spawning schema thread" Thread.new do debug "schema thread spawned" sleep @configuration.schema_report_delay_ms / 1000.0 debug "running schema job" SchemaJob.new.perform(self) end end end
log(message = nil) { || ... }
click to toggle source
# File lib/optics-agent/agent.rb, line 210 def log(message = nil) message = yield unless message self.class.logger.info "optics-agent: #{message}" end
rack_middleware()
click to toggle source
# File lib/optics-agent/agent.rb, line 182 def rack_middleware # We need to pass ourselves to the class we return here because # rack will instanciate it. (See comment at the top of RackMiddleware) OpticsAgent::RackMiddleware.agent = self OpticsAgent::RackMiddleware end
report_traces?()
click to toggle source
# File lib/optics-agent/agent.rb, line 45 def report_traces? @configuration.report_traces end
reporting_connection()
click to toggle source
# File lib/optics-agent/agent.rb, line 99 def reporting_connection @reporting_connection ||= Faraday.new(:url => @configuration.endpoint_url) do |conn| conn.request :retry, :max => 5, :interval => 0.1, :max_interval => 10, :backoff_factor => 2, :exceptions => [Exception], :retry_if => ->(env, exc) { true } conn.use OpticsAgent::Reporting::DetectServerSideError # XXX: allow setting adaptor in config conn.adapter :net_http_persistent end end
reporting_stats?()
click to toggle source
# File lib/optics-agent/agent.rb, line 116 def reporting_stats? @stats_reporting_thread != nil && !!@stats_reporting_thread.status end
schedule_report()
click to toggle source
# File lib/optics-agent/agent.rb, line 120 def schedule_report @semaphone.synchronize do return if reporting_stats? debug "spawning reporting thread" thread = Thread.new do begin debug "reporting thread spawned" report_interval = @configuration.report_interval_ms / 1000.0 last_started = Time.now while true next_send = last_started + report_interval sleep_time = next_send - Time.now if sleep_time < 0 warn 'Report took more than one interval! Some requests might appear at the wrong time.' else sleep sleep_time end debug "running reporting job" last_started = Time.now ReportJob.new.perform(self) debug "finished running reporting job" end rescue Exception => e warn "Stats report thread dying: #{e}" end end at_exit do if thread.status debug 'sending last stats report before exiting' thread.exit ReportJob.new.perform(self) debug 'last stats report sent' end end @stats_reporting_thread = thread end end
send_message(path, message)
click to toggle source
# File lib/optics-agent/agent.rb, line 193 def send_message(path, message) response = reporting_connection.post do |request| request.url path request.headers['x-api-key'] = @configuration.api_key request.headers['user-agent'] = "optics-agent-rb" request.body = message.class.encode(message) if @configuration.debug || @configuration.print_reports log "sending message: #{message.class.encode_json(message)}" end end if @configuration.debug || @configuration.print_reports log "got response body: #{response.body}" end end
warn(message = nil)
click to toggle source
# File lib/optics-agent/agent.rb, line 215 def warn(message = nil) self.class.logger.warn "optics-agent: WARNING: #{message}" end