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.

[View source]

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

[View source]

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

def [](key)
  params[key]
end

#[]=(key, value) ⇒ Object

[View source]

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

[View source]

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

[View source]

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:

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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