datadog 2.0.0.beta1 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +181 -1
  3. data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +1 -1
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +40 -32
  5. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +23 -12
  6. data/ext/datadog_profiling_native_extension/crashtracker.c +108 -0
  7. data/ext/datadog_profiling_native_extension/extconf.rb +9 -23
  8. data/ext/datadog_profiling_native_extension/heap_recorder.c +81 -4
  9. data/ext/datadog_profiling_native_extension/heap_recorder.h +12 -1
  10. data/ext/datadog_profiling_native_extension/http_transport.c +1 -94
  11. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +86 -0
  12. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +4 -0
  13. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +2 -12
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +25 -86
  15. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  16. data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -5
  17. data/ext/datadog_profiling_native_extension/stack_recorder.c +161 -62
  18. data/lib/datadog/appsec/contrib/devise/tracking.rb +8 -0
  19. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +43 -13
  20. data/lib/datadog/appsec/event.rb +2 -2
  21. data/lib/datadog/core/configuration/components.rb +2 -1
  22. data/lib/datadog/core/configuration/option.rb +7 -5
  23. data/lib/datadog/core/configuration/settings.rb +34 -79
  24. data/lib/datadog/core/configuration.rb +20 -4
  25. data/lib/datadog/core/environment/platform.rb +7 -1
  26. data/lib/datadog/core/remote/client/capabilities.rb +2 -1
  27. data/lib/datadog/core/remote/client.rb +1 -5
  28. data/lib/datadog/core/remote/configuration/repository.rb +1 -1
  29. data/lib/datadog/core/remote/dispatcher.rb +3 -3
  30. data/lib/datadog/core/remote/transport/http/config.rb +5 -5
  31. data/lib/datadog/core/telemetry/client.rb +18 -10
  32. data/lib/datadog/core/telemetry/emitter.rb +9 -13
  33. data/lib/datadog/core/telemetry/event.rb +247 -57
  34. data/lib/datadog/core/telemetry/ext.rb +1 -0
  35. data/lib/datadog/core/telemetry/heartbeat.rb +1 -3
  36. data/lib/datadog/core/telemetry/http/ext.rb +4 -1
  37. data/lib/datadog/core/telemetry/http/response.rb +4 -0
  38. data/lib/datadog/core/telemetry/http/transport.rb +9 -4
  39. data/lib/datadog/core/telemetry/request.rb +59 -0
  40. data/lib/datadog/core/utils/base64.rb +22 -0
  41. data/lib/datadog/opentelemetry/sdk/span_processor.rb +19 -2
  42. data/lib/datadog/opentelemetry/sdk/trace/span.rb +3 -17
  43. data/lib/datadog/profiling/collectors/code_provenance.rb +10 -4
  44. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +25 -0
  45. data/lib/datadog/profiling/component.rb +49 -17
  46. data/lib/datadog/profiling/crashtracker.rb +91 -0
  47. data/lib/datadog/profiling/exporter.rb +6 -3
  48. data/lib/datadog/profiling/http_transport.rb +7 -11
  49. data/lib/datadog/profiling/load_native_extension.rb +14 -1
  50. data/lib/datadog/profiling/profiler.rb +9 -2
  51. data/lib/datadog/profiling/stack_recorder.rb +6 -2
  52. data/lib/datadog/profiling.rb +12 -0
  53. data/lib/datadog/tracing/component.rb +5 -1
  54. data/lib/datadog/tracing/configuration/dynamic.rb +39 -1
  55. data/lib/datadog/tracing/configuration/settings.rb +1 -0
  56. data/lib/datadog/tracing/contrib/action_pack/integration.rb +1 -1
  57. data/lib/datadog/tracing/contrib/action_view/integration.rb +1 -1
  58. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -0
  59. data/lib/datadog/tracing/contrib/active_record/integration.rb +11 -1
  60. data/lib/datadog/tracing/contrib/active_support/integration.rb +1 -1
  61. data/lib/datadog/tracing/contrib/configuration/resolver.rb +43 -0
  62. data/lib/datadog/tracing/contrib/grape/endpoint.rb +43 -5
  63. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +1 -1
  64. data/lib/datadog/tracing/correlation.rb +3 -4
  65. data/lib/datadog/tracing/remote.rb +5 -1
  66. data/lib/datadog/tracing/sampling/ext.rb +5 -1
  67. data/lib/datadog/tracing/sampling/matcher.rb +75 -26
  68. data/lib/datadog/tracing/sampling/rule.rb +27 -4
  69. data/lib/datadog/tracing/sampling/rule_sampler.rb +19 -1
  70. data/lib/datadog/tracing/sampling/span/matcher.rb +13 -41
  71. data/lib/datadog/tracing/span.rb +7 -2
  72. data/lib/datadog/tracing/span_link.rb +92 -0
  73. data/lib/datadog/tracing/span_operation.rb +6 -4
  74. data/lib/datadog/tracing/trace_operation.rb +12 -0
  75. data/lib/datadog/tracing/tracer.rb +4 -3
  76. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  77. data/lib/datadog/tracing/utils.rb +16 -0
  78. data/lib/datadog/version.rb +1 -1
  79. metadata +10 -31
  80. data/lib/datadog/core/telemetry/collector.rb +0 -248
  81. data/lib/datadog/core/telemetry/v1/app_event.rb +0 -59
  82. data/lib/datadog/core/telemetry/v1/application.rb +0 -94
  83. data/lib/datadog/core/telemetry/v1/configuration.rb +0 -27
  84. data/lib/datadog/core/telemetry/v1/dependency.rb +0 -45
  85. data/lib/datadog/core/telemetry/v1/host.rb +0 -59
  86. data/lib/datadog/core/telemetry/v1/install_signature.rb +0 -38
  87. data/lib/datadog/core/telemetry/v1/integration.rb +0 -66
  88. data/lib/datadog/core/telemetry/v1/product.rb +0 -36
  89. data/lib/datadog/core/telemetry/v1/telemetry_request.rb +0 -108
  90. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +0 -41
  91. data/lib/datadog/core/telemetry/v2/request.rb +0 -29
