class NewRelic::Agent::Threading::ThreadProfile

Constants

THREAD_PROFILER_NODES

Attributes

backtrace_count[R]
command_arguments[R]
created_at[R]
duration[R]
failure_count[R]
finished_at[RW]
poll_count[R]
profile_agent_code[R]
profile_id[R]
sample_period[R]
traces[R]
xray_id[R]

Public Class Methods

new(command_arguments={}) click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 21
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      => BacktraceRoot.new,
    :background => BacktraceRoot.new,
    :other      => BacktraceRoot.new,
    :request    => BacktraceRoot.new
  }

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

  @created_at = Time.now
end

Public Instance Methods

aggregate(backtrace, bucket, thread) click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 70
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
convert_N_trace_nodes_to_arrays(count_to_keep) click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 80
def convert_N_trace_nodes_to_arrays(count_to_keep) #THREAD_LOCAL_ACCESS
  all_nodes = @traces.values.map { |n| n.flattened }.flatten

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

  all_nodes.sort! do |a, b|
    # we primarily prefer higher runnable_count
    comparison = b.runnable_count <=> a.runnable_count
    # we secondarily prefer lower depth
    comparison = a.depth          <=> b.depth if comparison == 0
    # it is thus impossible for any child to preceed their parent
    comparison
  end

  all_nodes.each_with_index do |n, i|
    break if i >= count_to_keep
    n.mark_for_array_conversion
  end
  all_nodes.each_with_index do |n, i|
    break if i >= count_to_keep
    n.complete_array_conversion
  end
end
empty?() click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 61
def empty?
  @backtrace_count == 0
end
generate_traces() click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 109
def generate_traces
  convert_N_trace_nodes_to_arrays(THREAD_PROFILER_NODES)

  {
    "OTHER"      => @traces[:other     ].as_array,
    "REQUEST"    => @traces[:request   ].as_array,
    "AGENT"      => @traces[:agent     ].as_array,
    "BACKGROUND" => @traces[:background].as_array
  }
end
increment_poll_count() click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 49
def increment_poll_count
  @poll_count += 1
end
requested_period() click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 45
def requested_period
  @sample_period
end
sample_count() click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 53
def sample_count
  xray? ? @backtrace_count : @poll_count
end
to_collector_array(encoder) click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 120
def to_collector_array(encoder)
  encoded_trace_tree = encoder.encode(generate_traces, :skip_normalization => true)
  result = [
    int(self.profile_id),
    float(self.created_at),
    float(self.finished_at),
    int(self.sample_count),
    encoded_trace_tree,
    int(self.unique_thread_count),
    0 # runnable thread count, which we don't track
  ]
  result << int(@xray_id) if xray?
  result
end
to_log_description() click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 135
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
unique_thread_count() click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 65
def unique_thread_count
  return 0 if @unique_threads.nil?
  @unique_threads.length
end
xray?() click to toggle source
# File lib/new_relic/agent/threading/thread_profile.rb, line 57
def xray?
  !!@xray_id
end