Class: Datadog::Span
- Inherits:
-
Object
- Object
- Datadog::Span
- Includes:
- Analytics::Span, ForcedTracing::Span
- Defined in:
- lib/ddtrace/span.rb
Overview
Represents a logical unit of work in the system. Each trace consists of one or more spans. Each span consists of a start time and a duration. For example, a span can describe the time spent on a distributed call on a separate machine, or the time spent in a small component within a larger operation. Spans can be nested within each other, and in those instances will have a parent-child relationship.
rubocop:disable Metrics/ClassLength
Constant Summary collapse
- MAX_ID =
The max value for a Span identifier. Span and trace identifiers should be strictly positive and strictly inferior to this limit.
Limited to 63-bit positive integers, as some other languages might be limited to this, and IDs need to be easy to port across various languages and platforms.
2**63
- EXTERNAL_MAX_ID =
While we only generate 63-bit integers due to limitations in other languages, we support parsing 64-bit integers for distributed tracing since an upstream system may generate one
2**64
Instance Attribute Summary collapse
-
#context ⇒ Object
Returns the value of attribute context.
-
#end_time ⇒ Object
Returns the value of attribute end_time.
-
#name ⇒ Object
Returns the value of attribute name.
-
#parent ⇒ Object
Returns the value of attribute parent.
-
#parent_id ⇒ Object
Returns the value of attribute parent_id.
-
#resource ⇒ Object
Returns the value of attribute resource.
-
#sampled ⇒ Object
Returns the value of attribute sampled.
-
#service ⇒ Object
Returns the value of attribute service.
-
#span_id ⇒ Object
Returns the value of attribute span_id.
-
#span_type ⇒ Object
Returns the value of attribute span_type.
-
#start_time ⇒ Object
Returns the value of attribute start_time.
-
#status ⇒ Object
Returns the value of attribute status.
-
#trace_id ⇒ Object
Returns the value of attribute trace_id.
-
#tracer ⇒ Object
Returns the value of attribute tracer.
Instance Method Summary collapse
- #allocations ⇒ Object
-
#finish(finish_time = nil) ⇒ Object
Mark the span finished at the current time and submit it.
-
#finished? ⇒ Boolean
Return whether the span is finished or not.
-
#get_metric(key) ⇒ Object
Return the metric with the given key, nil if it doesn’t exist.
-
#get_tag(key) ⇒ Object
Return the tag with the given key, nil if it doesn’t exist.
-
#initialize(tracer, name, options = {}) ⇒ Span
constructor
Create a new span linked to the given tracer.
-
#pretty_print(q) ⇒ Object
Return a human readable version of the span.
-
#set_error(e) ⇒ Object
Mark the span with the given error.
-
#set_metric(key, value) ⇒ Object
This method sets a tag with a floating point value for the given key.
-
#set_parent(parent) ⇒ Object
DEPRECATED: remove this function in the next release, replaced by “parent=“.
-
#set_tag(key, value = nil) ⇒ Object
Set the given key / value tag pair on the span.
-
#to_hash ⇒ Object
Return the hash representation of the current span.
-
#to_s ⇒ Object
Return a string representation of the span.
Constructor Details
#initialize(tracer, name, options = {}) ⇒ Span
Create a new span linked to the given tracer. Call the Tracer method start_span()
and then finish()
once the tracer operation is over.
-
service
: the service name for this span -
resource
: the resource this span refers, orname
if it’s missing -
span_type
: the type of the span (such ashttp
,db
and so on) -
parent_id
: the identifier of the parent span -
trace_id
: the identifier of the root span for this trace -
context
: the context of the span
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/ddtrace/span.rb', line 49 def initialize(tracer, name, = {}) @tracer = tracer @name = name @service = .fetch(:service, nil) @resource = .fetch(:resource, name) @span_type = .fetch(:span_type, nil) @span_id = Datadog::Utils.next_id @parent_id = .fetch(:parent_id, 0) @trace_id = .fetch(:trace_id, Datadog::Utils.next_id) @context = .fetch(:context, nil) @meta = {} @metrics = {} @status = 0 @parent = nil @sampled = true @start_time = nil # set by Tracer.start_span @end_time = nil # set by Span.finish @allocation_count_start = now_allocations @allocation_count_finish = @allocation_count_start end |
Instance Attribute Details
#context ⇒ Object
Returns the value of attribute context.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def context @context end |
#end_time ⇒ Object
Returns the value of attribute end_time.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def end_time @end_time end |
#name ⇒ Object
Returns the value of attribute name.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def name @name end |
#parent ⇒ Object
Returns the value of attribute parent.
39 40 41 |
# File 'lib/ddtrace/span.rb', line 39 def parent @parent end |
#parent_id ⇒ Object
Returns the value of attribute parent_id.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def parent_id @parent_id end |
#resource ⇒ Object
Returns the value of attribute resource.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def resource @resource end |
#sampled ⇒ Object
Returns the value of attribute sampled.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def sampled @sampled end |
#service ⇒ Object
Returns the value of attribute service.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def service @service end |
#span_id ⇒ Object
Returns the value of attribute span_id.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def span_id @span_id end |
#span_type ⇒ Object
Returns the value of attribute span_type.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def span_type @span_type end |
#start_time ⇒ Object
Returns the value of attribute start_time.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def start_time @start_time end |
#status ⇒ Object
Returns the value of attribute status.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def status @status end |
#trace_id ⇒ Object
Returns the value of attribute trace_id.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def trace_id @trace_id end |
#tracer ⇒ Object
Returns the value of attribute tracer.
33 34 35 |
# File 'lib/ddtrace/span.rb', line 33 def tracer @tracer end |
Instance Method Details
#allocations ⇒ Object
182 183 184 |
# File 'lib/ddtrace/span.rb', line 182 def allocations @allocation_count_finish - @allocation_count_start end |
#finish(finish_time = nil) ⇒ Object
Mark the span finished at the current time and submit it.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/ddtrace/span.rb', line 118 def finish(finish_time = nil) # A span should not be finished twice. Note that this is not thread-safe, # finish is called from multiple threads, a given span might be finished # several times. Again, one should not do this, so this test is more a # fallback to avoid very bad things and protect you in most common cases. return if finished? @allocation_count_finish = now_allocations # Provide a default start_time if unset, but this should have been set by start_span. # Using now here causes 0-duration spans, still, this is expected, as we never # explicitely say when it started. @start_time ||= Time.now.utc @end_time = finish_time.nil? ? Time.now.utc : finish_time # finish this # Finish does not really do anything if the span is not bound to a tracer and a context. return self if @tracer.nil? || @context.nil? # spans without a service would be dropped, so here we provide a default. # This should really never happen with integrations in contrib, as a default # service is always set. It's only for custom instrumentation. @service ||= @tracer.default_service unless @tracer.nil? begin @context.close_span(self) @tracer.record(self) rescue StandardError => e Datadog::Tracer.log.debug("error recording finished trace: #{e}") end self end |
#finished? ⇒ Boolean
Return whether the span is finished or not.
152 153 154 |
# File 'lib/ddtrace/span.rb', line 152 def finished? !@end_time.nil? end |
#get_metric(key) ⇒ Object
Return the metric with the given key, nil if it doesn’t exist.
103 104 105 |
# File 'lib/ddtrace/span.rb', line 103 def get_metric(key) @metrics[key] end |
#get_tag(key) ⇒ Object
Return the tag with the given key, nil if it doesn’t exist.
88 89 90 |
# File 'lib/ddtrace/span.rb', line 88 def get_tag(key) @meta[key] end |
#pretty_print(q) ⇒ Object
Return a human readable version of the span
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/ddtrace/span.rb', line 211 def pretty_print(q) start_time = (@start_time.to_f * 1e9).to_i rescue '-' end_time = (@end_time.to_f * 1e9).to_i rescue '-' duration = ((@end_time - @start_time) * 1e9).to_i rescue 0 q.group 0 do q.breakable q.text "Name: #{@name}\n" q.text "Span ID: #{@span_id}\n" q.text "Parent ID: #{@parent_id}\n" q.text "Trace ID: #{@trace_id}\n" q.text "Type: #{@span_type}\n" q.text "Service: #{@service}\n" q.text "Resource: #{@resource}\n" q.text "Error: #{@status}\n" q.text "Start: #{start_time}\n" q.text "End: #{end_time}\n" q.text "Duration: #{duration}\n" q.text "Allocations: #{allocations}\n" q.group(2, 'Tags: [', "]\n") do q.breakable q.seplist @meta.each do |key, value| q.text "#{key} => #{value}" end end q.group(2, 'Metrics: [', ']') do q.breakable q.seplist @metrics.each do |key, value| q.text "#{key} => #{value}" end end end end |
#set_error(e) ⇒ Object
Mark the span with the given error.
108 109 110 111 112 113 114 115 |
# File 'lib/ddtrace/span.rb', line 108 def set_error(e) e = Error.build_from(e) @status = Ext::Errors::STATUS set_tag(Ext::Errors::TYPE, e.type) unless e.type.empty? set_tag(Ext::Errors::MSG, e.) unless e..empty? set_tag(Ext::Errors::STACK, e.backtrace) unless e.backtrace.empty? end |
#set_metric(key, value) ⇒ Object
This method sets a tag with a floating point value for the given key. It acts like ‘set_tag()` and it simply add a tag without further processing.
94 95 96 97 98 99 100 |
# File 'lib/ddtrace/span.rb', line 94 def set_metric(key, value) # enforce that the value is a floating point number value = Float(value) @metrics[key] = value rescue StandardError => e Datadog::Tracer.log.debug("Unable to set the metric #{key}, ignoring it. Caused by: #{e}") end |
#set_parent(parent) ⇒ Object
DEPRECATED: remove this function in the next release, replaced by “parent=“
162 163 164 |
# File 'lib/ddtrace/span.rb', line 162 def set_parent(parent) self.parent = parent end |
#set_tag(key, value = nil) ⇒ Object
Set the given key / value tag pair on the span. Keys and values must be strings. A valid example is:
span.set_tag('http.method', request.method)
81 82 83 84 85 |
# File 'lib/ddtrace/span.rb', line 81 def set_tag(key, value = nil) @meta[key] = value.to_s rescue StandardError => e Datadog::Tracer.log.debug("Unable to set the tag #{key}, ignoring it. Caused by: #{e}") end |
#to_hash ⇒ Object
Return the hash representation of the current span.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/ddtrace/span.rb', line 187 def to_hash h = { span_id: @span_id, parent_id: @parent_id, trace_id: @trace_id, name: @name, service: @service, resource: @resource, type: @span_type, meta: @meta, metrics: @metrics, allocations: allocations, error: @status } if !@start_time.nil? && !@end_time.nil? h[:start] = (@start_time.to_f * 1e9).to_i h[:duration] = ((@end_time - @start_time) * 1e9).to_i end h end |
#to_s ⇒ Object
Return a string representation of the span.
157 158 159 |
# File 'lib/ddtrace/span.rb', line 157 def to_s "Span(name:#{@name},sid:#{@span_id},tid:#{@trace_id},pid:#{@parent_id})" end |