Class: Datadog::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/ddtrace/context.rb

Overview

Context is used to keep track of a hierarchy of spans for the current execution flow. During each logical execution, the same Context is used to represent a single logical trace, even if the trace is built asynchronously.

A single code execution may use multiple Context if part of the execution must not be related to the current tracing. As example, a delayed job may compose a standalone trace instead of being related to the same trace that generates the job itself. On the other hand, if it’s part of the same Context, it will be related to the original trace.

This data structure is thread-safe.

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Context

Initialize a new thread-safe Context.



18
19
20
21
# File 'lib/ddtrace/context.rb', line 18

def initialize(options = {})
  @mutex = Mutex.new
  reset(options)
end

Instance Method Details

#add_span(span) ⇒ Object

Add a span to the context trace list, keeping it as the last active span.



79
80
81
82
83
84
85
# File 'lib/ddtrace/context.rb', line 79

def add_span(span)
  @mutex.synchronize do
    set_current_span(span)
    @trace << span
    span.context = self
  end
end

#close_span(span) ⇒ Object

Mark a span as a finished, increasing the internal counter to prevent cycles inside _trace list.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/ddtrace/context.rb', line 89

def close_span(span)
  @mutex.synchronize do
    @finished_spans += 1
    # Current span is only meaningful for linear tree-like traces,
    # in other cases, this is just broken and one should rely
    # on per-instrumentation code to retrieve handle parent/child relations.
    set_current_span(span.parent)
    return if span.tracer.nil?
    return unless Datadog::Tracer.debug_logging
    if span.parent.nil? && !check_finished_spans
      opened_spans = @trace.length - @finished_spans
      Datadog::Tracer.log.debug("root span #{span.name} closed but has #{opened_spans} unfinished spans:")
      @trace.each do |s|
        Datadog::Tracer.log.debug("unfinished span: #{s}") unless s.finished?
      end
    end
  end
end

#current_spanObject

Return the last active span that corresponds to the last inserted item in the trace list. This cannot be considered as the current active span in asynchronous environments, because some spans can be closed earlier while child spans still need to finish their traced execution.



61
62
63
64
65
# File 'lib/ddtrace/context.rb', line 61

def current_span
  @mutex.synchronize do
    return @current_span
  end
end

#finished?Boolean

Returns if the trace for the current Context is finished or not. A Context is considered finished if all spans in this context are finished.

Returns:

  • (Boolean)


116
117
118
119
120
# File 'lib/ddtrace/context.rb', line 116

def finished?
  @mutex.synchronize do
    return check_finished_spans
  end
end

#getObject

Returns both the trace list generated in the current context and if the context is sampled or not. It returns nil, nil if the “Context“ is not finished. If a trace is returned, the Context will be reset so that it can be re-used immediately.

This operation is thread-safe.



136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/ddtrace/context.rb', line 136

def get
  @mutex.synchronize do
    return nil, nil unless check_finished_spans

    trace = @trace
    sampled = @sampled
    attach_sampling_priority if sampled && @sampling_priority

    reset
    return trace, sampled
  end
end

#sampled?Boolean

Returns true if the context is sampled, that is, if it should be kept and sent to the trace agent.

Returns:

  • (Boolean)


124
125
126
127
128
# File 'lib/ddtrace/context.rb', line 124

def sampled?
  @mutex.synchronize do
    return @sampled
  end
end

#sampling_priorityObject



45
46
47
48
49
# File 'lib/ddtrace/context.rb', line 45

def sampling_priority
  @mutex.synchronize do
    @sampling_priority
  end
end

#sampling_priority=(priority) ⇒ Object



51
52
53
54
55
# File 'lib/ddtrace/context.rb', line 51

def sampling_priority=(priority)
  @mutex.synchronize do
    @sampling_priority = priority
  end
end

#span_idObject



39
40
41
42
43
# File 'lib/ddtrace/context.rb', line 39

def span_id
  @mutex.synchronize do
    @parent_span_id
  end
end

#to_sObject

Return a string representation of the context.



150
151
152
153
154
155
# File 'lib/ddtrace/context.rb', line 150

def to_s
  @mutex.synchronize do
    # rubocop:disable Metrics/LineLength
    "Context(trace.length:#{@trace.length},sampled:#{@sampled},finished_spans:#{@finished_spans},current_span:#{@current_span})"
  end
end

#trace_idObject



33
34
35
36
37
# File 'lib/ddtrace/context.rb', line 33

def trace_id
  @mutex.synchronize do
    @parent_trace_id
  end
end