Module: Datadog::Profiling::Component
- Defined in:
- lib/datadog/profiling/component.rb
Overview
Responsible for wiring up the Profiler for execution
Class Method Summary collapse
-
.build_profiler_component(settings:, agent_settings:, optional_tracer:) ⇒ Object
Passing in a ‘nil` tracer is supported and will disable the following profiling features: * Code Hotspots panel in the trace viewer, as well as scoping a profile down to a span * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call).
Class Method Details
.build_profiler_component(settings:, agent_settings:, optional_tracer:) ⇒ Object
Passing in a ‘nil` tracer is supported and will disable the following profiling features:
-
Code Hotspots panel in the trace viewer, as well as scoping a profile down to a span
-
Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
10 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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 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 81 82 83 84 85 |
# File 'lib/datadog/profiling/component.rb', line 10 def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) # rubocop:disable Metrics/MethodLength return [nil, {profiling_enabled: false}] unless settings.profiling.enabled # Workaround for weird dependency direction: the Core::Configuration::Components class currently has a # dependency on individual products, in this case the Profiler. # (Note "currently": in the future we want to change this so core classes don't depend on specific products) # # If the current file included a `require 'datadog/profiler'` at its beginning, we would generate circular # requires when used from profiling: # # datadog/profiling # └─requires─> datadog/core # └─requires─> datadog/core/configuration/components # └─requires─> datadog/profiling # Loop! # # ...thus in #1998 we removed such a require. # # On the other hand, if datadog/core is loaded by a different product and no general `require 'datadog'` is # done, then profiling may not be loaded, and thus to avoid this issue we do a require here (which is a # no-op if profiling is already loaded). require_relative "../profiling" return [nil, {profiling_enabled: false}] unless Profiling.supported? # Activate forking extensions Profiling::Tasks::Setup.new.run # NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method no_signals_workaround_enabled = no_signals_workaround_enabled?(settings) timeline_enabled = settings.profiling.advanced.timeline_enabled allocation_profiling_enabled = enable_allocation_profiling?(settings) heap_sample_every = get_heap_sample_every(settings) heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every) heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled) overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage) upload_period_seconds = [60, settings.profiling.advanced.upload_period_seconds].max recorder = Datadog::Profiling::StackRecorder.new( cpu_time_enabled: RUBY_PLATFORM.include?("linux"), # Only supported on Linux currently alloc_samples_enabled: allocation_profiling_enabled, heap_samples_enabled: heap_profiling_enabled, heap_size_enabled: heap_size_profiling_enabled, heap_sample_every: heap_sample_every, timeline_enabled: timeline_enabled, heap_clean_after_gc_enabled: settings.profiling.advanced.heap_clean_after_gc_enabled, ) thread_context_collector = build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled) worker = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new( gc_profiling_enabled: enable_gc_profiling?(settings), no_signals_workaround_enabled: no_signals_workaround_enabled, thread_context_collector: thread_context_collector, dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage, allocation_profiling_enabled: allocation_profiling_enabled, allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled, gvl_profiling_enabled: enable_gvl_profiling?(settings), ) = { no_signals_workaround_enabled: no_signals_workaround_enabled, timeline_enabled: timeline_enabled, heap_sample_every: heap_sample_every, }.freeze exporter = build_profiler_exporter(settings, recorder, worker, internal_metadata: ) transport = build_profiler_transport(settings, agent_settings) scheduler = Profiling::Scheduler.new(exporter: exporter, transport: transport, interval: upload_period_seconds) profiler = Profiling::Profiler.new(worker: worker, scheduler: scheduler) if dir_interruption_workaround_enabled?(settings, no_signals_workaround_enabled) Datadog::Profiling::Ext::DirMonkeyPatches.apply! end [profiler, {profiling_enabled: true}] end |