Class: Datadog::Profiling::Pprof::StackSample
- Inherits:
-
Converter
- Object
- Converter
- Datadog::Profiling::Pprof::StackSample
show all
- Defined in:
- lib/datadog/profiling/pprof/stack_sample.rb
Overview
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.
Constant Summary
collapse
- SAMPLE_TYPES =
{
cpu_time_ns: [
Profiling::Ext::Pprof::VALUE_TYPE_CPU,
Profiling::Ext::Pprof::VALUE_UNIT_NANOSECONDS
],
wall_time_ns: [
Profiling::Ext::Pprof::VALUE_TYPE_WALL,
Profiling::Ext::Pprof::VALUE_UNIT_NANOSECONDS
]
}.freeze
Instance Attribute Summary
Attributes inherited from Converter
#builder
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Converter
#group_events, #sample_value_index
Constructor Details
29
30
31
32
33
34
35
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 29
def initialize(*_)
super
@most_recent_trace_samples = {}
@processed_unique_stacks = 0
@processed_with_trace = 0
end
|
Class Method Details
.sample_value_types ⇒ Object
25
26
27
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 25
def self.sample_value_types
SAMPLE_TYPES
end
|
Instance Method Details
#add_events!(stack_samples) ⇒ Object
37
38
39
40
|
# File 'lib/datadog/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_event_values(stack_sample) ⇒ Object
86
87
88
89
90
91
92
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 86
def build_event_values(stack_sample)
no_value = Profiling::Ext::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_sample(stack_sample, values) ⇒ Object
73
74
75
76
77
78
79
80
81
82
83
84
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 73
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) ⇒ Object
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 94
def build_sample_labels(stack_sample)
labels = [
Perftools::Profiles::Label.new(
key: builder.string_table.fetch(Profiling::Ext::Pprof::LABEL_KEY_THREAD_ID),
str: builder.string_table.fetch(stack_sample.thread_id.to_s)
)
]
root_span_id = stack_sample.root_span_id || 0
span_id = stack_sample.span_id || 0
if root_span_id != 0 && span_id != 0
@processed_with_trace += 1
labels << Perftools::Profiles::Label.new(
key: builder.string_table.fetch(Profiling::Ext::Pprof::LABEL_KEY_LOCAL_ROOT_SPAN_ID),
str: builder.string_table.fetch(root_span_id.to_s)
)
labels << Perftools::Profiles::Label.new(
key: builder.string_table.fetch(Profiling::Ext::Pprof::LABEL_KEY_SPAN_ID),
str: builder.string_table.fetch(span_id.to_s)
)
trace_resource = @most_recent_trace_samples.fetch(stack_sample.root_span_id, stack_sample).trace_resource
if trace_resource && !trace_resource.empty?
labels << Perftools::Profiles::Label.new(
key: builder.string_table.fetch(Profiling::Ext::Pprof::LABEL_KEY_TRACE_ENDPOINT),
str: builder.string_table.fetch(trace_resource)
)
end
end
labels
end
|
#build_samples(stack_samples) ⇒ Object
65
66
67
68
69
70
71
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 65
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 ⇒ Object
133
134
135
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 133
def debug_statistics
"unique stacks: #{@processed_unique_stacks}, of which had active traces: #{@processed_with_trace}"
end
|
#stack_sample_group_key(stack_sample) ⇒ Object
42
43
44
45
46
47
48
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 42
def stack_sample_group_key(stack_sample)
update_most_recent_trace_sample(stack_sample)
stack_sample.hash
end
|
#update_most_recent_trace_sample(stack_sample) ⇒ Object
Track the most recent sample for each trace (identified by root span id)
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# File 'lib/datadog/profiling/pprof/stack_sample.rb', line 51
def update_most_recent_trace_sample(stack_sample)
return unless stack_sample.root_span_id && stack_sample.trace_resource
if (most_recent_trace_sample = @most_recent_trace_samples[stack_sample.root_span_id])
if most_recent_trace_sample.timestamp < stack_sample.timestamp
@most_recent_trace_samples[stack_sample.root_span_id] = stack_sample
end
else
@most_recent_trace_samples[stack_sample.root_span_id] = stack_sample
end
end
|