class Datadog::Profiling::Pprof::StackSample

Builds a profile from a StackSample

NOTE: This class may appear stateless but is in fact stateful; a new instance should be created for every encoded profile.

Constants

SAMPLE_TYPES

Public Class Methods

new(*_) click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 30
def initialize(*_)
  super

  @processed_unique_stacks = 0
  @processed_with_trace_ids = 0
end
sample_value_types() click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 26
def self.sample_value_types
  SAMPLE_TYPES
end

Public Instance Methods

add_events!(stack_samples) click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 37
def add_events!(stack_samples)
  new_samples = build_samples(stack_samples)
  builder.samples.concat(new_samples)
end
build_sample(stack_sample, values) click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 54
def build_sample(stack_sample, values)
  locations = builder.build_locations(
    stack_sample.frames,
    stack_sample.total_frame_count
  )

  Perftools::Profiles::Sample.new(
    location_id: locations.collect { |location| location['id'.freeze] },
    value: values,
    label: build_sample_labels(stack_sample)
  )
end
build_sample_labels(stack_sample) click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 75
def build_sample_labels(stack_sample)
  labels = [
    Perftools::Profiles::Label.new(
      key: builder.string_table.fetch(Datadog::Ext::Profiling::Pprof::LABEL_KEY_THREAD_ID),
      str: builder.string_table.fetch(stack_sample.thread_id.to_s)
    )
  ]

  trace_id = stack_sample.trace_id || 0
  span_id = stack_sample.span_id || 0

  if trace_id != 0 && span_id != 0
    @processed_with_trace_ids += 1

    labels << Perftools::Profiles::Label.new(
      key: builder.string_table.fetch(Datadog::Ext::Profiling::Pprof::LABEL_KEY_TRACE_ID),
      str: builder.string_table.fetch(trace_id.to_s)
    )

    labels << Perftools::Profiles::Label.new(
      key: builder.string_table.fetch(Datadog::Ext::Profiling::Pprof::LABEL_KEY_SPAN_ID),
      str: builder.string_table.fetch(span_id.to_s)
    )

    trace_resource = stack_sample.trace_resource_container && stack_sample.trace_resource_container.latest
    if trace_resource && !trace_resource.empty?
      labels << Perftools::Profiles::Label.new(
        key: builder.string_table.fetch(Datadog::Ext::Profiling::Pprof::LABEL_KEY_TRACE_ENDPOINT),
        str: builder.string_table.fetch(trace_resource)
      )
    end
  end

  labels
end
build_sample_values(stack_sample) click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 67
def build_sample_values(stack_sample)
  no_value = Datadog::Ext::Profiling::Pprof::SAMPLE_VALUE_NO_VALUE
  values = super(stack_sample)
  values[sample_value_index(:cpu_time_ns)] = stack_sample.cpu_time_interval_ns || no_value
  values[sample_value_index(:wall_time_ns)] = stack_sample.wall_time_interval_ns || no_value
  values
end
build_samples(stack_samples) click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 46
def build_samples(stack_samples)
  groups = group_events(stack_samples, &method(:stack_sample_group_key))
  groups.collect do |_group_key, group|
    @processed_unique_stacks += 1
    build_sample(group.sample, group.values)
  end
end
debug_statistics() click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 111
def debug_statistics
  "unique stacks: #{@processed_unique_stacks}, of which had active traces: #{@processed_with_trace_ids}"
end
stack_sample_group_key(stack_sample) click to toggle source
# File lib/ddtrace/profiling/pprof/stack_sample.rb, line 42
def stack_sample_group_key(stack_sample)
  stack_sample.hash
end