ddtrace 1.0.0 → 1.1.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 (122) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -16
  3. data/CHANGELOG.md +31 -2
  4. data/LICENSE-3rdparty.csv +3 -2
  5. data/README.md +2 -2
  6. data/ddtrace.gemspec +12 -3
  7. data/docs/GettingStarted.md +19 -2
  8. data/docs/ProfilingDevelopment.md +8 -8
  9. data/docs/UpgradeGuide.md +3 -3
  10. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +118 -0
  11. data/ext/ddtrace_profiling_loader/extconf.rb +53 -0
  12. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +31 -5
  13. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +0 -8
  14. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +278 -0
  15. data/ext/ddtrace_profiling_native_extension/extconf.rb +70 -100
  16. data/ext/ddtrace_profiling_native_extension/libddprof_helpers.h +13 -0
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +186 -0
  18. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +579 -7
  19. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +30 -0
  20. data/ext/ddtrace_profiling_native_extension/profiling.c +7 -0
  21. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +139 -0
  22. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +28 -0
  23. data/lib/datadog/appsec/autoload.rb +2 -2
  24. data/lib/datadog/appsec/configuration/settings.rb +19 -0
  25. data/lib/datadog/appsec/configuration.rb +8 -0
  26. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +76 -33
  27. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -0
  28. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -1
  29. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +64 -0
  30. data/lib/datadog/appsec/contrib/rack/request.rb +6 -0
  31. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +41 -0
  32. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +60 -5
  33. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +81 -0
  34. data/lib/datadog/appsec/contrib/rails/patcher.rb +34 -1
  35. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +68 -0
  36. data/lib/datadog/appsec/contrib/rails/request.rb +33 -0
  37. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +124 -0
  38. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +69 -2
  39. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +63 -0
  40. data/lib/datadog/appsec/event.rb +33 -18
  41. data/lib/datadog/appsec/extensions.rb +0 -3
  42. data/lib/datadog/appsec/processor.rb +45 -2
  43. data/lib/datadog/appsec/rate_limiter.rb +5 -0
  44. data/lib/datadog/appsec/reactive/operation.rb +0 -1
  45. data/lib/datadog/ci/ext/environment.rb +21 -7
  46. data/lib/datadog/core/configuration/agent_settings_resolver.rb +1 -1
  47. data/lib/datadog/core/configuration/components.rb +22 -4
  48. data/lib/datadog/core/configuration/settings.rb +3 -3
  49. data/lib/datadog/core/configuration.rb +7 -5
  50. data/lib/datadog/core/environment/cgroup.rb +3 -1
  51. data/lib/datadog/core/environment/container.rb +2 -1
  52. data/lib/datadog/core/environment/variable_helpers.rb +26 -2
  53. data/lib/datadog/core/logging/ext.rb +11 -0
  54. data/lib/datadog/core/metrics/client.rb +15 -5
  55. data/lib/datadog/core/runtime/metrics.rb +1 -1
  56. data/lib/datadog/core/workers/async.rb +3 -1
  57. data/lib/datadog/core/workers/runtime_metrics.rb +0 -3
  58. data/lib/datadog/core.rb +6 -0
  59. data/lib/datadog/kit/enable_core_dumps.rb +50 -0
  60. data/lib/datadog/kit/identity.rb +63 -0
  61. data/lib/datadog/kit.rb +11 -0
  62. data/lib/datadog/opentracer/tracer.rb +0 -2
  63. data/lib/datadog/profiling/collectors/old_stack.rb +298 -0
  64. data/lib/datadog/profiling/collectors/stack.rb +6 -287
  65. data/lib/datadog/profiling/encoding/profile.rb +0 -1
  66. data/lib/datadog/profiling/ext.rb +1 -1
  67. data/lib/datadog/profiling/flush.rb +1 -1
  68. data/lib/datadog/profiling/load_native_extension.rb +22 -0
  69. data/lib/datadog/profiling/recorder.rb +1 -1
  70. data/lib/datadog/profiling/scheduler.rb +1 -1
  71. data/lib/datadog/profiling/stack_recorder.rb +33 -0
  72. data/lib/datadog/profiling/tag_builder.rb +48 -0
  73. data/lib/datadog/profiling/tasks/exec.rb +2 -2
  74. data/lib/datadog/profiling/tasks/setup.rb +6 -4
  75. data/lib/datadog/profiling.rb +29 -27
  76. data/lib/datadog/tracing/buffer.rb +9 -3
  77. data/lib/datadog/tracing/contrib/action_view/patcher.rb +0 -1
  78. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
  79. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  80. data/lib/datadog/tracing/contrib/active_record/vendor/connection_specification.rb +1 -1
  81. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +4 -2
  82. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +10 -3
  83. data/lib/datadog/tracing/contrib/dalli/patcher.rb +0 -1
  84. data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +0 -1
  85. data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +9 -3
  86. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +38 -2
  87. data/lib/datadog/tracing/contrib/ethon/patcher.rb +0 -1
  88. data/lib/datadog/tracing/contrib/extensions.rb +0 -2
  89. data/lib/datadog/tracing/contrib/faraday/patcher.rb +0 -1
  90. data/lib/datadog/tracing/contrib/grape/patcher.rb +0 -1
  91. data/lib/datadog/tracing/contrib/graphql/patcher.rb +0 -1
  92. data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -1
  93. data/lib/datadog/tracing/contrib/kafka/patcher.rb +0 -1
  94. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -1
  95. data/lib/datadog/tracing/contrib/qless/patcher.rb +0 -1
  96. data/lib/datadog/tracing/contrib/que/patcher.rb +0 -1
  97. data/lib/datadog/tracing/contrib/racecar/patcher.rb +0 -1
  98. data/lib/datadog/tracing/contrib/rails/log_injection.rb +3 -16
  99. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
  100. data/lib/datadog/tracing/contrib/rake/patcher.rb +0 -1
  101. data/lib/datadog/tracing/contrib/redis/patcher.rb +0 -1
  102. data/lib/datadog/tracing/contrib/resque/patcher.rb +0 -1
  103. data/lib/datadog/tracing/contrib/rest_client/patcher.rb +0 -1
  104. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +2 -1
  105. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
  106. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +20 -1
  107. data/lib/datadog/tracing/contrib/sinatra/framework.rb +11 -0
  108. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +0 -1
  109. data/lib/datadog/tracing/contrib/sneakers/patcher.rb +0 -1
  110. data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +0 -1
  111. data/lib/datadog/tracing/event.rb +2 -1
  112. data/lib/datadog/tracing/sampling/priority_sampler.rb +4 -5
  113. data/lib/datadog/tracing/sampling/rule.rb +12 -6
  114. data/lib/datadog/tracing/sampling/rule_sampler.rb +3 -5
  115. data/lib/datadog/tracing/span_operation.rb +2 -3
  116. data/lib/datadog/tracing/trace_operation.rb +0 -1
  117. data/lib/ddtrace/transport/http/client.rb +2 -1
  118. data/lib/ddtrace/transport/http/response.rb +34 -4
  119. data/lib/ddtrace/transport/io/client.rb +3 -1
  120. data/lib/ddtrace/version.rb +1 -1
  121. data/lib/ddtrace.rb +1 -0
  122. metadata +43 -6
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ # typed: ignore
4
+
5
+ require 'libddprof'
6
+
7
+ module Datadog
8
+ module Profiling
9
+ module NativeExtensionHelpers
10
+ ENV_NO_EXTENSION = 'DD_PROFILING_NO_EXTENSION'
11
+
12
+ # Older Rubies don't have the MJIT header, used by the JIT compiler, so we need to use a different approach
13
+ CAN_USE_MJIT_HEADER = RUBY_VERSION >= '2.6'
14
+
15
+ # Used to check if profiler is supported, including user-visible clear messages explaining why their
16
+ # system may not be supported.
17
+ # rubocop:disable Metrics/ModuleLength
18
+ module Supported
19
+ private_class_method def self.explain_issue(*reason, suggested:)
20
+ { reason: reason, suggested: suggested }
21
+ end
22
+
23
+ def self.supported?
24
+ unsupported_reason.nil?
25
+ end
26
+
27
+ def self.unsupported_reason
28
+ disabled_via_env? ||
29
+ on_jruby? ||
30
+ on_truffleruby? ||
31
+ on_windows? ||
32
+ on_macos? ||
33
+ on_unknown_os? ||
34
+ not_on_amd64_or_arm64? ||
35
+ expected_to_use_mjit_but_mjit_is_disabled? ||
36
+ libddprof_not_usable?
37
+ end
38
+
39
+ # This banner will show up in the logs/terminal while compiling the native extension
40
+ def self.failure_banner_for(reason:, suggested:)
41
+ prettify_lines = proc { |lines| lines.map { |line| "| #{line.ljust(76)} |" }.join("\n") }
42
+ %(
43
+ +------------------------------------------------------------------------------+
44
+ | Could not compile the Datadog Continuous Profiler because |
45
+ #{prettify_lines.call(reason)}
46
+ | |
47
+ | The Datadog Continuous Profiler will not be available, |
48
+ | but all other ddtrace features will work fine! |
49
+ | |
50
+ #{prettify_lines.call(suggested)}
51
+ +------------------------------------------------------------------------------+
52
+ )
53
+ end
54
+
55
+ # This will be saved in a file to later be presented while operating the gem
56
+ def self.render_skipped_reason_file(reason:, suggested:)
57
+ [*reason, *suggested].join(' ')
58
+ end
59
+
60
+ CONTACT_SUPPORT = [
61
+ 'For help solving this issue, please contact Datadog support at',
62
+ '<https://docs.datadoghq.com/help/>.',
63
+ ].freeze
64
+
65
+ REPORT_ISSUE = [
66
+ 'If you needed to use this, please tell us why on',
67
+ '<https://github.com/DataDog/dd-trace-rb/issues/new> so we can fix it :)',
68
+ ].freeze
69
+
70
+ GET_IN_TOUCH = [
71
+ "Get in touch with us if you're interested in profiling your app!"
72
+ ].freeze
73
+
74
+ # Validation for this check is done in extconf.rb because it relies on mkmf
75
+ FAILED_TO_CONFIGURE_LIBDDPROF = explain_issue(
76
+ 'there was a problem in setting up the `libddprof` dependency.',
77
+ suggested: CONTACT_SUPPORT,
78
+ )
79
+
80
+ # Validation for this check is done in extconf.rb because it relies on mkmf
81
+ COMPILATION_BROKEN = explain_issue(
82
+ 'compilation of the Ruby VM just-in-time header failed.',
83
+ 'Your C compiler or Ruby VM just-in-time compiler seem to be broken.',
84
+ suggested: CONTACT_SUPPORT,
85
+ )
86
+
87
+ private_class_method def self.disabled_via_env?
88
+ disabled_via_env = explain_issue(
89
+ 'the `DD_PROFILING_NO_EXTENSION` environment variable is/was set to',
90
+ '`true` during installation.',
91
+ suggested: REPORT_ISSUE,
92
+ )
93
+
94
+ return unless ENV[ENV_NO_EXTENSION].to_s.strip.downcase == 'true'
95
+
96
+ disabled_via_env
97
+ end
98
+
99
+ private_class_method def self.on_jruby?
100
+ jruby_not_supported = explain_issue(
101
+ 'JRuby is not supported by the Datadog Continuous Profiler.',
102
+ suggested: GET_IN_TOUCH,
103
+ )
104
+
105
+ jruby_not_supported if RUBY_ENGINE == 'jruby'
106
+ end
107
+
108
+ private_class_method def self.on_truffleruby?
109
+ truffleruby_not_supported = explain_issue(
110
+ 'TruffleRuby is not supported by the ddtrace gem.',
111
+ suggested: GET_IN_TOUCH,
112
+ )
113
+
114
+ truffleruby_not_supported if RUBY_ENGINE == 'truffleruby'
115
+ end
116
+
117
+ # See https://docs.datadoghq.com/tracing/setup_overview/setup/ruby/#microsoft-windows-support for current
118
+ # state of Windows support in ddtrace.
119
+ private_class_method def self.on_windows?
120
+ windows_not_supported = explain_issue(
121
+ 'Microsoft Windows is not supported by the Datadog Continuous Profiler.',
122
+ suggested: GET_IN_TOUCH,
123
+ )
124
+
125
+ windows_not_supported if Gem.win_platform?
126
+ end
127
+
128
+ private_class_method def self.on_macos?
129
+ macos_not_supported = explain_issue(
130
+ 'macOS is currently not supported by the Datadog Continuous Profiler.',
131
+ suggested: GET_IN_TOUCH,
132
+ )
133
+ # For development only; not supported otherwise
134
+ macos_testing_override = ENV['DD_PROFILING_MACOS_TESTING'] == 'true'
135
+
136
+ macos_not_supported if RUBY_PLATFORM.include?('darwin') && !macos_testing_override
137
+ end
138
+
139
+ private_class_method def self.on_unknown_os?
140
+ unknown_os_not_supported = explain_issue(
141
+ 'your operating system is not supported by the Datadog Continuous Profiler.',
142
+ suggested: GET_IN_TOUCH,
143
+ )
144
+
145
+ unknown_os_not_supported unless RUBY_PLATFORM.include?('darwin') || RUBY_PLATFORM.include?('linux')
146
+ end
147
+
148
+ private_class_method def self.not_on_amd64_or_arm64?
149
+ architecture_not_supported = explain_issue(
150
+ 'your CPU architecture is not supported by the Datadog Continuous Profiler.',
151
+ suggested: GET_IN_TOUCH,
152
+ )
153
+
154
+ architecture_not_supported unless RUBY_PLATFORM.start_with?('x86_64', 'aarch64')
155
+ end
156
+
157
+ # On some Rubies, we require the mjit header to be present. If Ruby was installed without MJIT support, we also skip
158
+ # building the extension.
159
+ private_class_method def self.expected_to_use_mjit_but_mjit_is_disabled?
160
+ ruby_without_mjit = explain_issue(
161
+ 'your Ruby has been compiled without JIT support (--disable-jit-support).',
162
+ 'The profiling native extension requires a Ruby compiled with JIT support,',
163
+ 'even if the JIT is not in use by the application itself.',
164
+ suggested: CONTACT_SUPPORT,
165
+ )
166
+
167
+ ruby_without_mjit if CAN_USE_MJIT_HEADER && RbConfig::CONFIG['MJIT_SUPPORT'] != 'yes'
168
+ end
169
+
170
+ private_class_method def self.libddprof_not_usable?
171
+ no_binaries_for_current_platform = explain_issue(
172
+ 'the `libddprof` gem installed on your system is missing binaries for your',
173
+ 'platform variant.',
174
+ "(Your platform: `#{Gem::Platform.local}`)",
175
+ '(Available binaries: ',
176
+ "`#{Libddprof.available_binaries.join('`, `')}`)",
177
+ suggested: CONTACT_SUPPORT,
178
+ )
179
+
180
+ no_binaries_for_current_platform unless Libddprof.pkgconfig_folder
181
+ end
182
+ end
183
+ # rubocop:enable Metrics/ModuleLength
184
+ end
185
+ end
186
+ end