ddtrace 0.47.0 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +4 -2
  3. data/.circleci/images/primary/Dockerfile-2.0.0 +11 -1
  4. data/.circleci/images/primary/Dockerfile-2.1.10 +11 -1
  5. data/.circleci/images/primary/Dockerfile-2.2.10 +11 -1
  6. data/.circleci/images/primary/Dockerfile-2.3.8 +10 -0
  7. data/.circleci/images/primary/Dockerfile-2.4.6 +10 -0
  8. data/.circleci/images/primary/Dockerfile-2.5.6 +10 -0
  9. data/.circleci/images/primary/Dockerfile-2.6.4 +10 -0
  10. data/.circleci/images/primary/Dockerfile-2.7.0 +10 -0
  11. data/.circleci/images/primary/Dockerfile-jruby-9.2-latest +10 -0
  12. data/.gitlab-ci.yml +18 -18
  13. data/.rubocop.yml +19 -0
  14. data/.rubocop_todo.yml +44 -3
  15. data/Appraisals +55 -1
  16. data/CHANGELOG.md +47 -1
  17. data/Gemfile +10 -0
  18. data/Rakefile +9 -0
  19. data/bin/ddtracerb +15 -0
  20. data/ddtrace.gemspec +4 -2
  21. data/docs/GettingStarted.md +36 -53
  22. data/docs/ProfilingDevelopment.md +88 -0
  23. data/integration/README.md +1 -2
  24. data/integration/apps/rack/Dockerfile +3 -0
  25. data/integration/apps/rack/script/build-images +1 -1
  26. data/integration/apps/rack/script/ci +1 -1
  27. data/integration/apps/rails-five/script/build-images +1 -1
  28. data/integration/apps/rails-five/script/ci +1 -1
  29. data/integration/apps/ruby/script/build-images +1 -1
  30. data/integration/apps/ruby/script/ci +1 -1
  31. data/integration/images/include/http-health-check +1 -1
  32. data/integration/images/wrk/scripts/entrypoint.sh +1 -1
  33. data/integration/script/build-images +1 -1
  34. data/lib/ddtrace.rb +1 -0
  35. data/lib/ddtrace/configuration.rb +39 -13
  36. data/lib/ddtrace/configuration/components.rb +85 -3
  37. data/lib/ddtrace/configuration/settings.rb +31 -0
  38. data/lib/ddtrace/contrib/active_record/configuration/makara_resolver.rb +30 -0
  39. data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +9 -3
  40. data/lib/ddtrace/contrib/resque/configuration/settings.rb +17 -1
  41. data/lib/ddtrace/contrib/resque/patcher.rb +4 -4
  42. data/lib/ddtrace/contrib/resque/resque_job.rb +22 -1
  43. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +1 -0
  44. data/lib/ddtrace/contrib/shoryuken/tracer.rb +7 -3
  45. data/lib/ddtrace/diagnostics/environment_logger.rb +1 -1
  46. data/lib/ddtrace/error.rb +2 -0
  47. data/lib/ddtrace/ext/profiling.rb +52 -0
  48. data/lib/ddtrace/ext/transport.rb +1 -0
  49. data/lib/ddtrace/metrics.rb +4 -0
  50. data/lib/ddtrace/profiling.rb +54 -0
  51. data/lib/ddtrace/profiling/backtrace_location.rb +32 -0
  52. data/lib/ddtrace/profiling/buffer.rb +41 -0
  53. data/lib/ddtrace/profiling/collectors/stack.rb +253 -0
  54. data/lib/ddtrace/profiling/encoding/profile.rb +31 -0
  55. data/lib/ddtrace/profiling/event.rb +13 -0
  56. data/lib/ddtrace/profiling/events/stack.rb +102 -0
  57. data/lib/ddtrace/profiling/exporter.rb +23 -0
  58. data/lib/ddtrace/profiling/ext/cpu.rb +54 -0
  59. data/lib/ddtrace/profiling/ext/cthread.rb +134 -0
  60. data/lib/ddtrace/profiling/ext/forking.rb +97 -0
  61. data/lib/ddtrace/profiling/flush.rb +41 -0
  62. data/lib/ddtrace/profiling/pprof/builder.rb +121 -0
  63. data/lib/ddtrace/profiling/pprof/converter.rb +85 -0
  64. data/lib/ddtrace/profiling/pprof/message_set.rb +12 -0
  65. data/lib/ddtrace/profiling/pprof/payload.rb +18 -0
  66. data/lib/ddtrace/profiling/pprof/pprof.proto +212 -0
  67. data/lib/ddtrace/profiling/pprof/pprof_pb.rb +81 -0
  68. data/lib/ddtrace/profiling/pprof/stack_sample.rb +90 -0
  69. data/lib/ddtrace/profiling/pprof/string_table.rb +10 -0
  70. data/lib/ddtrace/profiling/pprof/template.rb +114 -0
  71. data/lib/ddtrace/profiling/preload.rb +3 -0
  72. data/lib/ddtrace/profiling/profiler.rb +28 -0
  73. data/lib/ddtrace/profiling/recorder.rb +87 -0
  74. data/lib/ddtrace/profiling/scheduler.rb +84 -0
  75. data/lib/ddtrace/profiling/tasks/setup.rb +77 -0
  76. data/lib/ddtrace/profiling/transport/client.rb +12 -0
  77. data/lib/ddtrace/profiling/transport/http.rb +122 -0
  78. data/lib/ddtrace/profiling/transport/http/api.rb +43 -0
  79. data/lib/ddtrace/profiling/transport/http/api/endpoint.rb +90 -0
  80. data/lib/ddtrace/profiling/transport/http/api/instance.rb +36 -0
  81. data/lib/ddtrace/profiling/transport/http/api/spec.rb +40 -0
  82. data/lib/ddtrace/profiling/transport/http/builder.rb +28 -0
  83. data/lib/ddtrace/profiling/transport/http/client.rb +33 -0
  84. data/lib/ddtrace/profiling/transport/http/response.rb +21 -0
  85. data/lib/ddtrace/profiling/transport/io.rb +30 -0
  86. data/lib/ddtrace/profiling/transport/io/client.rb +27 -0
  87. data/lib/ddtrace/profiling/transport/io/response.rb +16 -0
  88. data/lib/ddtrace/profiling/transport/parcel.rb +17 -0
  89. data/lib/ddtrace/profiling/transport/request.rb +15 -0
  90. data/lib/ddtrace/profiling/transport/response.rb +8 -0
  91. data/lib/ddtrace/runtime/container.rb +11 -3
  92. data/lib/ddtrace/sampling/rule_sampler.rb +3 -9
  93. data/lib/ddtrace/tasks/exec.rb +48 -0
  94. data/lib/ddtrace/tasks/help.rb +14 -0
  95. data/lib/ddtrace/tracer.rb +21 -0
  96. data/lib/ddtrace/transport/io/client.rb +15 -8
  97. data/lib/ddtrace/transport/parcel.rb +4 -0
  98. data/lib/ddtrace/version.rb +3 -1
  99. data/lib/ddtrace/workers/runtime_metrics.rb +14 -1
  100. metadata +70 -9
