Class: Skylight::Trace
- Includes:
- Util::Logging
- Defined in:
- lib/skylight/trace.rb
Constant Summary collapse
- GC_CAT =
"noise.gc".freeze
- SYNTHETIC =
"<synthetic>".freeze
- META_KEYS =
%i[mute_children database].freeze
Instance Attribute Summary collapse
-
#component ⇒ Object
readonly
Returns the value of attribute component.
-
#compound_response_error_status ⇒ Object
Returns the value of attribute compound_response_error_status.
-
#endpoint ⇒ Object
Returns the value of attribute endpoint.
-
#instrumenter ⇒ Object
readonly
Returns the value of attribute instrumenter.
-
#meta ⇒ Object
readonly
Returns the value of attribute meta.
-
#notifications ⇒ Object
readonly
Returns the value of attribute notifications.
-
#segment ⇒ Object
Returns the value of attribute segment.
Class Method Summary collapse
- .new(instrumenter, endpoint, start, cat, title = nil, desc = nil, meta: nil, segment: nil, component: nil) ⇒ Object
-
.normalize_time(time) ⇒ Object
TODO: Move this into native.
Instance Method Summary collapse
- #broken! ⇒ Object
- #broken? ⇒ Boolean
- #config ⇒ Object
- #done(span, meta = nil) ⇒ Object
- #endpoint_assignment_muted? ⇒ Boolean
-
#initialize(instrumenter, cat, title, desc, meta, component: nil) ⇒ Trace
constructor
A new instance of Trace.
- #inspect ⇒ Object
- #instrument(cat, title = nil, desc = nil, meta = nil) ⇒ Object
- #log_context ⇒ Object
- #maybe_broken(err) ⇒ Object
- #muted ⇒ Object
- #release ⇒ Object
- #submit ⇒ Object
- #too_many_spans! ⇒ Object
- #too_many_spans? ⇒ Boolean
- #traced ⇒ Object
- #tracing_muted? ⇒ Boolean
- #uuid ⇒ Object
- #uuid=(value) ⇒ Object
Methods included from Util::Logging
#config_for_logging, #debug, #error, #fmt, #info, #log, #raise_on_error?, #t, #trace, #trace?, #warn
Constructor Details
#initialize(instrumenter, cat, title, desc, meta, component: nil) ⇒ Trace
Returns a new instance of Trace.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/skylight/trace.rb', line 32 def initialize(instrumenter, cat, title, desc, , component: nil) raise ArgumentError, "instrumenter is required" unless instrumenter @instrumenter = instrumenter @submitted = false @broken = false @notifications = [] @spans = [] () if # create the root node @root = start(native_get_started_at, cat, title, desc, , normalize: false) # Also store meta for later access @meta = @gc = config.gc.track unless ENV.key?("SKYLIGHT_DISABLE_GC_TRACKING") self.component = component if component @too_many_spans = false native_use_pruning if use_pruning? end |
Instance Attribute Details
#component ⇒ Object
Returns the value of attribute component.
13 14 15 |
# File 'lib/skylight/trace.rb', line 13 def component @component end |
#compound_response_error_status ⇒ Object
Returns the value of attribute compound_response_error_status.
90 91 92 |
# File 'lib/skylight/trace.rb', line 90 def compound_response_error_status @compound_response_error_status end |
#endpoint ⇒ Object
Returns the value of attribute endpoint.
13 14 15 |
# File 'lib/skylight/trace.rb', line 13 def endpoint @endpoint end |
#instrumenter ⇒ Object (readonly)
Returns the value of attribute instrumenter.
13 14 15 |
# File 'lib/skylight/trace.rb', line 13 def instrumenter @instrumenter end |
#meta ⇒ Object (readonly)
Returns the value of attribute meta.
13 14 15 |
# File 'lib/skylight/trace.rb', line 13 def @meta end |
#notifications ⇒ Object (readonly)
Returns the value of attribute notifications.
13 14 15 |
# File 'lib/skylight/trace.rb', line 13 def notifications @notifications end |
#segment ⇒ Object
Returns the value of attribute segment.
13 14 15 |
# File 'lib/skylight/trace.rb', line 13 def segment @segment end |
Class Method Details
.new(instrumenter, endpoint, start, cat, title = nil, desc = nil, meta: nil, segment: nil, component: nil) ⇒ Object
15 16 17 18 19 20 21 22 23 |
# File 'lib/skylight/trace.rb', line 15 def self.new(instrumenter, endpoint, start, cat, title = nil, desc = nil, meta: nil, segment: nil, component: nil) uuid = SecureRandom.uuid inst = native_new(normalize_time(start), uuid, endpoint, ) inst.uuid = uuid inst.send(:initialize, instrumenter, cat, title, desc, , component: component) inst.endpoint = endpoint inst.segment = segment inst end |
.normalize_time(time) ⇒ Object
TODO: Move this into native
26 27 28 29 30 |
# File 'lib/skylight/trace.rb', line 26 def self.normalize_time(time) # At least one customer has extensions that cause integer division to produce rationals. # Since the native code expects an integer, we force it again. (time.to_i / 100_000).to_i end |
Instance Method Details
#broken! ⇒ Object
174 175 176 177 |
# File 'lib/skylight/trace.rb', line 174 def broken! debug "trace is broken" @broken = true end |
#broken? ⇒ Boolean
108 109 110 |
# File 'lib/skylight/trace.rb', line 108 def broken? !!@broken end |
#config ⇒ Object
92 93 94 |
# File 'lib/skylight/trace.rb', line 92 def config @instrumenter.config end |
#done(span, meta = nil) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/skylight/trace.rb', line 140 def done(span, = nil) # `span` will be `nil` if we failed to start instrumenting, such as in # the case of too many spans in a request. return unless span return if broken? if &.[](:defer) deferred_spans[span] ||= (Skylight::Util::Clock.nanos - gc_time) return end if && ([:exception_object] || [:exception]) native_span_set_exception(span, [:exception_object], [:exception]) end stop(span, Skylight::Util::Clock.nanos - gc_time) rescue StandardError => e error "failed to close span; msg=%s; endpoint=%s", e., endpoint log_trace "Original Backtrace:\n#{e.backtrace.join("\n")}" broken! nil end |
#endpoint_assignment_muted? ⇒ Boolean
104 105 106 |
# File 'lib/skylight/trace.rb', line 104 def endpoint_assignment_muted? tracing_muted? || @instrumenter.endpoint_assignment_muted? end |
#inspect ⇒ Object
163 164 165 |
# File 'lib/skylight/trace.rb', line 163 def inspect to_s end |
#instrument(cat, title = nil, desc = nil, meta = nil) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/skylight/trace.rb', line 121 def instrument(cat, title = nil, desc = nil, = nil) return if tracing_muted? return if broken? t { "instrument: #{cat}, #{title}" } title.freeze if title.is_a?(String) desc.freeze if desc.is_a?(String) now = Skylight::Util::Clock.nanos () if start(now - gc_time, cat, title, desc, ) rescue StandardError => e maybe_broken(e) nil end |
#log_context ⇒ Object
75 76 77 |
# File 'lib/skylight/trace.rb', line 75 def log_context @log_context ||= { trace: uuid } end |
#maybe_broken(err) ⇒ Object
112 113 114 115 116 117 118 119 |
# File 'lib/skylight/trace.rb', line 112 def maybe_broken(err) if err.is_a?(Skylight::MaximumTraceSpansError) && config.get(:report_max_spans_exceeded) too_many_spans! else error "failed to instrument span; msg=%s; endpoint=%s", err., endpoint broken! end end |
#muted ⇒ Object
96 97 98 |
# File 'lib/skylight/trace.rb', line 96 def muted @child_instrumentation_muted_by || @instrumenter.muted end |
#release ⇒ Object
167 168 169 170 171 172 |
# File 'lib/skylight/trace.rb', line 167 def release t { "release; is_current=#{@instrumenter.current_trace == self}" } return unless @instrumenter.current_trace == self @instrumenter.current_trace = nil end |
#submit ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/skylight/trace.rb', line 195 def submit t { "submitting trace" } # This must always be called to clean up properly release if broken? t { "broken, not submitting" } return end if @submitted t { "already submitted" } return end @submitted = true traced @instrumenter.process(self) rescue Exception => e error e. t { e.backtrace.join("\n") } end |
#too_many_spans! ⇒ Object
67 68 69 |
# File 'lib/skylight/trace.rb', line 67 def too_many_spans! @too_many_spans = true end |
#too_many_spans? ⇒ Boolean
71 72 73 |
# File 'lib/skylight/trace.rb', line 71 def too_many_spans? !!@too_many_spans end |
#traced ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/skylight/trace.rb', line 179 def traced if too_many_spans? error( "[E%04d] The request exceeded the maximum number of spans allowed. It will still " \ "be tracked but with reduced information. endpoint=%s", Skylight::MaximumTraceSpansError.code, endpoint ) end gc = gc_time now = Skylight::Util::Clock.nanos track_gc(gc, now) stop(@root, now) end |
#tracing_muted? ⇒ Boolean
100 101 102 |
# File 'lib/skylight/trace.rb', line 100 def tracing_muted? !!@child_instrumentation_muted_by || @instrumenter.tracing_muted? end |
#uuid ⇒ Object
58 59 60 |
# File 'lib/skylight/trace.rb', line 58 def uuid native_get_uuid end |
#uuid=(value) ⇒ Object
62 63 64 65 |
# File 'lib/skylight/trace.rb', line 62 def uuid=(value) # We can't change the UUID so just check to make sure we weren't trying to change raise "unable to change uuid" unless value == uuid end |