Class: NewRelic::Agent::Threading::ThreadProfile

Inherits:
Object
  • Object
show all
Includes:
Coerce
Defined in:
lib/new_relic/agent/threading/thread_profile.rb

Constant Summary collapse

THREAD_PROFILER_NODES =
20_000

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Coerce

#float, #int, #int_or_nil, #log_failure, #string

Constructor Details

#initialize(command_arguments = {}) ⇒ ThreadProfile

Returns a new instance of ThreadProfile.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 22

def initialize(command_arguments={})
  @command_arguments  = command_arguments
  @profile_id         = command_arguments.fetch('profile_id', -1)
  @duration           = command_arguments.fetch('duration', 120)
  @sample_period      = command_arguments.fetch('sample_period', 0.1)
  @profile_agent_code = command_arguments.fetch('profile_agent_code', false)
  @xray_id            = command_arguments.fetch('x_ray_id', nil)
  @finished = false

  @traces = {
    :agent      => BacktraceNode.new(nil),
    :background => BacktraceNode.new(nil),
    :other      => BacktraceNode.new(nil),
    :request    => BacktraceNode.new(nil)
  }

  @poll_count = 0
  @backtrace_count = 0
  @failure_count = 0
  @unique_threads = []

  @created_at = Time.now
end

Instance Attribute Details

#backtrace_countObject (readonly)

Returns the value of attribute backtrace_count.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def backtrace_count
  @backtrace_count
end

#command_argumentsObject (readonly)

Returns the value of attribute command_arguments.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def command_arguments
  @command_arguments
end

#created_atObject (readonly)

Returns the value of attribute created_at.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def created_at
  @created_at
end

#durationObject (readonly)

Returns the value of attribute duration.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def duration
  @duration
end

#failure_countObject (readonly)

Returns the value of attribute failure_count.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def failure_count
  @failure_count
end

#finished_atObject

Returns the value of attribute finished_at.



20
21
22
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 20

def finished_at
  @finished_at
end

#poll_countObject (readonly)

Returns the value of attribute poll_count.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def poll_count
  @poll_count
end

#profile_agent_codeObject (readonly)

Returns the value of attribute profile_agent_code.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def profile_agent_code
  @profile_agent_code
end

#profile_idObject (readonly)

Returns the value of attribute profile_id.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def profile_id
  @profile_id
end

#sample_periodObject (readonly)

Returns the value of attribute sample_period.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def sample_period
  @sample_period
end

#tracesObject (readonly)

Returns the value of attribute traces.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def traces
  @traces
end

#xray_idObject (readonly)

Returns the value of attribute xray_id.



17
18
19
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 17

def xray_id
  @xray_id
end

Instance Method Details

#aggregate(backtrace, bucket, thread) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 71

def aggregate(backtrace, bucket, thread)
  if backtrace.nil?
    @failure_count += 1
  else
    @backtrace_count += 1
    @traces[bucket].aggregate(backtrace)
    @unique_threads << thread unless @unique_threads.include?(thread)
  end
end

#empty?Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 62

def empty?
  @backtrace_count == 0
end

#generate_tracesObject



96
97
98
99
100
101
102
103
104
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 96

def generate_traces
  truncate_to_node_count!(THREAD_PROFILER_NODES)
  {
    "OTHER" => @traces[:other].to_array,
    "REQUEST" => @traces[:request].to_array,
    "AGENT" => @traces[:agent].to_array,
    "BACKGROUND" => @traces[:background].to_array
  }
end

#increment_poll_countObject



50
51
52
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 50

def increment_poll_count
  @poll_count += 1
end

#requested_periodObject



46
47
48
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 46

def requested_period
  @sample_period
end

#sample_countObject



54
55
56
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 54

def sample_count
  xray? ? @backtrace_count : @poll_count
end

#to_collector_array(encoder) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 106

def to_collector_array(encoder)
  result = [
    int(self.profile_id),
    float(self.created_at),
    float(self.finished_at),
    int(self.sample_count),
    string(encoder.encode(generate_traces)),
    int(self.unique_thread_count),
    0 # runnable thread count, which we don't track
  ]
  result << int(@xray_id) if xray?
  result
end

#to_log_descriptionObject



120
121
122
123
124
125
126
127
128
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 120

def to_log_description
  id = if xray?
         "@xray_id: #{xray_id}"
       else
         "@profile_id: #{profile_id}"
       end

  "#<ThreadProfile:#{object_id} #{id} @command_arguments=#{@command_arguments.inspect}>"
end

#truncate_to_node_count!(count_to_keep) ⇒ Object



81
82
83
84
85
86
87
88
89
90
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 81

def truncate_to_node_count!(count_to_keep)
  all_nodes = @traces.values.map { |n| n.flatten }.flatten

  NewRelic::Agent.instance.stats_engine.
    record_supportability_metric_count("ThreadProfiler/NodeCount", all_nodes.size)

  all_nodes.sort!
  nodes_to_prune = Set.new(all_nodes[count_to_keep..-1] || [])
  traces.values.each { |root| root.prune!(nodes_to_prune) }
end

#unique_thread_countObject



66
67
68
69
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 66

def unique_thread_count
  return 0 if @unique_threads.nil?
  @unique_threads.length
end

#xray?Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/new_relic/agent/threading/thread_profile.rb', line 58

def xray?
  !!@xray_id
end