@@ -0,0 +1,88 @@
1
+ # Profiling Development
2
+
3
+ This file contains development notes specific to the profiling feature.
4
+
5
+ For a more practical view of getting started with development of `ddtrace`, see <DevelopmentGuide.md>.
6
+
7
+ ## Profiling components high-level view
8
+
9
+ Components below live inside <../lib/ddtrace/profiling>:
10
+
11
+ * `Collectors::Stack`: Collects stack trace samples from Ruby threads for both CPU-time (if available) and wall-clock.
12
+ Runs on its own background thread.
13
+ * `Encoding::Profile`: Encodes gathered data into the pprof format.
14
+ * `Events::Stack`, `Events::StackSample`, `Events::StackExceptionSample`: Entity classes used to represent stacks.
15
+ * `Ext::CPU`: Monkey patches Ruby's `Thread` with our `Ext::CThread` to enable CPU-time profiling.
16
+ * `Ext::CThread`: Extension used to enable CPU-time profiling via use of Pthread's `getcpuclockid`.
17
+ * `Ext::Forking`: Monkey patches `Kernel#fork`, adding a `Kernel#at_fork` callback mechanism which is used to restore
18
+ profiling abilities after the VM forks (such as re-instrumenting the main thread, and restarting profiler threads).
19
+ * `Pprof::*` (in <../lib/ddtrace/profiling/pprof>): Converts samples captured in the `Recorder` into the pprof format.
20
+ * `Tasks::Setup`: Takes care of loading our extensions/monkey patches to handle fork() and CPU profiling.
21
+ * `Transport::*` (in <../lib/ddtrace/profiling/transport>): Implements transmission of profiling payloads to the Datadog agent
22
+ or backend.
23
+ * `BacktraceLocation`: Entity class used to represent an entry in a stack trace.
24
+ * `Buffer`: Bounded buffer used to store profiling events.
25
+ * `Exporter`: Writes profiling data to a given transport.
26
+ * `Flush`: Entity class used to represent metadata for a given profile.
27
+ * `Profiler`: Profiling entry point, which coordinates collectors and a scheduler.
28
+ * `Recorder`: Stores profiling events gathered by `Collector`s.
29
+ * `Scheduler`: Periodically (every 1 minute) takes data from the `Recorder` and pushes them to all configured
30
+ `Exporter`s. Runs on its own background thread.
31
+
32
+ ## Initialization
33
+
34
+ When started via `ddtracerb exec` (together with `DD_PROFILING_ENABLED=true`), initialization goes through the following
35
+ flow:
36
+
37
+ 1. <../lib/ddtrace/profiling/preload.rb> triggers the creation of the `Datadog.profiler` instance by calling the method
38
+ 2. `Datadog.profiler` is handled by `Datadog::Configuration`, which triggers the configuration of `ddtrace` components
39
+ in `#build_components`
40
+ 3. Inside `Datadog::Components`, the `build_profiler` method triggers the execution of the `Tasks::Setup`
41
+ 4. The `Setup` task activates our extensions
42
+ * `Datadog::Profiling::Ext::Forking`
43
+ * `Datadog::Profiling::Ext::CPU`
44
+ 5. Still inside `Datadog::Components`, the `build_profiler` method then creates and wires up the Profiler:
45
+ ```ruby
46
+ recorder = build_profiler_recorder(settings)
47
+ collectors = build_profiler_collectors(settings, recorder)
48
+ exporters = build_profiler_exporters(settings)
49
+ scheduler = build_profiler_scheduler(settings, recorder, exporters)
50
+
51
+ Datadog::Profiler.new(collectors, scheduler)
52
+ ```
53
+ ```asciiflow
54
+ +------------+
55
+ | Profiler |
56
+ +-+--------+-+
57
+ | |
58
+ v v
59
+ +---------+--+ +--+--------+
60
+ | Collectors | | Scheduler |
61
+ +---------+--+ +-+-------+-+
62
+ | | |
63
+ v | v
64
+ +-----+-+ | +----+------+
65
+ | Stack | | | Exporters |
66
+ +-----+-+ | +-----------+
67
+ | |
68
+ v v
69
+ +-+-------+-+
70
+ | Recorder |
71
+ +-----------+
72
+ ```
73
+ 6. The profiler gets started when `startup!` is called by `Datadog::Configuration` after component creation.
74
+
75
+ ## Run-time execution
76
+
77
+ During run-time, the `Scheduler` and the `Collectors::Stack` each execute on their own background thread.
78
+
79
+ The `Collectors::Stack` samples stack traces of threads, capturing both CPU-time (if available) and wall-clock, storing
80
+ them in the `Recorder`.
81
+
82
+ The `Scheduler` wakes up every 1 minute to flush the results of the `Recorder` into one or more `exporter`s.
83
+ Usually only one exporter is in use. By default, the `Exporter` delegates to the default `Transport::HTTP` transport, which
84
+ takes care of encoding the data and reporting it to the datadog agent (or to the API, when running without an agent).
85
+
86
+ ## How CPU-time profiling works
87
+
88
+ **TODO**: Document our pthread-based approach to getting CPU-time for threads.
@@ -6,8 +6,7 @@ Integration tests for `ddtrace` that use a variety of real applications.
6
6
 
