class OpenCensus::Trace::SpanContext

SpanContext represents the context within which a span may be created. It includes the ID of the parent trace, the ID of the parent span, and sampling state.

Constants

MAX_SPAN_ID

Maximum integer value for a `span_id` @private

MAX_TRACE_ID

Maximum integer value for a `trace_id` @private

TraceData

Internal struct that holds trace-wide data. @private

Attributes

parent[R]

The parent of this context, or `nil` if this is a root context.

@return [SpanContext, nil]

same_process_as_parent[R]

Whether the parent of spans created by this context is local, or `nil` if this context creates root spans or this information is unknown.

@return [boolean, nil]

span_id[R]

The span ID as a 16-character hex string, or the empty string if the context refers to the root of the trace.

@return [String]

trace_options[R]

The original trace options byte used to create this span context.

@return [Integer]

Public Class Methods

create_root(trace_context: nil, same_process_as_parent: nil) click to toggle source

Create a new root SpanContext object, given either a traceparent header value by itself, or an entire Rack environment. If a valid traceparent header can be obtained from either source, it is used to generate the SpanContext. Otherwise, a new root context with a unique `trace_id` and a root `span_id` of “” is used.

@param [TraceContextData] trace_context The request's incoming trace

context (optional)

@param [boolean, nil] same_process_as_parent Set to `true` if the

parent span is local, `false` if it is remote, or `nil` if there
is no parent span or this information is not available.

@return [SpanContext]

# File lib/opencensus/trace/span_context.rb, line 58
def create_root trace_context: nil, same_process_as_parent: nil
  if trace_context
    trace_data = TraceData.new trace_context.trace_id, {}
    new trace_data, nil, trace_context.span_id,
        trace_context.trace_options, same_process_as_parent
  else
    trace_id = rand 1..MAX_TRACE_ID
    trace_id = trace_id.to_s(16).rjust(32, "0")
    trace_data = TraceData.new trace_id, {}
    new trace_data, nil, "", 0, nil
  end
end
new(trace_data, parent, span_id, trace_options, same_process_as_parent) click to toggle source

Initialize a SpanContext object. This low-level constructor is used internally only. Generally, you should create a SpanContext using the `SpanContext.create_root` method.

@private

# File lib/opencensus/trace/span_context.rb, line 290
def initialize trace_data, parent, span_id, trace_options,
               same_process_as_parent
  @trace_data = trace_data
  @parent = parent
  @span_id = span_id
  @trace_options = trace_options
  @same_process_as_parent = same_process_as_parent
end

Public Instance Methods

build_contained_spans(max_attributes: nil, max_stack_frames: nil, max_annotations: nil, max_message_events: nil, max_links: nil, max_string_length: nil) click to toggle source

Builds spans under this context, and returns an array of built `Span` objects. Builds only spans that are both finished and sampled, and ignores others. The order of the generated spans is undefined.

Does not build any ancestor spans. If you want the entire span tree built, call this method on the `#root` context.

@param [Integer, nil] max_attributes The maximum number of attributes

to save, or `nil` to use the config value.

@param [Integer, nil] max_stack_frames The maximum number of stack

frames to save, or `nil` to use the config value.

@param [Integer, nil] max_annotations The maximum number of annotations

to save, or `nil` to use the config value.

@param [Integer, nil] max_message_events The maximum number of message

events to save, or `nil` to use the config value.

@param [Integer, nil] max_links The maximum number of links to save,

or `nil` to use the config value.

@param [Integer, nil] max_string_length The maximum length in bytes for

truncated strings, or `nil` to use the config value.

@return [Array<Span>] Built Span objects

# File lib/opencensus/trace/span_context.rb, line 264
def build_contained_spans max_attributes: nil,
                          max_stack_frames: nil,
                          max_annotations: nil,
                          max_message_events: nil,
                          max_links: nil,
                          max_string_length: nil
  sampled_span_builders = contained_span_builders.find_all do |sb|
    sb.finished? && sb.sampled?
  end
  sampled_span_builders.map do |sb|
    sb.to_span max_attributes: max_attributes,
               max_stack_frames: max_stack_frames,
               max_annotations: max_annotations,
               max_message_events: max_message_events,
               max_links: max_links,
               max_string_length: max_string_length
  end
end
contained_span_builders() click to toggle source

Returns all SpanBuilder objects created by this context or any descendant context. The order of the returned spans is undefined.

@private @return [Array<SpanBuilder>]

# File lib/opencensus/trace/span_context.rb, line 321
def contained_span_builders
  builders = @trace_data.span_map.values
  if root?
    builders
  else
    builders.find_all { |sb| contains? sb.context.parent }
  end
end
contains?(context) click to toggle source

Returns true if this context equals or is an ancestor of the given context.

@private @return [boolean]

# File lib/opencensus/trace/span_context.rb, line 306
def contains? context
  until context.nil?
    return true if context == self
    context = context.parent
  end
  false
end
end_span(span) click to toggle source

Finish the given span, which must have been created by this span context.

@param [SpanBuilder] span The span to finish.

# File lib/opencensus/trace/span_context.rb, line 222
def end_span span
  unless span.context.parent == self
    raise "The given span was not created by this context"
  end
  span.finish!
end
in_span(name, kind: nil, skip_frames: 0, sampler: nil) { |span| ... } click to toggle source

Create a new span in this context. You must pass a name for the span. All other span attributes should be set using {OpenCensus::Trace::SpanBuilder} methods.

The span will be started automatically with the current timestamp. The SpanBuilder will then be passed to the block you provide. The span will be finished automatically at the end of the block.

@param [String] name Name of the span. Required. @param [Symbol] kind Kind of span. Optional. Defaults to unspecified.

