class Skylight::Core::Instrumenter
@api private
Constants
- KEY
- TOO_MANY_UNIQUES
Attributes
config[R]
gc[R]
uuid[R]
Public Class Methods
match?(string, regex)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 202 def self.match?(string, regex) @scanner ||= StringScanner.new("") @scanner.string = string @scanner.match?(regex) end
native_new(_uuid, _config_env)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 45 def self.native_new(_uuid, _config_env) raise "not implemented" end
new(config)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 49 def self.new(config) config.validate! uuid = SecureRandom.uuid inst = native_new(uuid, config.to_native_env) inst.send(:initialize, uuid, config) inst end
new(uuid, config)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 58 def initialize(uuid, config) @uuid = uuid @gc = config.gc @config = config @subscriber = Subscriber.new(config, self) key = "#{KEY}_#{self.class.trace_class.name}".gsub(/\W/, "_") @trace_info = @config[:trace_info] || TraceInfo.new(key) @mutex = Mutex.new end
trace_class()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 41 def self.trace_class Trace end
Public Instance Methods
broken!()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 258 def broken! return unless (trace = @trace_info.current) trace.broken! end
check_install!()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 98 def check_install! true end
current_trace()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 89 def current_trace @trace_info.current end
current_trace=(trace)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 93 def current_trace=(trace) t { "setting current_trace=#{trace ? trace.uuid : 'nil'}; thread=#{Thread.current.object_id}" } @trace_info.current = trace end
done(span, meta = nil)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 271 def done(span, meta = nil) return unless (trace = @trace_info.current) trace.done(span, meta) end
finalize_endpoint_segment(trace)
click to toggle source
Because GraphQL can return multiple results, each of which may have their own success/error states, we need to set the skylight segment as follows:
-
when all queries have errors: “error”
-
when some queries have errors: “<rendered format>+error”
-
when no queries have errors: “<rendered format>”
<rendered format> will be determined by the Rails controller as usual. See Instrumenter#finalize_endpoint_segment
for the actual segment/error assignment.
# File lib/skylight/core/instrumenter.rb, line 330 def finalize_endpoint_segment(trace) return unless (segment = trace.segment) segment = case trace.compound_response_error_status when :all "error" when :partial "#{segment}+error" else segment end trace.endpoint += "<sk-segment>#{segment}</sk-segment>" end
handle_instrumenter_error(trace, e)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 305 def handle_instrumenter_error(trace, e) warn "failed to submit trace to worker; trace=%s, err=%s", trace.uuid, e t { "BACKTRACE:\n#{e.backtrace.join("\n")}" } false end
ignore?(trace)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 311 def ignore?(trace) config.ignored_endpoints.include?(trace.endpoint) end
instrument(cat, title = nil, desc = nil, meta = nil) { || ... }
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 212 def instrument(cat, title = nil, desc = nil, meta = nil) raise ArgumentError, "cat is required" unless cat if muted? return yield if block_given? return end unless (trace = @trace_info.current) return yield if block_given? return end cat = cat.to_s unless match?(cat, Skylight::CATEGORY_REGEX) warn "invalid skylight instrumentation category; trace=%s; value=%s", trace.uuid, cat return yield if block_given? return end cat = "other.#{cat}" unless match?(cat, Skylight::TIER_REGEX) unless (sp = trace.instrument(cat, title, desc, meta)) return yield if block_given? return end return sp unless block_given? meta = {} begin yield sp rescue Exception => e meta = { exception: [e.class.name, e.message], exception_object: e } raise e ensure trace.done(sp, meta) end end
limited_description(description)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 276 def limited_description(description) endpoint = @trace_info.current.endpoint if description if native_track_desc(endpoint, description) description else TOO_MANY_UNIQUES end end end
log_context()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 69 def log_context @log_context ||= { inst: uuid } end
match?(string, regex)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 208 def match?(string, regex) self.class.match?(string, regex) end
mute() { || ... }
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 110 def mute old_muted = muted? self.muted = true yield if block_given? ensure self.muted = old_muted end
Also aliased as: disable
muted=(val)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 102 def muted=(val) @trace_info.muted = val end
muted?()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 106 def muted? @trace_info.muted? end
Also aliased as: disabled?
native_start()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 73 def native_start raise "not implemented" end
native_stop()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 77 def native_stop raise "not implemented" end
native_submit_trace(_trace)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 85 def native_submit_trace(_trace) raise "not implemented" end
native_track_desc(_endpoint, _description)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 81 def native_track_desc(_endpoint, _description) raise "not implemented" end
poison!()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 263 def poison! @poisoned = true end
poisoned?()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 267 def poisoned? @poisoned end
process(trace)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 288 def process(trace) t { fmt "processing trace=#{trace.uuid}" } if ignore?(trace) t { fmt "ignoring trace=#{trace.uuid}" } return false end begin finalize_endpoint_segment(trace) native_submit_trace(trace) true rescue => e handle_instrumenter_error(trace, e) end end
process_sql(sql)
click to toggle source
Return [title, sql]
# File lib/skylight/core/instrumenter.rb, line 316 def process_sql(sql) [nil, sql] end
shutdown()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 170 def shutdown @subscriber.unregister! native_stop end
silence_warnings(context)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 126 def silence_warnings(context) @warnings_silenced || @mutex.synchronize do @warnings_silenced ||= {} end @warnings_silenced[context] = true end
span_correlation_header(span)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 253 def span_correlation_header(span) return unless (trace = @trace_info.current) trace.span_correlation_header(span) end
start!()
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 141 def start! # We do this here since we can't report these issues via Gem install without stopping install entirely. check_install! t { "starting instrumenter" } unless config.validate_with_server log_error "invalid config" return end t { "starting native instrumenter" } unless native_start warn "failed to start instrumenter" return end config.gc.enable @subscriber.register! ActiveSupport::Notifications.instrument("started_instrumenter.skylight", instrumenter: self) self rescue Exception => e log_error "failed to start instrumenter; msg=%s; config=%s", e.message, config.inspect t { e.backtrace.join("\n") } nil end
trace(endpoint, cat, title = nil, desc = nil, meta: nil, segment: nil, component: nil) { |trace| ... }
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 175 def trace(endpoint, cat, title = nil, desc = nil, meta: nil, segment: nil, component: nil) # If a trace is already in progress, continue with that one if (trace = @trace_info.current) return yield(trace) if block_given? return trace end begin trace = self.class.trace_class.new(self, endpoint, Util::Clock.nanos, cat, title, desc, meta: meta, segment: segment, component: component) rescue Exception => e log_error e.message t { e.backtrace.join("\n") } return end @trace_info.current = trace return trace unless block_given? begin yield trace ensure @trace_info.current = nil t { "instrumenter submitting trace; trace=#{trace.uuid}" } trace.submit end end
unmute() { || ... }
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 118 def unmute old_muted = muted? self.muted = false yield if block_given? ensure self.muted = old_muted end
warnings_silenced?(context)
click to toggle source
# File lib/skylight/core/instrumenter.rb, line 134 def warnings_silenced?(context) @warnings_silenced && @warnings_silenced[context] end