Class: Datadog::Profiling::StackRecorder
- Inherits:
-
Object
- Object
- Datadog::Profiling::StackRecorder
- Defined in:
- lib/datadog/profiling/stack_recorder.rb,
ext/datadog_profiling_native_extension/stack_recorder.c
Overview
Stores stack samples in a native libdatadog data structure and expose Ruby-level serialization APIs Note that ‘record_sample` is only accessible from native code. Methods prefixed with native are implemented in `stack_recorder.c`
Defined Under Namespace
Modules: Testing
Class Method Summary collapse
- ._native_initialize ⇒ Object
- ._native_reset_after_fork ⇒ Object
- ._native_serialize ⇒ Object
- ._native_stats ⇒ Object
- .for_testing(cpu_time_enabled: true, alloc_samples_enabled: false, heap_samples_enabled: false, heap_size_enabled: false, heap_sample_every: 1, timeline_enabled: false, heap_clean_after_gc_enabled: true, **options) ⇒ Object
Instance Method Summary collapse
-
#initialize(cpu_time_enabled:, alloc_samples_enabled:, heap_samples_enabled:, heap_size_enabled:, heap_sample_every:, timeline_enabled:, heap_clean_after_gc_enabled:) ⇒ StackRecorder
constructor
A new instance of StackRecorder.
- #reset_after_fork ⇒ Object
- #serialize ⇒ Object
- #serialize! ⇒ Object
- #stats ⇒ Object
Constructor Details
#initialize(cpu_time_enabled:, alloc_samples_enabled:, heap_samples_enabled:, heap_size_enabled:, heap_sample_every:, timeline_enabled:, heap_clean_after_gc_enabled:) ⇒ StackRecorder
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/datadog/profiling/stack_recorder.rb', line 11 def initialize( cpu_time_enabled:, alloc_samples_enabled:, heap_samples_enabled:, heap_size_enabled:, heap_sample_every:, timeline_enabled:, heap_clean_after_gc_enabled: ) # This mutex works in addition to the fancy C-level mutexes we have in the native side (see the docs there). # It prevents multiple Ruby threads calling serialize at the same time -- something like # `10.times { Thread.new { stack_recorder.serialize } }`. # This isn't something we expect to happen normally, but because it would break the assumptions of the # C-level mutexes (that there is a single serializer thread), we add it here as an extra safeguard against it # accidentally happening. @no_concurrent_serialize_mutex = Mutex.new self.class._native_initialize( self_instance: self, cpu_time_enabled: cpu_time_enabled, alloc_samples_enabled: alloc_samples_enabled, heap_samples_enabled: heap_samples_enabled, heap_size_enabled: heap_size_enabled, heap_sample_every: heap_sample_every, timeline_enabled: timeline_enabled, heap_clean_after_gc_enabled: heap_clean_after_gc_enabled, ) end |
Class Method Details
._native_initialize ⇒ Object
247 |
# File 'ext/datadog_profiling_native_extension/stack_recorder.c', line 247 static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self); |
._native_reset_after_fork ⇒ Object
259 |
# File 'ext/datadog_profiling_native_extension/stack_recorder.c', line 259 static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_instance); |
._native_serialize ⇒ Object
248 |
# File 'ext/datadog_profiling_native_extension/stack_recorder.c', line 248 static VALUE _native_serialize(VALUE self, VALUE recorder_instance); |
._native_stats ⇒ Object
267 |
# File 'ext/datadog_profiling_native_extension/stack_recorder.c', line 267 static VALUE _native_stats(DDTRACE_UNUSED VALUE self, VALUE instance); |
.for_testing(cpu_time_enabled: true, alloc_samples_enabled: false, heap_samples_enabled: false, heap_size_enabled: false, heap_sample_every: 1, timeline_enabled: false, heap_clean_after_gc_enabled: true, **options) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/datadog/profiling/stack_recorder.rb', line 40 def self.for_testing( cpu_time_enabled: true, alloc_samples_enabled: false, heap_samples_enabled: false, heap_size_enabled: false, heap_sample_every: 1, timeline_enabled: false, heap_clean_after_gc_enabled: true, ** ) new( cpu_time_enabled: cpu_time_enabled, alloc_samples_enabled: alloc_samples_enabled, heap_samples_enabled: heap_samples_enabled, heap_size_enabled: heap_size_enabled, heap_sample_every: heap_sample_every, timeline_enabled: timeline_enabled, heap_clean_after_gc_enabled: heap_clean_after_gc_enabled, **, ) end |
Instance Method Details
#reset_after_fork ⇒ Object
95 96 97 |
# File 'lib/datadog/profiling/stack_recorder.rb', line 95 def reset_after_fork self.class._native_reset_after_fork(self) end |
#serialize ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/datadog/profiling/stack_recorder.rb', line 62 def serialize status, result = @no_concurrent_serialize_mutex.synchronize { self.class._native_serialize(self) } if status == :ok start, finish, encoded_profile, profile_stats = result Datadog.logger.debug { "Encoded profile covering #{start.iso8601} to #{finish.iso8601}" } [start, finish, encoded_profile, profile_stats] else = result Datadog.logger.warn("Failed to serialize profiling data: #{error_message}") Datadog::Core::Telemetry::Logger.error("Failed to serialize profiling data (#{error_message})") nil end end |
#serialize! ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/datadog/profiling/stack_recorder.rb', line 81 def serialize! status, result = @no_concurrent_serialize_mutex.synchronize { self.class._native_serialize(self) } if status == :ok _start, _finish, encoded_profile = result encoded_profile else = result raise("Failed to serialize profiling data: #{error_message}") end end |
#stats ⇒ Object
99 100 101 |
# File 'lib/datadog/profiling/stack_recorder.rb', line 99 def stats self.class._native_stats(self) end |