Module: Datadog::OpenTelemetry::API::Context

Defined in:
lib/datadog/opentelemetry/api/context.rb

Overview

The OpenTelemetry Context contains a key-value store that can be attached to a trace.

It loosely matches our ‘TraceOperations#tags`, except for the following:

  • Context can store arbitrary objects as values. One example is for the key ‘Context::Key.new(’current-span’)‘, which is associated with a `Span` object. In contrast, `TraceOperations#tags` only stores string values.

  • Context is how spans know who their parent span is. The parenting operation happens on every span created. Parenting is not directly tied to the active Fiber or Thread.

  • Context is immutable: changing a value creates a copy of Context.

  • Context is not bound to a specific trace: it can be reused an arbitrary number of times.

Defined Under Namespace

Modules: SingletonClass

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.prepended(base) ⇒ Object



165
166
167
# File 'lib/datadog/opentelemetry/api/context.rb', line 165

def self.prepended(base)
  base.singleton_class.prepend(SingletonClass)
end

Instance Method Details

#ensure_traceObject

Because Context can be reused, we have to make sure we have a valid ‘TraceOperation` on every invocation.



33
34
35
36
37
38
39
# File 'lib/datadog/opentelemetry/api/context.rb', line 33

def ensure_trace
  return nil unless @trace

  # The Context can be reused after the root span has finished.
  @trace.send(:reset) if @trace.finished?
  @trace
end

#initialize(entries, trace: nil) ⇒ Object



25
26
27
28
29
# File 'lib/datadog/opentelemetry/api/context.rb', line 25

def initialize(entries, trace: nil)
  @trace = trace || ::Datadog::Tracing.send(:tracer).send(:start_trace)
  @trace.otel_values.merge!(entries) if entries
  @trace.otel_context ||= self
end

#set_value(key, value) ⇒ Context

Returns a new Context where entries contains the newly added key and value

Parameters:

  • key (Key)

    The key to store this value under

  • value (Object)

    Object to be stored under key

Returns:



58
59
60
# File 'lib/datadog/opentelemetry/api/context.rb', line 58

def set_value(key, value)
  set_values(key => value)
end

#set_values(values) ⇒ Context

Returns a new Context with the current context’s entries merged with the

new entries

Parameters:

  • values (Hash)

    The values to be merged with the current context’s entries.

  • value (Object)

    Object to be stored under key

Returns:



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/datadog/opentelemetry/api/context.rb', line 69

def set_values(values)
  if (current_span = values[CURRENT_SPAN_KEY]) && current_span.datadog_trace
    # Because `#set_value` returns new context, we have to create
    # a new copy of the active trace to ensure there's no conflict with
    # other users of the active trace.
    # It effectively becomes an internal trace propagation.
    trace = Datadog::OpenTelemetry::Trace.start_trace_copy(
      current_span.datadog_trace,
      parent_span: current_span.datadog_span
    )
  end

  existing_values = @trace && @trace.otel_values || {}

  ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace)
end

#traceObject

The Datadog TraceOperation associated with this Datadog::OpenTelemetry::API::Context.



87
88
89
# File 'lib/datadog/opentelemetry/api/context.rb', line 87

def trace
  @trace
end

#value(key) ⇒ Object Also known as: []

Returns the corresponding value (or nil) for key

Parameters:

  • key (Key)

    The lookup key

Returns:

  • (Object)


45
46
47
48
49
# File 'lib/datadog/opentelemetry/api/context.rb', line 45

def value(key)
  return nil unless @trace

  @trace.otel_value(key)
end