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

end_time[RW]

The ending timestamp of this span in UTC, or `nil` if the ending timestamp has not yet been populated.

@return [Time, nil]

kind[RW]

The kind of this span.

@return [Google::Cloud::Trace::SpanKind]

labels[R]

The properties of this span.

@return [Hash{String => String}]

name[RW]

The name of this span.

@return [String]

parent[R]

The TraceSpan object representing this span's parent, or `nil` if this span is a root span.

@return [Google::Cloud::Trace::Span, nil]

parent_span_id[R]

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]

span_id[R]

The numeric ID of this span.

@return [Integer]

start_time[RW]

The starting timestamp of this span in UTC, or `nil` if the starting timestamp has not yet been populated.

@return [Time, nil]

trace[R]

The Trace object containing this span.

@return [Google::Cloud::Trace::TraceRecord]

Public Class Methods

from_grpc(span_proto, trace) click to toggle source

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
new(trace, id, parent_span_id, parent, name, kind, start_time, end_time, labels) click to toggle source

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

==(other)
Alias for: eql?
add_child(child) click to toggle source

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
children() click to toggle source

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
create_span(name, span_id: nil, kind: SpanKind::UNSPECIFIED, start_time: nil, end_time: nil, labels: {}) click to toggle source

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
delete() click to toggle source

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_exists!() click to toggle source

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
ensure_finished() click to toggle source

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_no_cycle!(new_parent) click to toggle source

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
ensure_started() click to toggle source

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
eql?(other) click to toggle source

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
Also aliased as: ==
exists?() click to toggle source

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
finish!() click to toggle source

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
in_span(name, kind: SpanKind::UNSPECIFIED, labels: {}) { |span| ... } click to toggle source

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
move_under(new_parent) click to toggle source

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_child(child) click to toggle source

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
same_children?(other) click to toggle source

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
start!() click to toggle source

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
to_grpc(default_parent_id = 0) click to toggle source

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
trace_context() click to toggle source

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
trace_id() click to toggle source

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