class Google::Cloud::Trace::Span
Span
represents a span in a trace record. Spans are contained in a trace and arranged in a forest. That is, each span may be a root span or have a parent span, and may have zero or more children.
Attributes
The ending timestamp of this span in UTC, or `nil` if the ending timestamp has not yet been populated.
@return [Time, nil]
The kind of this span.
@return [Google::Cloud::Trace::SpanKind]
The properties of this span.
@return [Hash{String => String}]
The name of this span.
@return [String]
The TraceSpan object representing this span's parent, or `nil` if this span is a root span.
@return [Google::Cloud::Trace::Span, nil]
The ID of the parent span, as an integer that may be zero if this is a true root span.
Note that it is possible for a span to be “orphaned”, that is, to be a root span with a nonzero parent ID, indicating that parent has not (yet) been written. In that case, `parent` will return nil, but `parent_span_id` will have a value.
@return [Integer]
The numeric ID of this span.
@return [Integer]
The starting timestamp of this span in UTC, or `nil` if the starting timestamp has not yet been populated.
@return [Time, nil]
The Trace
object containing this span.
@return [Google::Cloud::Trace::TraceRecord]
Public Class Methods
Create a new Span
object from a TraceSpan protobuf and insert it into the given trace.
@param [Google::Cloud::Trace::V1::Tracespan] span_proto The
span protobuf from the V1 gRPC Trace API.
@param [Google::Cloud::Trace::TraceRecord] trace The trace object
to contain the span.
@return [Google::Cloud::Trace::Span] A corresponding Span
object.
# File lib/google/cloud/trace/span.rb, line 149 def self.from_grpc span_proto, trace labels = {} span_proto.labels.each { |k, v| labels[k] = v } span_kind = SpanKind.get span_proto.kind start_time = Google::Cloud::Trace::Utils.grpc_to_time span_proto.start_time end_time = Google::Cloud::Trace::Utils.grpc_to_time span_proto.end_time trace.create_span span_proto.name, parent_span_id: span_proto.parent_span_id.to_i, span_id: span_proto.span_id.to_i, kind: span_kind, start_time: start_time, end_time: end_time, labels: labels end
Create an empty Span
object.
@private
# File lib/google/cloud/trace/span.rb, line 105 def initialize trace, id, parent_span_id, parent, name, kind, start_time, end_time, labels @trace = trace @span_id = id @parent_span_id = parent_span_id @parent = parent @children = [] @name = name @kind = kind @start_time = start_time @end_time = end_time @labels = labels end
Public Instance Methods
Add the given span to this span's child list.
@private
# File lib/google/cloud/trace/span.rb, line 399 def add_child child @children << child end
Returns a list of children of this span.
@return [Array{TraceSpan}] The children.
# File lib/google/cloud/trace/span.rb, line 223 def children ensure_exists! @children.dup end
Creates a new child span under this span.
@param [String] name The name of the span. @param [Integer] span_id
The numeric ID of the span, or nil to
generate a new random unique ID. Optional (defaults to nil).
@param [SpanKind] kind The kind of span. Optional. @param [Time] start_time
The starting timestamp, or nil if not yet
specified. Optional (defaults to nil).
@param [Time] end_time
The ending timestamp, or nil if not yet
specified. Optional (defaults to nil).
@param [Hash{String=>String}] labels The span properties. Optional
(defaults to empty).
@return [TraceSpan] The created span.
@example
require "google/cloud/trace" trace_record = Google::Cloud::Trace::TraceRecord.new "my-project" span = trace_record.create_span "root_span" subspan = span.create_span "subspan"
# File lib/google/cloud/trace/span.rb, line 250 def create_span name, span_id: nil, kind: SpanKind::UNSPECIFIED, start_time: nil, end_time: nil, labels: {} ensure_exists! span = trace.internal_create_span self, span_id, self.span_id, name, kind, start_time, end_time, labels @children << span span end
Deletes this span, and all descendant spans. After this completes, {Span#exists?} will return `false`.
# File lib/google/cloud/trace/span.rb, line 350 def delete ensure_exists! @children.each(&:delete) parent&.remove_child self trace.remove_span self @trace = nil @parent = nil self end
Ensure this span exists (i.e. has not been deleted) and throw a RuntimeError if not.
@private
# File lib/google/cloud/trace/span.rb, line 418 def ensure_exists! raise "Span has been deleted" unless trace end
Sets the ending timestamp for this span to the current time, if it has not yet been set. Also ensures that all descendant spans have also been finished. Does nothing if the ending timestamp for this span is already set.
# File lib/google/cloud/trace/span.rb, line 337 def ensure_finished ensure_exists! unless end_time self.end_time = ::Time.now.utc @children.each(&:ensure_finished) end self end
Ensure moving this span under the given parent would not result in a cycle, and throw a RuntimeError if it would.
@private
# File lib/google/cloud/trace/span.rb, line 428 def ensure_no_cycle! new_parent ptr = new_parent until ptr.nil? raise "Move would result in a cycle" if ptr.equal? self ptr = ptr.parent end end
Sets the starting timestamp for this span to the current time, if it has not yet been set. Also ensures that all ancestor spans have also been started. Does nothing if the starting timestamp for this span is already set.
# File lib/google/cloud/trace/span.rb, line 322 def ensure_started ensure_exists! unless start_time self.start_time = ::Time.now.utc parent&.ensure_started end self end
Standard value equality check for this object.
@param [Object] other @return [Boolean]
# File lib/google/cloud/trace/span.rb, line 125 def eql? other other.is_a?(Google::Cloud::Trace::Span) && trace.trace_context == other.trace.trace_context && span_id == other.span_id && parent_span_id == other.parent_span_id && same_children?(other) && kind == other.kind && name == other.name && start_time == other.start_time && end_time == other.end_time && labels == other.labels end
Returns true if this span exists. A span exists until it has been removed from its trace.
@return [Boolean]
# File lib/google/cloud/trace/span.rb, line 194 def exists? !@trace.nil? end
Sets the ending timestamp for this span to the current time. Asserts that the timestamp has not yet been set, and throws a RuntimeError if that is not the case. Also ensures that all descendant spans have also finished, and finishes them if not.
# File lib/google/cloud/trace/span.rb, line 310 def finish! raise "Span not yet started" unless start_time raise "Span already finished" if end_time ensure_finished end
Creates a root span around the given block. Automatically populates the start and end timestamps. The span (with start time but not end time populated) is yielded to the block.
@param [String] name The name of the span. @param [SpanKind] kind The kind of span. Optional. @param [Hash{String=>String}] labels The span properties. Optional
(defaults to empty).
@return [TraceSpan] The created span.
@example
require "google/cloud/trace" trace_record = Google::Cloud::Trace::TraceRecord.new "my-project" trace_record.in_span "root_span" do |span| # Do stuff... span.in_span "subspan" do |subspan| # Do subspan stuff... end # Do stuff... end
# File lib/google/cloud/trace/span.rb, line 283 def in_span name, kind: SpanKind::UNSPECIFIED, labels: {} span = create_span name, kind: kind, labels: labels span.start! yield span ensure span.finish! end
Moves this span under a new parent, which must be part of the same trace. The entire tree under this span moves with it.
@param [Google::Cloud::Trace::Span] new_parent The new parent.
@example
require "google/cloud/trace" trace_record = Google::Cloud::Trace::TraceRecord.new "my-project" root1 = trace_record.create_span "root_span_1" root2 = trace_record.create_span "root_span_2" subspan = root1.create_span "subspan" subspan.move_under root2
# File lib/google/cloud/trace/span.rb, line 375 def move_under new_parent ensure_exists! ensure_no_cycle! new_parent if parent parent.remove_child self else trace.remove_root self end if new_parent new_parent.add_child self @parent_span_id = new_parent.span_id else trace.add_root self @parent_span_id = 0 end @parent = new_parent self end
Remove the given span from this span's child list.
@private
# File lib/google/cloud/trace/span.rb, line 408 def remove_child child @children.delete child end
Returns true if this span has the same children as the given other.
@private
# File lib/google/cloud/trace/span.rb, line 441 def same_children? other child_ids = @children.map(&:span_id) other_child_ids = other.children.map(&:span_id) ::Set.new(child_ids) == ::Set.new(other_child_ids) end
Sets the starting timestamp for this span to the current time. Asserts that the timestamp has not yet been set, and throws a RuntimeError if that is not the case. Also ensures that all ancestor spans have already started, and starts them if not.
# File lib/google/cloud/trace/span.rb, line 298 def start! raise "Span already started" if start_time ensure_started end
Convert this Span
object to an equivalent TraceSpan protobuf suitable for the V1 gRPC Trace
API.
@param [Integer] default_parent_id The parent span ID to use if the
span has no parent in the trace tree. Optional; defaults to 0.
@return [Google::Cloud::Trace::V1::TraceSpan] The generated
protobuf.
# File lib/google/cloud/trace/span.rb, line 175 def to_grpc default_parent_id = 0 start_proto = Google::Cloud::Trace::Utils.time_to_grpc start_time end_proto = Google::Cloud::Trace::Utils.time_to_grpc end_time Google::Cloud::Trace::V1::TraceSpan.new \ span_id: span_id.to_i, kind: kind.to_sym, name: name, start_time: start_proto, end_time: end_proto, parent_span_id: parent_span_id || default_parent_id, labels: labels end
Returns the trace context in effect within this span.
@return [Stackdriver::Core::TraceContext]
# File lib/google/cloud/trace/span.rb, line 203 def trace_context ensure_exists! trace.trace_context.with span_id: span_id end
Returns the trace ID for this span.
@return [String] The trace ID string.
# File lib/google/cloud/trace/span.rb, line 213 def trace_id ensure_exists! trace.trace_id end