datadog 2.6.0 → 2.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23fdb98e800ed71c28238b4b61e7f1187b27833d8e98c14e0f60d43ce838d4cd
4
- data.tar.gz: ed99ae40d1e94aedcf27f8bcdeb70059c02ad116e8648621e37d22d5be1f69ad
3
+ metadata.gz: '00617590b3381113b74dde6671802aad74e6ffee0a96737fbc04149515c6a79d'
4
+ data.tar.gz: 5bed675aca238d308051ba0a728209e2a4a5ba17f2dc11a52eacee8aaf55a123
5
5
  SHA512:
6
- metadata.gz: df3d8bc5efb89bb7a893b006484d3d826acf7beb57d6abbf8b25c2e9a277a95f7f681d6262d5dd08485aaf5526c677edf641711435e67674f1043c1fbf1ba55f
7
- data.tar.gz: 02b397ae85a8ced3f6112beb899826c86ba137be36c229a85150cdc708dadd937e9860775bdfd02d7475bb4f7c890b1019901ec146acb5ad21bdd192906aa339
6
+ metadata.gz: 4097896d2d8126418f0827b9c4ad916a003e71ead0919fae2b3586415540f869d58f140865d4c625d20fd4de6a76bcf667156893e7c01f0fee981b7fcb6cafe9
7
+ data.tar.gz: ce91b73f91a97db31570bd92dab0ca26bf7a6b849d67b774a4efacea0ec93e19f19c27a3dc3f0f232f2adce6cf5ed13b510c30651c529a6b402137944a6b2e87
data/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.7.1] - 2024-11-28
6
+
7
+ ### Fixed
8
+
9
+ * Tracing: Fix missing version tag ([#4075][])
10
+ * Profiling: Fix profiling not loading in certain situations on Ruby 2.5 and 3.3 ([#4161][])
11
+
12
+ ## [2.7.0] - 2024-11-13
13
+
14
+ ### Added
15
+
16
+ * Profiling: Enable "heap clean after GC" profiler optimization by default ([#4085][])
17
+
18
+ ### Changed
19
+
20
+ * Enable crashtracking by default ([#4083][])
21
+ * Upgrade to `libdatadog` 14.1 ([#4082][])
22
+
23
+ ### Fixed
24
+
25
+ * Fix `Process.waitall` hanging and stack overflow when crashtracking enabled ([#4082][])
26
+
5
27
  ## [2.6.0] - 2024-11-06
6
28
 
7
29
  ### Changed
@@ -3013,7 +3035,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
3013
3035
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3014
3036
 
3015
3037
 
3016
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.6.0...master
3038
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.7.0...master
3039
+ [2.7.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.6.0...v2.7.0
3017
3040
  [2.6.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.5.0...v2.6.0
3018
3041
  [2.5.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.4.0...v2.5.0
3019
3042
  [2.4.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.3.0...v2.4.0
@@ -4457,7 +4480,12 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4457
4480
  [#4027]: https://github.com/DataDog/dd-trace-rb/issues/4027
4458
4481
  [#4033]: https://github.com/DataDog/dd-trace-rb/issues/4033
4459
4482
  [#4065]: https://github.com/DataDog/dd-trace-rb/issues/4065
4483
+ [#4075]: https://github.com/DataDog/dd-trace-rb/issues/4075
4460
4484
  [#4078]: https://github.com/DataDog/dd-trace-rb/issues/4078
4485
+ [#4082]: https://github.com/DataDog/dd-trace-rb/issues/4082
4486
+ [#4083]: https://github.com/DataDog/dd-trace-rb/issues/4083
4487
+ [#4085]: https://github.com/DataDog/dd-trace-rb/issues/4085
4488
+ [#4161]: https://github.com/DataDog/dd-trace-rb/issues/4161
4461
4489
  [@AdrianLC]: https://github.com/AdrianLC
4462
4490
  [@Azure7111]: https://github.com/Azure7111
4463
4491
  [@BabyGroot]: https://github.com/BabyGroot
@@ -131,6 +131,9 @@ end
131
131
 
132
132
  have_func "malloc_stats"
133
133
 
134
+ # On Ruby 2.5 and 3.3, this symbol was not visible. It is on 2.6 to 3.2, as well as 3.4+
135
+ $defs << "-DNO_RB_OBJ_INFO" if RUBY_VERSION.start_with?("2.5", "3.3")
136
+
134
137
  # On older Rubies, rb_postponed_job_preregister/rb_postponed_job_trigger did not exist
135
138
  $defs << "-DNO_POSTPONED_TRIGGER" if RUBY_VERSION < "3.3"
136
139
 
@@ -587,16 +587,13 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *st
587
587
  // Taken from upstream vm_insnhelper.c at commit 5f10bd634fb6ae8f74a4ea730176233b0ca96954 (March 2022, Ruby 3.2 trunk)
588
588
  // Copyright (C) 2007 Koichi Sasada
589
589
  // to support our custom rb_profile_frames (see above)
590
- // Modifications: None
590
+ // Modifications:
591
+ // * Removed debug checks (they were ifdef'd out anyway)
591
592
  static rb_callable_method_entry_t *
592
593
  check_method_entry(VALUE obj, int can_be_svar)
593
594
  {
594
595
  if (obj == Qfalse) return NULL;
595
596
 
596
- #if VM_CHECK_MODE > 0
597
- if (!RB_TYPE_P(obj, T_IMEMO)) rb_bug("check_method_entry: unknown type: %s", rb_obj_info(obj));
598
- #endif
599
-
600
597
  switch (imemo_type(obj)) {
601
598
  case imemo_ment:
602
599
  return (rb_callable_method_entry_t *)obj;
@@ -608,9 +605,6 @@ check_method_entry(VALUE obj, int can_be_svar)
608
605
  }
609
606
  // fallthrough
610
607
  default:
611
- #if VM_CHECK_MODE > 0
612
- rb_bug("check_method_entry: svar should not be there:");
613
- #endif
614
608
  return NULL;
615
609
  }
616
610
  }
@@ -37,6 +37,7 @@ static VALUE _native_trigger_holding_the_gvl_signal_handler_on(DDTRACE_UNUSED VA
37
37
  static VALUE _native_enforce_success(DDTRACE_UNUSED VALUE _self, VALUE syserr_errno, VALUE with_gvl);
38
38
  static void *trigger_enforce_success(void *trigger_args);
39
39
  static VALUE _native_malloc_stats(DDTRACE_UNUSED VALUE _self);
40
+ static VALUE _native_safe_object_info(DDTRACE_UNUSED VALUE _self, VALUE obj);
40
41
 
41
42
  void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
42
43
  VALUE datadog_module = rb_define_module("Datadog");
@@ -72,6 +73,7 @@ void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
72
73
  rb_define_singleton_method(testing_module, "_native_trigger_holding_the_gvl_signal_handler_on", _native_trigger_holding_the_gvl_signal_handler_on, 1);
73
74
  rb_define_singleton_method(testing_module, "_native_enforce_success", _native_enforce_success, 2);
74
75
  rb_define_singleton_method(testing_module, "_native_malloc_stats", _native_malloc_stats, 0);
76
+ rb_define_singleton_method(testing_module, "_native_safe_object_info", _native_safe_object_info, 1);
75
77
  }
76
78
 
77
79
  static VALUE native_working_p(DDTRACE_UNUSED VALUE _self) {
@@ -265,3 +267,7 @@ static VALUE _native_malloc_stats(DDTRACE_UNUSED VALUE _self) {
265
267
  return Qfalse;
266
268
  #endif
267
269
  }
270
+
271
+ static VALUE _native_safe_object_info(DDTRACE_UNUSED VALUE _self, VALUE obj) {
272
+ return rb_str_new_cstr(safe_object_info(obj));
273
+ }
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include "ruby_helpers.h"
5
5
  #include "private_vm_api_access.h"
6
+ #include "extconf.h"
6
7
 
7
8
  // The following global variables are initialized at startup to save expensive lookups later.
8
9
  // They are not expected to be mutated outside of init.
@@ -219,17 +220,26 @@ static bool ruby_is_obj_with_class(VALUE obj) {
219
220
  return false;
220
221
  }
221
222
 
222
- // These two functions are not present in the VM headers, but are public symbols that can be invoked.
223
+ // This function is not present in the VM headers, but is a public symbol that can be invoked.
223
224
  int rb_objspace_internal_object_p(VALUE obj);
224
- const char *rb_obj_info(VALUE obj);
225
+
226
+ #ifdef NO_RB_OBJ_INFO
227
+ const char* safe_object_info(DDTRACE_UNUSED VALUE obj) { return "(No rb_obj_info for current Ruby)"; }
228
+ #else
229
+ // This function is a public symbol, but not on all Rubies; `safe_object_info` below abstracts this, and
230
+ // should be used instead.
231
+ const char *rb_obj_info(VALUE obj);
232
+
233
+ const char* safe_object_info(VALUE obj) { return rb_obj_info(obj); }
234
+ #endif
225
235
 
226
236
  VALUE ruby_safe_inspect(VALUE obj) {
227
237
  if (!ruby_is_obj_with_class(obj)) return rb_str_new_cstr("(Not an object)");
228
- if (rb_objspace_internal_object_p(obj)) return rb_sprintf("(VM Internal, %s)", rb_obj_info(obj));
238
+ if (rb_objspace_internal_object_p(obj)) return rb_sprintf("(VM Internal, %s)", safe_object_info(obj));
229
239
  // @ivoanjo: I saw crashes on Ruby 3.1.4 when trying to #inspect matchdata objects. I'm not entirely sure why this
230
240
  // is needed, but since we only use this method for debug purposes I put in this alternative and decided not to
231
241
  // dig deeper.
232
- if (rb_type(obj) == RUBY_T_MATCH) return rb_sprintf("(MatchData, %s)", rb_obj_info(obj));
242
+ if (rb_type(obj) == RUBY_T_MATCH) return rb_sprintf("(MatchData, %s)", safe_object_info(obj));
233
243
  if (rb_respond_to(obj, inspect_id)) return rb_sprintf("%+"PRIsVALUE, obj);
234
244
  if (rb_respond_to(obj, to_s_id)) return rb_sprintf("%"PRIsVALUE, obj);
235
245
 
@@ -90,3 +90,7 @@ size_t ruby_obj_memsize_of(VALUE obj);
90
90
  // return a string with the result of that call. Elsif the object responds to
91
91
  // 'to_s', return a string with the result of that call. Otherwise, return Qnil.
92
92
  VALUE ruby_safe_inspect(VALUE obj);
93
+
94
+ // You probably want ruby_safe_inspect instead; this is a lower-level dependency
95
+ // of it, that's being exposed here just to facilitate testing.
96
+ const char* safe_object_info(VALUE obj);
@@ -58,16 +58,18 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
58
58
 
59
59
  ddog_crasht_Config config = {
60
60
  .additional_files = {},
61
- // The Ruby VM already uses an alt stack to detect stack overflows so the crash handler must not overwrite it.
61
+ // @ivoanjo: The Ruby VM already uses an alt stack to detect stack overflows.
62
62
  //
63
- // @ivoanjo: Specifically, with `create_alt_stack = true` I saw a segfault, such as Ruby 2.6's bug with
63
+ // In libdatadog < 14 with `create_alt_stack = true` I saw a segfault, such as Ruby 2.6's bug with
64
64
  // "Process.detach(fork { exit! }).instance_variable_get(:@foo)" being turned into a
65
65
  // "-e:1:in `instance_variable_get': stack level too deep (SystemStackError)" by Ruby.
66
- //
67
66
  // The Ruby crash handler also seems to get confused when this option is enabled and
68
67
  // "Process.kill('SEGV', Process.pid)" gets run.
68
+ //
69
+ // This actually changed in libdatadog 14, so I could see no issues with `create_alt_stack = true`, but not
70
+ // overridding what Ruby set up seems a saner default to keep anyway.
69
71
  .create_alt_stack = false,
70
- .use_alt_stack = true, // NOTE: This is a no-op in libdatadog 14.0; should be fixed in a future version
72
+ .use_alt_stack = true,
71
73
  .endpoint = endpoint,
72
74
  .resolve_frames = DDOG_CRASHT_STACKTRACE_COLLECTION_ENABLED_WITH_SYMBOLS_IN_RECEIVER,
73
75
  .timeout_ms = FIX2INT(upload_timeout_seconds) * 1000,
@@ -8,7 +8,7 @@ module Datadog
8
8
  module LibdatadogExtconfHelpers
9
9
  # Used to make sure the correct gem version gets loaded, as extconf.rb does not get run with "bundle exec" and thus
10
10
  # may see multiple libdatadog versions. See https://github.com/DataDog/dd-trace-rb/pull/2531 for the horror story.
11
- LIBDATADOG_VERSION = '~> 14.0.0.1.0'
11
+ LIBDATADOG_VERSION = '~> 14.1.0.1.0'
12
12
 
13
13
  # Used as an workaround for a limitation with how dynamic linking works in environments where the datadog gem and
14
14
  # libdatadog are moved after the extension gets compiled.
@@ -518,13 +518,13 @@ module Datadog
518
518
  # Controls if the heap profiler should attempt to clean young objects after GC, rather than just at
519
519
  # serialization time. This lowers memory usage and high percentile latency.
520
520
  #
521
- # Only takes effect when used together with `gc_enabled: true` and `experimental_heap_enabled: true`.
521
+ # Only has effect when used together with `gc_enabled: true` and `experimental_heap_enabled: true`.
522
522
  #
523
- # @default false
523
+ # @default true
524
524
  option :heap_clean_after_gc_enabled do |o|
525
525
  o.type :bool
526
526
  o.env 'DD_PROFILING_HEAP_CLEAN_AFTER_GC_ENABLED'
527
- o.default false
527
+ o.default true
528
528
  end
529
529
  end
530
530
 
@@ -927,7 +927,7 @@ module Datadog
927
927
  # Enables reporting of information when Ruby VM crashes.
928
928
  option :enabled do |o|
929
929
  o.type :bool
930
- o.default false
930
+ o.default true
931
931
  o.env 'DD_CRASHTRACKING_ENABLED'
932
932
  end
933
933
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Lint/AssignmentInCondition
4
+
3
5
  module Datadog
4
6
  module DI
5
7
  # Tracks loaded Ruby code by source file and maintains a map from
@@ -77,6 +79,26 @@ module Datadog
77
79
  registry[path] = tp.instruction_sequence
78
80
  end
79
81
  end
82
+
83
+ DI.component&.probe_manager&.install_pending_line_probes(path)
84
+
85
+ # Since this method normally is called from customer applications,
86
+ # rescue any exceptions that might not be handled to not break said
87
+ # customer applications.
88
+ rescue => exc
89
+ # TODO we do not have DI.component defined yet, remove steep:ignore
90
+ # before release.
91
+ if component = DI.component # steep:ignore
92
+ raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
93
+ component.logger.warn("Unhandled exception in script_compiled trace point: #{exc.class}: #{exc}")
94
+ component.telemetry&.report(exc, description: "Unhandled exception in script_compiled trace point")
95
+ # TODO test this path
96
+ else
97
+ # If we don't have a component, we cannot log anything properly.
98
+ # Do not just print a warning to avoid spamming customer logs.
99
+ # Don't reraise the exception either.
100
+ # TODO test this path
101
+ end
80
102
  end
81
103
  end
82
104
  end
@@ -112,15 +134,18 @@ module Datadog
112
134
  def iseqs_for_path_suffix(suffix)
113
135
  registry_lock.synchronize do
114
136
  exact = registry[suffix]
115
- return [exact] if exact
137
+ return [suffix, exact] if exact
116
138
 
117
139
  inexact = []
118
140
  registry.each do |path, iseq|
119
141
  if Utils.path_matches_suffix?(path, suffix)
120
- inexact << iseq
142
+ inexact << [path, iseq]
121
143
  end
122
144
  end
123
- inexact
145
+ if inexact.length > 1
146
+ raise Error::MultiplePathsMatch, "Multiple paths matched requested suffix"
147
+ end
148
+ inexact.first
124
149
  end
125
150
  end
126
151
 
@@ -164,3 +189,5 @@ module Datadog
164
189
  end
165
190
  end
166
191
  end
192
+
193
+ # rubocop:enable Lint/AssignmentInCondition
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module DI
5
+ # Component for dynamic instrumentation.
6
+ #
7
+ # Only one instance of the Component should ever be active;
8
+ # if configuration is changed, the old distance should be shut down
9
+ # prior to the new instance being created.
10
+ #
11
+ # The Component instance stores all state related to DI, for example
12
+ # which probes have been retrieved via remote config,
13
+ # intalled tracepoints and so on. Component will clean up all
14
+ # resources and installed tracepoints upon shutdown.
15
+ class Component
16
+ class << self
17
+ def build(settings, agent_settings, telemetry: nil)
18
+ return unless settings.respond_to?(:dynamic_instrumentation) && settings.dynamic_instrumentation.enabled
19
+
20
+ unless settings.respond_to?(:remote) && settings.remote.enabled
21
+ Datadog.logger.debug("Dynamic Instrumentation could not be enabled because Remote Configuration Management is not available. To enable Remote Configuration, see https://docs.datadoghq.com/agent/remote_config")
22
+ return
23
+ end
24
+
25
+ return unless environment_supported?(settings)
26
+
27
+ new(settings, agent_settings, Datadog.logger, code_tracker: DI.code_tracker, telemetry: telemetry)
28
+ end
29
+
30
+ def build!(settings, agent_settings, telemetry: nil)
31
+ unless settings.respond_to?(:dynamic_instrumentation) && settings.dynamic_instrumentation.enabled
32
+ raise "Requested DI component but DI is not enabled in settings"
33
+ end
34
+
35
+ unless settings.respond_to?(:remote) && settings.remote.enabled
36
+ raise "Requested DI component but remote config is not enabled in settings"
37
+ end
38
+
39
+ unless environment_supported?(settings)
40
+ raise "DI does not support the environment (development or Ruby version too low or not MRI)"
41
+ end
42
+
43
+ new(settings, agent_settings, Datadog.logger, code_tracker: DI.code_tracker, telemetry: telemetry)
44
+ end
45
+
46
+ # Checks whether the runtime environment is supported by
47
+ # dynamic instrumentation. Currently we only require that, if Rails
48
+ # is used, that Rails environment is not development because
49
+ # DI does not currently support code unloading and reloading.
50
+ def environment_supported?(settings)
51
+ # TODO add tests?
52
+ unless settings.dynamic_instrumentation.internal.development
53
+ if Datadog::Core::Environment::Execution.development?
54
+ Datadog.logger.debug("Not enabling dynamic instrumentation because we are in development environment")
55
+ return false
56
+ end
57
+ end
58
+ if RUBY_ENGINE != 'ruby' || RUBY_VERSION < '2.6'
59
+ Datadog.logger.debug("Not enabling dynamic instrumentation because of unsupported Ruby version")
60
+ return false
61
+ end
62
+ true
63
+ end
64
+ end
65
+
66
+ def initialize(settings, agent_settings, logger, code_tracker: nil, telemetry: nil)
67
+ @settings = settings
68
+ @agent_settings = agent_settings
69
+ @logger = logger
70
+ @telemetry = telemetry
71
+ @redactor = Redactor.new(settings)
72
+ @serializer = Serializer.new(settings, redactor, telemetry: telemetry)
73
+ @instrumenter = Instrumenter.new(settings, serializer, logger, code_tracker: code_tracker, telemetry: telemetry)
74
+ @transport = Transport.new(agent_settings)
75
+ @probe_notifier_worker = ProbeNotifierWorker.new(settings, transport, logger, telemetry: telemetry)
76
+ @probe_notification_builder = ProbeNotificationBuilder.new(settings, serializer)
77
+ @probe_manager = ProbeManager.new(settings, instrumenter, probe_notification_builder, probe_notifier_worker, logger, telemetry: telemetry)
78
+ probe_notifier_worker.start
79
+ end
80
+
81
+ attr_reader :settings
82
+ attr_reader :agent_settings
83
+ attr_reader :logger
84
+ attr_reader :telemetry
85
+ attr_reader :instrumenter
86
+ attr_reader :transport
87
+ attr_reader :probe_notifier_worker
88
+ attr_reader :probe_notification_builder
89
+ attr_reader :probe_manager
90
+ attr_reader :redactor
91
+ attr_reader :serializer
92
+
93
+ # Shuts down dynamic instrumentation.
94
+ #
95
+ # Removes all code hooks and stops background threads.
96
+ #
97
+ # Does not clear out the code tracker, because it's only populated
98
+ # by code when code is compiled and therefore, if the code tracker
99
+ # was replaced by a new instance, the new instance of it wouldn't have
100
+ # any of the already loaded code tracked.
101
+ def shutdown!(replacement = nil)
102
+ probe_manager.clear_hooks
103
+ probe_manager.close
104
+ probe_notifier_worker.stop
105
+ end
106
+ end
107
+ end
108
+ end
@@ -12,8 +12,6 @@ module Datadog
12
12
 
13
13
  def self.add_settings!(base)
14
14
  base.class_eval do
15
- # The setting has "internal" prefix to prevent it from being
16
- # prematurely turned on by customers.
17
15
  settings :dynamic_instrumentation do
18
16
  option :enabled do |o|
19
17
  o.type :bool
@@ -26,48 +24,6 @@ module Datadog
26
24
  o.default false
27
25
  end
28
26
 
29
- # This option instructs dynamic instrumentation to use
30
- # untargeted trace points when installing line probes and
31
- # code tracking is not active.
32
- # WARNING: untargeted trace points carry a massive performance
33
- # penalty for the entire file in which a line probe is placed.
34
- #
35
- # If this option is set to false, which is the default,
36
- # dynamic instrumentation will add probes that reference
37
- # unknown files to the list of pending probes, and when
38
- # the respective files are loaded, the line probes will be
39
- # installed using targeted trace points. If the file in
40
- # question is already loaded when the probe is received
41
- # (for example, it is in a third-party library loaded during
42
- # application boot), and code tracking was not active when
43
- # the file was loaded, such files will not be instrumentable
44
- # via line probes.
45
- #
46
- # If this option is set to true
47
- #
48
- # activated, DI will in
49
- # activated or because the files being targeted have beenIf true and code tracking is not enabled, dynamic instrumentation
50
- # will use untargeted trace points.
51
- # If false and code tracking is not enabled, dynamic
52
- # instrumentation will not instrument any files loaded
53
- # WARNING: these trace points will greatly degrade performance
54
- # of all code in the instrumented files.
55
- option :untargeted_trace_points do |o|
56
- o.type :bool
57
- o.default false
58
- end
59
-
60
- # If true, all of the catch-all rescue blocks in DI
61
- # will propagate the exceptions onward.
62
- # WARNING: for internal Datadog use only - this will break
63
- # the DI product and potentially the library in general in
64
- # a multitude of ways, cause resource leakage, permanent
65
- # performance decreases, etc.
66
- option :propagate_all_exceptions do |o|
67
- o.type :bool
68
- o.default false
69
- end
70
-
71
27
  # An array of variable and key names to redact in addition to
72
28
  # the built-in list of identifiers.
73
29
  #
@@ -154,6 +110,75 @@ module Datadog
154
110
  o.type :int
155
111
  o.default 20
156
112
  end
113
+
114
+ # Settings in the 'internal' group are for internal Datadog
115
+ # use only, and are needed to test dynamic instrumentation or
116
+ # experiment with features not released to customers.
117
+ settings :internal do
118
+ # This option instructs dynamic instrumentation to use
119
+ # untargeted trace points when installing line probes and
120
+ # code tracking is not active.
121
+ # WARNING: untargeted trace points carry a massive performance
122
+ # penalty for the entire file in which a line probe is placed.
123
+ #
124
+ # If this option is set to false, which is the default,
125
+ # dynamic instrumentation will add probes that reference
126
+ # unknown files to the list of pending probes, and when
127
+ # the respective files are loaded, the line probes will be
128
+ # installed using targeted trace points. If the file in
129
+ # question is already loaded when the probe is received
130
+ # (for example, it is in a third-party library loaded during
131
+ # application boot), and code tracking was not active when
132
+ # the file was loaded, such files will not be instrumentable
133
+ # via line probes.
134
+ #
135
+ # If this option is set to true, dynamic instrumentation will
136
+ # install untargeted trace points for all line probes,
137
+ # regardless of whether the referenced file is loaded.
138
+ # This permits instrumenting code which was loaded prior to
139
+ # code tracking being activated and instrumenting lines when
140
+ # code tracking is not activated at all. However, untargeted
141
+ # trace points are extremely slow and will greatly degrade
142
+ # performance of *all* code executed while they are installed,
143
+ # not just the instrumentation target.
144
+ option :untargeted_trace_points do |o|
145
+ o.type :bool
146
+ o.default false
147
+ end
148
+
149
+ # If true, all of the catch-all rescue blocks in DI
150
+ # will propagate the exceptions onward.
151
+ # WARNING: for internal Datadog use only - this will break
152
+ # the DI product and potentially the library in general in
153
+ # a multitude of ways, cause resource leakage, permanent
154
+ # performance decreases, etc.
155
+ option :propagate_all_exceptions do |o|
156
+ o.type :bool
157
+ o.default false
158
+ end
159
+
160
+ # Minimum interval, in seconds, between probe status and
161
+ # snapshot submissions to the agent. Probe notifier worker will
162
+ # batch together payloads submitted during each interval.
163
+ # A longer interval reduces the overhead imposed by dynamic
164
+ # instrumentation on the application, but also increases the
165
+ # time when application code cannot run (when the batches are
166
+ # being sent out by the probe notifier worker) and creates a
167
+ # possibility of dropping payloads if the queue gets too long.
168
+ option :min_send_interval do |o|
169
+ o.type :int
170
+ o.default 3
171
+ end
172
+
173
+ # Enable dynamic instrumentation in development environments.
174
+ # Currently DI does not fully implement support for code
175
+ # unloading and reloading, and is not supported in
176
+ # non-production environments.
177
+ option :development do |o|
178
+ o.type :bool
179
+ o.default false
180
+ end
181
+ end
157
182
  end
158
183
  end
159
184
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ Datadog::DI::Serializer.register(condition: lambda { |value| ActiveRecord::Base === value }) do |serializer, value, name:, depth:| # steep:ignore
4
+ # steep thinks all of the arguments are nil here
5
+ # steep:ignore:start
6
+ value_to_serialize = {
7
+ attributes: value.attributes,
8
+ }
9
+ serializer.serialize_value(value_to_serialize, depth: depth ? depth - 1 : nil, type: value.class)
10
+ # steep:ignore:end
11
+ end
@@ -26,6 +26,23 @@ module Datadog
26
26
  # that does not in fact exist anywhere (e.g. due to a misspelling).
27
27
  class DITargetNotDefined < Error
28
28
  end
29
+
30
+ # Raised when trying to install a probe whose installation failed
31
+ # earlier in the same process. This exception should contain the
32
+ # original exception report from initial installation attempt.
33
+ class ProbePreviouslyFailed < Error
34
+ end
35
+
36
+ # Raised when installing a line probe and multiple files match the
37
+ # specified path suffix.
38
+ # A probe must be installed into one file only, since UI only
39
+ # supports one instrumented location for a probe.
40
+ # If multiple files match, UI cannot properly render the data from
41
+ # all of them, and arbitrarily choosing one file may be not what the
42
+ # user intended. Instrumentation will fail when multiple files match
43
+ # and the user will need to make their suffix more precise.
44
+ class MultiplePathsMatch < Error
45
+ end
29
46
  end
30
47
  end
31
48
  end