Class: Datadog::Profiling::Collectors::CpuAndWallTimeWorker

Inherits:
Object
  • Object
show all
Defined in:
lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb,
ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c

Overview

Used to trigger the periodic execution of Collectors::ThreadState, which implements all of the sampling logic itself; this class only implements the “when to do it” part. Almost all of this class is implemented as native code.

Methods prefixed with native are implemented in ‘collectors_cpu_and_wall_time_worker.c`

Defined Under Namespace

Modules: Testing

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(recorder:, max_frames:, tracer:, endpoint_collection_enabled:, gc_profiling_enabled:, allocation_counting_enabled:, thread_context_collector: ThreadContext.new( recorder: recorder, max_frames: max_frames, tracer: tracer, endpoint_collection_enabled: endpoint_collection_enabled, ), idle_sampling_helper: IdleSamplingHelper.new, dynamic_sampling_rate_enabled: true) ⇒ CpuAndWallTimeWorker

Returns a new instance of CpuAndWallTimeWorker.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb', line 16

def initialize(
  recorder:,
  max_frames:,
  tracer:,
  endpoint_collection_enabled:,
  gc_profiling_enabled:,
  allocation_counting_enabled:,
  thread_context_collector: ThreadContext.new(
    recorder: recorder,
    max_frames: max_frames,
    tracer: tracer,
    endpoint_collection_enabled: endpoint_collection_enabled,
  ),
  idle_sampling_helper: IdleSamplingHelper.new,
  # **NOTE**: This should only be used for testing; disabling the dynamic sampling rate will increase the
  # profiler overhead!
  dynamic_sampling_rate_enabled: true
)
  unless dynamic_sampling_rate_enabled
    Datadog.logger.warn(
      'Profiling dynamic sampling rate disabled. This should only be used for testing, and will increase overhead!'
    )
  end

  self.class._native_initialize(
    self,
    thread_context_collector,
    gc_profiling_enabled,
    idle_sampling_helper,
    allocation_counting_enabled,
    dynamic_sampling_rate_enabled,
  )
  @worker_thread = nil
  @failure_exception = nil
  @start_stop_mutex = Mutex.new
  @idle_sampling_helper = idle_sampling_helper
end

Class Method Details

._native_allocation_countObject



170
# File 'ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c', line 170

static VALUE _native_allocation_count(DDTRACE_UNUSED VALUE self);

._native_initializeObject



131
132
133
134
135
136
137
138
139
# File 'ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c', line 131

static VALUE _native_initialize(
  DDTRACE_UNUSED VALUE _self,
  VALUE self_instance,
  VALUE thread_context_collector_instance,
  VALUE gc_profiling_enabled,
  VALUE idle_sampling_helper_instance,
  VALUE allocation_counting_enabled,
  VALUE dynamic_sampling_rate_enabled
);

._native_reset_after_forkObject



163
# File 'ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c', line 163

static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE instance);

._native_sampling_loopObject



141
# File 'ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c', line 141

static VALUE _native_sampling_loop(VALUE self, VALUE instance);

._native_statsObject



165
# File 'ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c', line 165

static VALUE _native_stats(DDTRACE_UNUSED VALUE self, VALUE instance);

._native_stopObject



142
# File 'ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c', line 142

static VALUE _native_stop(DDTRACE_UNUSED VALUE _self, VALUE self_instance, VALUE worker_thread);

Instance Method Details

#enabled=(_) ⇒ Object

TODO: Provided only for compatibility with the API for Collectors::OldStack used in the Profiler class. Can be removed once we remove OldStack.



84
# File 'lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb', line 84

def enabled=(_); end

#reset_after_forkObject



102
103
104
# File 'lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb', line 102

def reset_after_fork
  self.class._native_reset_after_fork(self)
end

#startObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb', line 54

def start
  @start_stop_mutex.synchronize do
    return if @worker_thread && @worker_thread.alive?

    Datadog.logger.debug { "Starting thread for: #{self}" }

    @idle_sampling_helper.start

    @worker_thread = Thread.new do
      begin
        Thread.current.name = self.class.name

        self.class._native_sampling_loop(self)

        Datadog.logger.debug('CpuAndWallTimeWorker thread stopping cleanly')
      rescue Exception => e # rubocop:disable Lint/RescueException
        @failure_exception = e
        Datadog.logger.warn(
          'CpuAndWallTimeWorker thread error. ' \
          "Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
        )
      end
    end
  end

  true
end

#statsObject



106
107
108
# File 'lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb', line 106

def stats
  self.class._native_stats(self)
end

#stop(*_) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb', line 86

def stop(*_)
  @start_stop_mutex.synchronize do
    Datadog.logger.debug('Requesting CpuAndWallTimeWorker thread shut down')

    @idle_sampling_helper.stop

    return unless @worker_thread

    self.class._native_stop(self, @worker_thread)

    @worker_thread.join
    @worker_thread = nil
    @failure_exception = nil
  end
end