@@ -129,12 +129,7 @@ bool is_current_thread_holding_the_gvl(void) {
129
129
  }
130
130
  #else
131
131
  current_gvl_owner gvl_owner(void) {
132
- rb_vm_t *vm =
133
- #ifndef NO_GET_VM
134
- GET_VM();
135
- #else
136
- thread_struct_from_object(rb_thread_current())->vm;
137
- #endif
132
+ rb_vm_t *vm = GET_VM();
138
133
 
139
134
  // BIG Issue: Ruby < 2.6 did not have the owner field. The really nice thing about the owner field is that it's
140
135
  // "atomic" -- when a thread sets it, it "declares" two things in a single step
@@ -163,7 +158,7 @@ bool is_current_thread_holding_the_gvl(void) {
163
158
  //
164
159
  // Thus an incorrect `is_current_thread_holding_the_gvl` result may lead to issues inside `rb_postponed_job_register_one`.
165
160
  //
166
- // For this reason we currently do not enable the new Ruby profiler on Ruby 2.5 and below by default, and we print a
161
+ // For this reason we currently do not enable the new Ruby profiler on Ruby 2.5 by default, and we print a
167
162
  // warning when customers force-enable it.
168
163
  bool gvl_acquired = vm->gvl.acquired != 0;
169
164
  rb_thread_t *current_owner = vm->running_thread;
@@ -213,12 +208,7 @@ uint64_t native_thread_id_for(VALUE thread) {
213
208
  // Returns the stack depth by using the same approach as rb_profile_frames and backtrace_each: get the positions
214
209
  // of the end and current frame pointers and subtracting them.
215
210
  ptrdiff_t stack_depth_for(VALUE thread) {
216
- #ifndef USE_THREAD_INSTEAD_OF_EXECUTION_CONTEXT // Modern Rubies
217
- const rb_execution_context_t *ec = thread_struct_from_object(thread)->ec;
218
- #else // Ruby < 2.5
219
- const rb_thread_t *ec = thread_struct_from_object(thread);
220
- #endif
221
-
211
+ const rb_execution_context_t *ec = thread_struct_from_object(thread)->ec;
222
212
  const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
223
213
 
224
214
  if (end_cfp == NULL) return 0;
@@ -253,12 +243,7 @@ void ddtrace_thread_list(VALUE result_array) {
253
243
  rb_ractor_t *current_ractor = ddtrace_get_ractor();
254
244
  ccan_list_for_each(&current_ractor->threads.set, thread, lt_node) {
255
245
  #else
256
- rb_vm_t *vm =
257
- #ifndef NO_GET_VM
258
- GET_VM();
259
- #else
260
- thread_struct_from_object(rb_thread_current())->vm;
261
- #endif
246
+ rb_vm_t *vm = GET_VM();
262
247
  list_for_each(&vm->living_threads, thread, vmlt_node) {
263
248
  #endif
264
249
  switch (thread->status) {
@@ -394,13 +379,6 @@ calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
394
379
  // * Add thread argument
395
380
  // * Add is_ruby_frame argument
396
381
  // * Removed `if (lines)` tests -- require/assume that like `buff`, `lines` is always specified
397
- // * Support Ruby < 2.5 by using rb_thread_t instead of rb_execution_context_t (which did not exist and was just
398
- // part of rb_thread_t)
399
- // * Support Ruby < 2.4 by using `RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)` instead of `VM_FRAME_RUBYFRAME_P(cfp)`.
400
- // Given that the Ruby 2.3 version of `rb_profile_frames` did not support native methods and thus did not need this
401
- // check, how did I figure out what to replace it with? I did it by looking at other places in the VM code where the
402
- // code looks exactly the same but Ruby 2.4 uses `VM_FRAME_RUBYFRAME_P` whereas Ruby 2.3 used `RUBY_VM_NORMAL_ISEQ_P`.
403
- // Examples of these are `errinfo_place` in `eval.c`, `rb_vm_get_ruby_level_next_cfp` (among others) in `vm.c`, etc.
404
382
  // * Skip dummy frame that shows up in main thread
405
383
  // * Add `end_cfp == NULL` and `end_cfp <= cfp` safety checks. These are used in a bunch of places in
406
384
  // `vm_backtrace.c` (`backtrace_each`, `backtrace_size`, `rb_ec_partial_backtrace_object`) but are conspicuously
@@ -449,11 +427,7 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, VALUE *buff, i
449
427
  // Modified from upstream: Instead of using `GET_EC` to collect info from the current thread,
450
428
  // support sampling any thread (including the current) passed as an argument
451
429
  rb_thread_t *th = thread_struct_from_object(thread);
452
- #ifndef USE_THREAD_INSTEAD_OF_EXECUTION_CONTEXT // Modern Rubies
453
- const rb_execution_context_t *ec = th->ec;
454
- #else // Ruby < 2.5
455
- const rb_thread_t *ec = th;
456
- #endif
430
+ const rb_execution_context_t *ec = th->ec;
457
431
  const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
458
432
  #ifndef NO_JIT_RETURN
459
433
  const rb_control_frame_t *top = cfp;
@@ -499,11 +473,7 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, VALUE *buff, i
499
473
  // rb_profile_frames does not do this check, but `backtrace_each` (`vm_backtrace.c`) does. This frame is not
500
474
  // exposed by the Ruby backtrace APIs and for now we want to match its behavior 1:1
501
475
  }
502
- #ifndef USE_ISEQ_P_INSTEAD_OF_RUBYFRAME_P // Modern Rubies
503
476
  else if (VM_FRAME_RUBYFRAME_P(cfp)) {
504
- #else // Ruby < 2.4
505
- else if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
506
- #endif
507
477
  if (start > 0) {
508
478
  start--;
509
479
  continue;
@@ -719,51 +689,27 @@ check_method_entry(VALUE obj, int can_be_svar)
719
689
  }
720
690
  }
721
691
 
722
- #ifndef USE_LEGACY_RB_VM_FRAME_METHOD_ENTRY
723
- // Taken from upstream vm_insnhelper.c at commit 5f10bd634fb6ae8f74a4ea730176233b0ca96954 (March 2022, Ruby 3.2 trunk)
724
- // Copyright (C) 2007 Koichi Sasada
725
- // to support our custom rb_profile_frames (see above)
726
- //
727
- // While older Rubies may have this function, the symbol is not exported which leads to dynamic loader issues, e.g.
728
- // `dyld: lazy symbol binding failed: Symbol not found: _rb_vm_frame_method_entry`.
729
- //
730
- // Modifications: None
731
- MJIT_STATIC const rb_callable_method_entry_t *
732
- rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
733
- {
734
- const VALUE *ep = cfp->ep;
735
- rb_callable_method_entry_t *me;
736
-
737
- while (!VM_ENV_LOCAL_P(ep)) {
738
- if ((me = check_method_entry(ep[VM_ENV_DATA_INDEX_ME_CREF], FALSE)) != NULL) return me;
739
- ep = VM_ENV_PREV_EP(ep);
740
- }
741
-
742
- return check_method_entry(ep[VM_ENV_DATA_INDEX_ME_CREF], TRUE);
743
- }
744
- #else
745
- // Taken from upstream vm_insnhelper.c at commit 556e9f726e2b80f6088982c6b43abfe68bfad591 (October 2018, ruby_2_3 branch)
746
- // Copyright (C) 2007 Koichi Sasada
747
- // to support our custom rb_profile_frames (see above)
748
- //
749
- // Quite a few macros in this function changed after Ruby 2.3. Rather than trying to fix the Ruby 3.2 version to work
750
- // with 2.3 constants, I decided to import the Ruby 2.3 version.
751
- //
752
- // Modifications: None
753
- const rb_callable_method_entry_t *
754
- rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
755
- {
756
- VALUE *ep = cfp->ep;
757
- rb_callable_method_entry_t *me;
692
+ // Taken from upstream vm_insnhelper.c at commit 5f10bd634fb6ae8f74a4ea730176233b0ca96954 (March 2022, Ruby 3.2 trunk)
693
+ // Copyright (C) 2007 Koichi Sasada
694
+ // to support our custom rb_profile_frames (see above)
695
+ //
696
+ // While older Rubies may have this function, the symbol is not exported which leads to dynamic loader issues, e.g.
697
+ // `dyld: lazy symbol binding failed: Symbol not found: _rb_vm_frame_method_entry`.
698
+ //
699
+ // Modifications: None
700
+ MJIT_STATIC const rb_callable_method_entry_t *
701
+ rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
702
+ {
703
+ const VALUE *ep = cfp->ep;
704
+ rb_callable_method_entry_t *me;
758
705
 
759
- while (!VM_EP_LEP_P(ep)) {
760
- if ((me = check_method_entry(ep[-1], FALSE)) != NULL) return me;
761
- ep = VM_EP_PREV_EP(ep);
762
- }
706
+ while (!VM_ENV_LOCAL_P(ep)) {
707
+ if ((me = check_method_entry(ep[VM_ENV_DATA_INDEX_ME_CREF], FALSE)) != NULL) return me;
708
+ ep = VM_ENV_PREV_EP(ep);
709
+ }
763
710
 
764
- return check_method_entry(ep[-1], TRUE);
765
- }
766
- #endif // USE_LEGACY_RB_VM_FRAME_METHOD_ENTRY
711
+ return check_method_entry(ep[VM_ENV_DATA_INDEX_ME_CREF], TRUE);
712
+ }
767
713
  #endif // RUBY_MJIT_HEADER
768
714
 
769
715
  #ifndef NO_RACTORS
@@ -880,13 +826,6 @@ static inline int ddtrace_imemo_type(VALUE imemo) {
880
826
  // This is used to workaround a VM bug. See "handle_sampling_signal" in "collectors_cpu_and_wall_time_worker" for details.
881
827
  #ifdef NO_POSTPONED_TRIGGER
882
828
  void *objspace_ptr_for_gc_finalize_deferred_workaround(void) {
883
- rb_vm_t *vm =
884
- #ifndef NO_GET_VM // TODO: Inline GET_VM below once we drop support in dd-trace-rb 2.x for < Ruby 2.5
885
- GET_VM();
886
- #else
887
- thread_struct_from_object(rb_thread_current())->vm;
888
- #endif
889
-
890
- return vm->objspace;
829
+ return GET_VM()->objspace;
891
830
  }
892
831
  #endif
@@ -19,6 +19,7 @@ void collectors_dynamic_sampling_rate_init(VALUE profiling_module);
19
19
  void collectors_idle_sampling_helper_init(VALUE profiling_module);
20
20
  void collectors_stack_init(VALUE profiling_module);
21
21
  void collectors_thread_context_init(VALUE profiling_module);
22
+ void crashtracker_init(VALUE profiling_module);
22
23
  void http_transport_init(VALUE profiling_module);
23
24
  void stack_recorder_init(VALUE profiling_module);
24
25
 
@@ -53,6 +54,7 @@ void DDTRACE_EXPORT Init_datadog_profiling_native_extension(void) {
53
54
  collectors_idle_sampling_helper_init(profiling_module);
54
55
  collectors_stack_init(profiling_module);
55
56
  collectors_thread_context_init(profiling_module);
57
+ crashtracker_init(profiling_module);
56
58
  http_transport_init(profiling_module);
57
59
  stack_recorder_init(profiling_module);
58
60
 
@@ -16,11 +16,6 @@ static inline VALUE process_pending_interruptions(DDTRACE_UNUSED VALUE _) {
16
16
  return Qnil;
17
17
  }
18
18
 
19
- // RB_UNLIKELY is not supported on Ruby 2.3
20
- #ifndef RB_UNLIKELY
21
- #define RB_UNLIKELY(x) x
22
- #endif
23
-
24
19
  // Calls process_pending_interruptions BUT "rescues" any exceptions to be raised, returning them instead as
25
20
  // a non-zero `pending_exception`.
26
21
  //
@@ -82,6 +77,9 @@ NORETURN(
82
77
  #define ENFORCE_SUCCESS_HELPER(expression, have_gvl) \
83
78
  { int result_syserr_errno = expression; if (RB_UNLIKELY(result_syserr_errno)) raise_syserr(result_syserr_errno, have_gvl, ADD_QUOTES(expression), __FILE__, __LINE__, __func__); }
84
79
 
80
+ #define RUBY_NUM_OR_NIL(val, condition, conv) ((val condition) ? conv(val) : Qnil)
81
+ #define RUBY_AVG_OR_NIL(total, count) ((count == 0) ? Qnil : DBL2NUM(((double) total) / count))
82
+
85
83
  // Called by ENFORCE_SUCCESS_HELPER; should not be used directly
86
84
  NORETURN(void raise_syserr(
87
85
  int syserr_errno,