7
7
  1. Build Docker base images:
8
8
 
9
- ```sh
10
- #!/bin/bash
9
+ ```bash
11
10
  ./script/build-images
12
11
  ```
13
12
 
@@ -15,6 +15,9 @@ ENV DD_DEMO_ENV_GEM_REF_DDTRACE ${ddtrace_ref}
15
15
 
16
16
  # Install dependencies
17
17
  COPY Gemfile /app/Gemfile
18
+ # This forces gems with native extensions to be compiled, rather than using pre-compiled binaries; it's needed because
19
+ # some google-protobuf versions ship with missing binaries for older rubies.
20
+ ENV BUNDLE_FORCE_RUBY_PLATFORM true
18
21
  RUN bundle install
19
22
 
20
23
  # Add files
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  APP_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  APP_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  APP_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  APP_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  APP_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  APP_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  # If health check URL provided, wait till it passes.
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  bash /vendor/dd-demo/http-health-check
3
3
 
4
4
  # Start the load test
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  INTEGRATION_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
data/lib/ddtrace.rb CHANGED
@@ -15,6 +15,7 @@ require 'ddtrace/configuration'
15
15
  require 'ddtrace/patcher'
16
16
  require 'ddtrace/metrics'
17
17
  require 'ddtrace/auto_instrument_base'
18
+ require 'ddtrace/profiling'
18
19
 
19
20
  # \Datadog global namespace that includes all tracing functionality for Tracer and Span classes.
20
21
  module Datadog
@@ -2,10 +2,11 @@ require 'forwardable'
2
2
  require 'ddtrace/configuration/pin_setup'
3
3
  require 'ddtrace/configuration/settings'
4
4
  require 'ddtrace/configuration/components'
5
+ require 'ddtrace/utils/only_once'
5
6
 
6
7
  module Datadog
7
8
  # Configuration provides a unique access point for configurations
8
- module Configuration
9
+ module Configuration # rubocop:disable Metrics/ModuleLength
9
10
  extend Forwardable
10
11
 
11
12
  # Used to ensure that @components initialization/reconfiguration is performed one-at-a-time, by a single thread.
@@ -42,6 +43,8 @@ module Datadog
42
43
  end
43
44
 
44
45
  def configure(target = configuration, opts = {})
46
+ ruby_version_deprecation_warning
47
+
45
48
  if target.is_a?(Settings)
46
49
  yield(target) if block_given?
47
50
 
@@ -64,6 +67,7 @@ module Datadog
64
67
  def_delegators \
65
68
  :components,
66
69
  :health_metrics,
70
+ :profiler,
67
71
  :runtime_metrics,
68
72
  :tracer
69
73
 
@@ -94,18 +98,6 @@ module Datadog
94
98
  end
95
99
  end
96
100
 
97
- # Gracefully shuts down the tracer and disposes of component references,
98
- # allowing execution to start anew.
99
- #
100
- # In contrast with +#shutdown!+, components will be automatically
101
- # reinitialized after a reset.
102
- def reset!
103
- safely_synchronize do |write_components|
104
- @components.shutdown! if components?
105
- write_components.call(nil)
106
- end
107
- end
108
-
109
101
  protected
110
102
 
111
103
  def components(allow_initialization: true)
@@ -119,6 +111,21 @@ module Datadog
119
111
 
120
112
  private
121
113
 
114
+ # Gracefully shuts down the tracer and disposes of component references,
115
+ # allowing execution to start anew.
116
+ #
117
+ # In contrast with +#shutdown!+, components will be automatically
118
+ # reinitialized after a reset.
119
+ #
120
+ # Used internally to ensure a clean environment between test runs.
121
+ def reset!
122
+ safely_synchronize do |write_components|
123
+ @components.shutdown! if components?
124
+ write_components.call(nil)
125
+ configuration.reset!
126
+ end
127
+ end
128
+
122
129
  def safely_synchronize
123
130
  # Writes to @components should only happen through this proc. Because this proc is only accessible to callers of
124
131
  # safely_synchronize, this forces all writers to go through this method.
@@ -168,5 +175,24 @@ module Datadog
168
175
  logger
169
176
  end
170
177
  end
178
+
179
+ # Perform version check only once
180
+ DEPRECATED_RUBY_VERSION = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.1')
181
+ private_constant :DEPRECATED_RUBY_VERSION
182
+
183
+ RUBY_VERSION_DEPRECATION_ONLY_ONCE = Datadog::Utils::OnlyOnce.new
184
+ private_constant :RUBY_VERSION_DEPRECATION_ONLY_ONCE
185
+
186
+ def ruby_version_deprecation_warning
187
+ return unless DEPRECATED_RUBY_VERSION
188
+
189
+ RUBY_VERSION_DEPRECATION_ONLY_ONCE.run do
190
+ Datadog.logger.warn(
191
+ "Support for Ruby versions < 2.1 in dd-trace-rb is DEPRECATED.\n" \
192
+ "Last version to support Ruby < 2.1 will be 0.49.x, which will only receive critical bugfixes.\n" \
193
+ 'Support for Ruby versions < 2.1 will be REMOVED in version 0.50.0.'
194
+ )
195
+ end
196
+ end
171
197
  end
172
198
  end
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/diagnostics/health'
2
2
  require 'ddtrace/logger'
3
+ require 'ddtrace/profiling'
3
4
  require 'ddtrace/runtime/metrics'
4
5
  require 'ddtrace/tracer'
5
6
  require 'ddtrace/workers/runtime_metrics'
@@ -8,6 +9,7 @@ module Datadog
8
9
  module Configuration
9
10
  # Global components for the trace library.
10
11
  # rubocop:disable Layout/LineLength
12
+ # rubocop:disable Metrics/ClassLength
11
13
  class Components
12
14
  class << self
13
15
  def build_health_metrics(settings)
@@ -66,6 +68,22 @@ module Datadog
66
68
  tracer
67
69
  end
68
70
 
71
+ def build_profiler(settings)
72
+ return unless Datadog::Profiling.supported? && settings.profiling.enabled
73
+
74
+ # Load extensions needed to support some of the Profiling features
75
+ Datadog::Profiling::Tasks::Setup.new.run
76
+
77
+ # NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method
78
+
79
+ recorder = build_profiler_recorder(settings)
80
+ collectors = build_profiler_collectors(settings, recorder)
81
+ exporters = build_profiler_exporters(settings)
82
+ scheduler = build_profiler_scheduler(settings, recorder, exporters)
83
+
84
+ Datadog::Profiler.new(collectors, scheduler)
85
+ end
86
+
69
87
  private
70
88
 
71
89
  def build_tracer_tags(settings)
@@ -90,11 +108,51 @@ module Datadog
90
108
  opts[:writer_options] = settings.writer_options if settings.writer.nil?
91
109
  end
92
110
  end
111
+
112
+ def build_profiler_recorder(settings)
113
+ event_classes = [Datadog::Profiling::Events::StackSample]
114
+
115
+ Datadog::Profiling::Recorder.new(event_classes, settings.profiling.max_events)
116
+ end
117
+
118
+ def build_profiler_collectors(settings, recorder)
119
+ [
120
+ Datadog::Profiling::Collectors::Stack.new(
121
+ recorder,
122
+ max_frames: settings.profiling.max_frames
123
+ # TODO: Provide proc that identifies Datadog worker threads?
124
+ # ignore_thread: settings.profiling.ignore_profiler
125
+ )
126
+ ]
127
+ end
128
+
129
+ def build_profiler_exporters(settings)
130
+ if settings.profiling.exporter.instances.is_a?(Array)
131
+ settings.profiling.exporter.instances
132
+ else
133
+ transport = if settings.profiling.exporter.transport
134
+ settings.profiling.exporter.transport
135
+ else
136
+ transport_options = settings.profiling.exporter.transport_options.dup
137
+ transport_options[:site] ||= settings.site if settings.site
138
+ transport_options[:api_key] ||= settings.api_key if settings.api_key
139
+ transport_options[:timeout] ||= settings.profiling.upload.timeout
140
+ Datadog::Profiling::Transport::HTTP.default(transport_options)
141
+ end
142
+
143
+ [Datadog::Profiling::Exporter.new(transport)]
144
+ end
145
+ end
146
+
147
+ def build_profiler_scheduler(settings, recorder, exporters)
148
+ Datadog::Profiling::Scheduler.new(recorder, exporters)
149
+ end
93
150
  end
94
151
 
95
152
  attr_reader \
96
153
  :health_metrics,
97
154
  :logger,
155
+ :profiler,
98
156
  :runtime_metrics,
99
157
  :tracer
100
158
 
@@ -105,6 +163,9 @@ module Datadog
105
163
  # Tracer
106
164
  @tracer = self.class.build_tracer(settings)
107
165
 
166
+ # Profiler
167
+ @profiler = self.class.build_profiler(settings)
168
+
108
169
  # Runtime metrics
109
170
  @runtime_metrics = self.class.build_runtime_metrics_worker(settings)
110
171
 
@@ -113,7 +174,20 @@ module Datadog
113
174
  end
114
175
 
115
176
  # Starts up components
116
- def startup!(settings); end
177
+ def startup!(settings)
178
+ if settings.profiling.enabled
179
+ if profiler
180
+ @logger.debug('Profiling started')
181
+ profiler.start
182
+ else
183
+ # Display a warning for users who expected profiling to autostart
184
+ protobuf = Datadog::Profiling.google_protobuf_supported?
185
+ logger.warn("Profiling was enabled but is not supported; profiling disabled. (google-protobuf?: #{protobuf})")
186
+ end
187
+ else
188
+ @logger.debug('Profiling is disabled')
189
+ end
190
+ end
117
191
 
118
192
  # Shuts down all the components in use.
119
193
  # If it has another instance to compare to, it will compare
@@ -123,12 +197,20 @@ module Datadog
123
197
  # (e.g. a custom tracer instance passed in.)
124
198
  tracer.shutdown! unless replacement && tracer == replacement.tracer
125
199
 
200
+ # Shutdown old profiler
201
+ profiler.shutdown! unless profiler.nil?
202
+
126
203
  # Shutdown workers
127
- runtime_metrics.enabled = false
128
- runtime_metrics.stop(true)
204
+ runtime_metrics.stop(true, close_metrics: false)
129
205
 
130
206
  # Shutdown the old metrics, unless they are still being used.
131
207
  # (e.g. custom Statsd instances.)
208
+ #
209
+ # TODO: This violates the encapsulation created by Runtime::Metrics and
210
+ # Health::Metrics, by directly manipulating `statsd` and changing
211
+ # it's lifecycle management.
212
+ # If we need to directly have ownership of `statsd` lifecycle, we should
213
+ # have direct ownership of it.
132
214
  old_statsd = [
133
215
  runtime_metrics.metrics.statsd,
134
216
  health_metrics.statsd
@@ -3,6 +3,7 @@ require 'ddtrace/configuration/base'
3
3
 
4
4
  require 'ddtrace/ext/analytics'
5
5
  require 'ddtrace/ext/distributed'
6
+ require 'ddtrace/ext/profiling'
6
7
  require 'ddtrace/ext/runtime'
7
8
  require 'ddtrace/ext/sampling'
8
9
 
@@ -108,6 +109,36 @@ module Datadog
108
109
  get_option(:logger).instance = logger
109
110
  end
110
111
 
112
+ settings :profiling do
113
+ option :enabled do |o|
114
+ o.default { env_to_bool(Ext::Profiling::ENV_ENABLED, false) }
115
+ o.lazy
116
+ end
117
+
118
+ settings :exporter do
119
+ option :instances
120
+ option :transport
121
+ option :transport_options, default: ->(_o) { {} }, lazy: true
122
+ end
123
+
124
+ option :max_events, default: 32768
125
+
126
+ # Controls the maximum number of frames for each thread sampled. Can be tuned to avoid omitted frames in the
127
+ # produced profiles. Increasing this may increase the overhead of profiling.
128
+ option :max_frames do |o|
129
+ o.default { env_to_int(Ext::Profiling::ENV_MAX_FRAMES, 400) }
130
+ o.lazy
131
+ end
132
+
133
+ settings :upload do
134
+ option :timeout do |o|
135
+ o.setter { |value| value.nil? ? 30.0 : value.to_f }
136
+ o.default { env_to_float(Ext::Profiling::ENV_UPLOAD_TIMEOUT, 30.0) }
137
+ o.lazy
138
+ end
139
+ end
140
+ end
141
+
111
142
  option :report_hostname do |o|
112
143
  o.default { env_to_bool(Ext::NET::ENV_REPORT_HOSTNAME, false) }
113
144
  o.lazy