Other allowed values are {OpenCensus::Trace::SpanBuilder::SERVER}
and {OpenCensus::Trace::SpanBuilder::CLIENT}.

@param [Sampler,Boolean,nil] sampler Span-scoped sampler. Optional.

If provided, the sampler may be a sampler object as defined in the
{OpenCensus::Trace::Samplers} module docs, or the values `true` or
`false` as shortcuts for {OpenCensus::Trace::Samplers::AlwaysSample}
or {OpenCensus::Trace::Samplers::NeverSample}, respectively. If no
span-scoped sampler is provided, the local parent span's sampling
decision is used. If there is no local parent span, the configured
default sampler is used to make a sampling decision.
# File lib/opencensus/trace/span_context.rb, line 206
def in_span name, kind: nil, skip_frames: 0, sampler: nil
  span = start_span name, kind: kind, skip_frames: skip_frames + 1,
                          sampler: sampler
  begin
    yield span
  ensure
    end_span span
  end
end
root() click to toggle source

The root context, which may be this context or one of its ancestors.

@return [SpanContext]

# File lib/opencensus/trace/span_context.rb, line 93
def root
  root = self
  until (parent = root.parent).nil?
    root = parent
  end
  root
end
root?() click to toggle source

Returns true if this is a root span context

@return [boolean]

# File lib/opencensus/trace/span_context.rb, line 84
def root?
  parent.nil?
end
sampled?() click to toggle source

Whether this context (e.g. the parent span) has been sampled. This information may be used in sampling decisions for new spans.

@return [boolean]

# File lib/opencensus/trace/span_context.rb, line 148
def sampled?
  trace_options & 0x01 != 0
end
start_span(name, kind: nil, skip_frames: 0, sampler: nil) click to toggle source

Create a new span in this context. You must pass a name for the span. All other span attributes should be set using {OpenCensus::Trace::SpanBuilder} methods. The span will be started automatically with the current timestamp. However, you are responsible for finishing the span yourself.

@param [String] name Name of the span. Required. @param [Symbol] kind Kind of span. Optional. Defaults to unspecified.

Other allowed values are {OpenCensus::Trace::SpanBuilder::SERVER}
and {OpenCensus::Trace::SpanBuilder::CLIENT}.

@param [Sampler,Boolean,nil] sampler Span-scoped sampler. Optional.

If provided, the sampler may be a sampler object as defined in the
{OpenCensus::Trace::Samplers} module docs, or the values `true` or
`false` as shortcuts for {OpenCensus::Trace::Samplers::AlwaysSample}
or {OpenCensus::Trace::Samplers::NeverSample}, respectively. If no
span-scoped sampler is provided, the local parent span's sampling
decision is used. If there is no local parent span, the configured
default sampler is used to make a sampling decision.

@return [SpanBuilder] A SpanBuilder object that you can use to

set span attributes and create children.
# File lib/opencensus/trace/span_context.rb, line 175
def start_span name, kind: nil, skip_frames: 0, sampler: nil
  child_context = create_child sampler
  span = SpanBuilder.new child_context, skip_frames: skip_frames + 1
  span.name = name
  span.kind = kind if kind
  span.start!
  @trace_data.span_map[child_context.span_id] = span
end
this_span() click to toggle source

Returns the span that defines this context; that is, the span that is the parent of spans created by this context. Returns `nil` if this context is the root and doesn't correspond to an actual span, or if the corresponding span is remote.

@return [SpanBuilder, nil] The span defining this context.

# File lib/opencensus/trace/span_context.rb, line 237
def this_span
  get_span @span_id
end
trace_context() click to toggle source

Returns the trace context for this span.

@return [TraceContextData]

# File lib/opencensus/trace/span_context.rb, line 106
def trace_context
  TraceContextData.new trace_id, @span_id, trace_options
end
trace_id() click to toggle source

The trace ID, as a 32-character hex string.

@return [String]

# File lib/opencensus/trace/span_context.rb, line 115
def trace_id
  @trace_data.trace_id
end

Private Instance Methods

create_child(sampler) click to toggle source

Create a child of this SpanContext, with a random unique span ID.

@param [Sampler,Boolean,nil] sampler Span-scoped sampler. @return [SpanContext] The created child context.

# File lib/opencensus/trace/span_context.rb, line 338
def create_child sampler
  sampling_decision = make_sampling_decision sampler
  child_trace_options = sampling_decision ? 1 : 0
  loop do
    child_span_id = rand 1..MAX_SPAN_ID
    child_span_id = child_span_id.to_s(16).rjust(16, "0")
    unless @trace_data.span_map.key? child_span_id
      return SpanContext.new @trace_data, self, child_span_id,
                             child_trace_options, true
    end
  end
end
get_span(span_id) click to toggle source

Get the SpanBuilder given a Span ID.

@param [Integer] span_id the ID of the span to get @return [SpanBuilder, nil] The SpanBuilder, or `nil` if ID not found

# File lib/opencensus/trace/span_context.rb, line 384
def get_span span_id
  @trace_data.span_map[span_id]
end
make_sampling_decision(sampler) click to toggle source

Make a sampling decision in the current context given a span sampler. Implements the logic specified at: github.com/census-instrumentation/opencensus-specs/blob/master/trace/Sampling.md

@param [Sampler,Boolean,nil] sampler Span-scoped sampler. @return [Boolean]

# File lib/opencensus/trace/span_context.rb, line 359
def make_sampling_decision sampler
  resolved_sampler =
    case sampler
    when true
      OpenCensus::Trace::Samplers::AlwaysSample.new
    when false
      OpenCensus::Trace::Samplers::NeverSample.new
    when nil
      root? ? OpenCensus::Trace.config.default_sampler : nil
    else
      sampler
    end
  if resolved_sampler
    resolved_sampler.call(span_context: self)
  else
    sampled?
  end
end