Class: NewRelic::Agent::Transaction::TraceNode

Inherits:
Object
  • Object
show all
Defined in:
lib/new_relic/agent/transaction/trace_node.rb

Constant Summary collapse

UNKNOWN_NODE_NAME =
'<unknown>'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(metric_name, relative_start, relative_end = nil, params = nil, parent = nil) ⇒ TraceNode

Returns a new instance of TraceNode.



20
21
22
23
24
25
26
27
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 20

def initialize(metric_name, relative_start, relative_end = nil, params = nil, parent = nil)
  @entry_timestamp = relative_start
  @metric_name = metric_name || UNKNOWN_NODE_NAME
  @exit_timestamp = relative_end
  @children = nil
  @params = select_allowed_params(params)
  @parent_node = parent
end

Instance Attribute Details

#childrenObject



90
91
92
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 90

def children
  @children ||= []
end

#entry_timestampObject (readonly)



9
10
11
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 9

def 
  @entry_timestamp
end

#exit_timestampObject

The exit timestamp will be relative except for the outermost sample which will have a timestamp.



12
13
14
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 12

def exit_timestamp
  @exit_timestamp
end

#metric_nameObject



16
17
18
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 16

def metric_name
  @metric_name
end

#paramsObject



118
119
120
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 118

def params
  @params ||= {}
end

#parent_nodeObject



14
15
16
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 14

def parent_node
  @parent_node
end

Instance Method Details

#[](key) ⇒ Object



130
131
132
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 130

def [](key)
  params[key]
end

#[]=(key, value) ⇒ Object



124
125
126
127
128
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 124

def []=(key, value)
  # only create a parameters field if a parameter is set; this will save
  # bandwidth etc as most nodes have no parameters
  params[key] = value
end

#count_nodesObject



112
113
114
115
116
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 112

def count_nodes
  count = 1
  children.each { |node| count += node.count_nodes }
  count
end

#durationObject

return the total duration of this node



97
98
99
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 97

def duration
  (@exit_timestamp - @entry_timestamp).to_f
end

#each_node {|_self| ... } ⇒ Object

call the provided block for this node and each of the called nodes

Yields:

  • (_self)

Yield Parameters:



136
137
138
139
140
141
142
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 136

def each_node(&block)
  yield(self)

  @children&.each do |node|
    node.each_node(&block)
  end
end

#each_node_with_nest_tracking(&block) ⇒ Object

call the provided block for this node and each of the called nodes while keeping track of nested nodes



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 146

def each_node_with_nest_tracking(&block)
  summary = yield(self)
  summary.current_nest_count += 1 if summary

  # no then branch coverage
  # rubocop:disable Style/SafeNavigation
  if @children
    @children.each do |node|
      node.each_node_with_nest_tracking(&block)
    end
  end
  # rubocop:enable Style/SafeNavigation

  summary.current_nest_count -= 1 if summary
end

#end_trace(timestamp) ⇒ Object

sets the final timestamp on a node to indicate the exit point of the node



39
40
41
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 39

def end_trace(timestamp)
  @exit_timestamp = timestamp
end

#exclusive_durationObject

return the duration of this node without including the time in the called nodes



103
104
105
106
107
108
109
110
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 103

def exclusive_duration
  d = duration

  children.each do |node|
    d -= node.duration
  end
  d
end

#explain_sqlObject



162
163
164
165
166
167
168
169
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 162

def explain_sql
  return params[:explain_plan] if params.key?(:explain_plan)

  statement = params[:sql]
  return nil unless statement.is_a?(Database::Statement)

  NewRelic::Agent::Database.explain_sql(statement)
end

#obfuscated_sqlObject



171
172
173
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 171

def obfuscated_sql
  NewRelic::Agent::Database.obfuscate_sql(params[:sql].sql)
end

#path_stringObject



56
57
58
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 56

def path_string
  "#{metric_name}[#{children.collect { |node| node.path_string }.join('')}]"
end

#select_allowed_params(params) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 29

def select_allowed_params(params)
  return unless params

  params.select do |p|
    NewRelic::Agent.instance.attribute_filter.allows_key?(p, AttributeFilter::DST_TRANSACTION_SEGMENTS)
  end
end

#to_arrayObject



47
48
49
50
51
52
53
54
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 47

def to_array
  params = @params || NewRelic::EMPTY_HASH
  [NewRelic::Helper.time_to_millis(@entry_timestamp),
    NewRelic::Helper.time_to_millis(@exit_timestamp),
    NewRelic::Coerce.string(@metric_name),
    params] +
    [(@children ? @children.map { |s| s.to_array } : NewRelic::EMPTY_ARRAY)]
end

#to_debug_str(depth) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 69

def to_debug_str(depth)
  tab = (+'  ') * depth
  s = tab.clone
  s << ">> #{'%3i ms' % (@entry_timestamp * 1000)} [#{self.class.name.split('::').last}] #{metric_name} \n"
  unless params.empty?
    params.each do |k, v|
      s << "#{tab}    -#{'%-16s' % k}: #{v.to_s[0..80]}\n"
    end
  end
  children.each do |cs|
    s << cs.to_debug_str(depth + 1)
  end
  s << tab + '<< '
  s << case @exit_timestamp
  when nil then ' n/a'
  when Numeric then '%3i ms' % (@exit_timestamp * 1000)
  else @exit_timestamp.to_s
  end
  s << " #{metric_name}\n"
end

#to_sObject



43
44
45
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 43

def to_s
  to_debug_str(0)
end

#to_s_compactObject



60
61
62
63
64
65
66
67
# File 'lib/new_relic/agent/transaction/trace_node.rb', line 60

def to_s_compact
  str = +''
  str << metric_name
  if children.any?
    str << "{#{children.map { |cs| cs.to_s_compact }.join(',')}}"
  end
  str
end