ddtrace 1.14.0 → 1.16.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 (283) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +146 -2
  3. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +3 -5
  4. data/ext/ddtrace_profiling_native_extension/clock_id.h +0 -3
  5. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +0 -22
  6. data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +0 -1
  7. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +41 -6
  8. data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.c +3 -0
  9. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +76 -24
  10. data/ext/ddtrace_profiling_native_extension/collectors_stack.h +1 -1
  11. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +207 -32
  12. data/ext/ddtrace_profiling_native_extension/collectors_thread_context.h +1 -1
  13. data/ext/ddtrace_profiling_native_extension/extconf.rb +8 -2
  14. data/ext/ddtrace_profiling_native_extension/http_transport.c +26 -10
  15. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.c +42 -0
  16. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +6 -0
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +1 -16
  18. data/ext/ddtrace_profiling_native_extension/pid_controller.c +57 -0
  19. data/ext/ddtrace_profiling_native_extension/pid_controller.h +45 -0
  20. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +17 -12
  21. data/ext/ddtrace_profiling_native_extension/profiling.c +0 -2
  22. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +74 -37
  23. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +13 -3
  24. data/lib/datadog/appsec/assets/waf_rules/processors.json +92 -0
  25. data/lib/datadog/appsec/assets/waf_rules/recommended.json +698 -75
  26. data/lib/datadog/appsec/assets/waf_rules/scanners.json +114 -0
  27. data/lib/datadog/appsec/assets/waf_rules/strict.json +98 -8
  28. data/lib/datadog/appsec/assets.rb +8 -0
  29. data/lib/datadog/appsec/component.rb +9 -2
  30. data/lib/datadog/appsec/configuration/settings.rb +67 -2
  31. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +6 -2
  32. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +46 -0
  33. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +8 -6
  34. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +2 -7
  35. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +2 -5
  36. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +7 -5
  37. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +3 -2
  38. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +34 -10
  39. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -2
  40. data/lib/datadog/appsec/contrib/rails/patcher.rb +9 -3
  41. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +2 -5
  42. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -4
  43. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +13 -7
  44. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +2 -5
  45. data/lib/datadog/appsec/event.rb +106 -50
  46. data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -3
  47. data/lib/datadog/appsec/monitor/reactive/set_user.rb +2 -5
  48. data/lib/datadog/appsec/processor/actions.rb +49 -0
  49. data/lib/datadog/appsec/processor/rule_merger.rb +22 -2
  50. data/lib/datadog/appsec/processor.rb +34 -6
  51. data/lib/datadog/appsec/remote.rb +4 -1
  52. data/lib/datadog/appsec/response.rb +82 -4
  53. data/lib/datadog/appsec/sample_rate.rb +21 -0
  54. data/lib/datadog/appsec.rb +2 -2
  55. data/lib/datadog/core/configuration/agent_settings_resolver.rb +29 -24
  56. data/lib/datadog/core/configuration/base.rb +1 -11
  57. data/lib/datadog/core/configuration/components.rb +7 -2
  58. data/lib/datadog/core/configuration/ext.rb +21 -0
  59. data/lib/datadog/core/configuration/option.rb +2 -4
  60. data/lib/datadog/core/configuration/option_definition.rb +17 -41
  61. data/lib/datadog/core/configuration/options.rb +5 -5
  62. data/lib/datadog/core/configuration/settings.rb +47 -45
  63. data/lib/datadog/core/environment/execution.rb +47 -9
  64. data/lib/datadog/core/environment/variable_helpers.rb +0 -69
  65. data/lib/datadog/core/error.rb +1 -0
  66. data/lib/datadog/core/git/ext.rb +2 -0
  67. data/lib/datadog/core/remote/client/capabilities.rb +1 -1
  68. data/lib/datadog/core/remote/component.rb +2 -2
  69. data/lib/datadog/core/remote/negotiation.rb +2 -2
  70. data/lib/datadog/core/remote/transport/config.rb +60 -0
  71. data/lib/datadog/core/remote/transport/http/api/instance.rb +39 -0
  72. data/lib/datadog/core/remote/transport/http/api/spec.rb +21 -0
  73. data/lib/datadog/core/remote/transport/http/api.rb +58 -0
  74. data/lib/datadog/core/remote/transport/http/builder.rb +219 -0
  75. data/lib/datadog/core/remote/transport/http/client.rb +48 -0
  76. data/lib/datadog/core/remote/transport/http/config.rb +280 -0
  77. data/lib/datadog/core/remote/transport/http/negotiation.rb +146 -0
  78. data/lib/datadog/core/remote/transport/http.rb +179 -0
  79. data/lib/datadog/core/{transport → remote/transport}/negotiation.rb +25 -23
  80. data/lib/datadog/core/remote/worker.rb +3 -1
  81. data/lib/datadog/core/telemetry/collector.rb +3 -2
  82. data/lib/datadog/core/telemetry/http/transport.rb +2 -1
  83. data/lib/datadog/core/transport/ext.rb +47 -0
  84. data/lib/datadog/core/transport/http/adapters/net.rb +168 -0
  85. data/lib/datadog/core/transport/http/adapters/registry.rb +29 -0
  86. data/lib/datadog/core/transport/http/adapters/test.rb +89 -0
  87. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +83 -0
  88. data/lib/datadog/core/transport/http/api/endpoint.rb +31 -0
  89. data/lib/datadog/core/transport/http/api/fallbacks.rb +26 -0
  90. data/lib/datadog/core/transport/http/api/map.rb +18 -0
  91. data/lib/datadog/core/transport/http/env.rb +62 -0
  92. data/lib/datadog/core/transport/http/response.rb +60 -0
  93. data/lib/datadog/core/transport/parcel.rb +22 -0
  94. data/lib/datadog/core/transport/request.rb +17 -0
  95. data/lib/datadog/core/transport/response.rb +64 -0
  96. data/lib/datadog/core/workers/polling.rb +2 -2
  97. data/lib/datadog/opentelemetry/api/context.rb +10 -3
  98. data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -1
  99. data/lib/datadog/opentelemetry/sdk/span_processor.rb +14 -2
  100. data/lib/datadog/opentelemetry/sdk/trace/span.rb +68 -0
  101. data/lib/datadog/opentelemetry/trace.rb +58 -0
  102. data/lib/datadog/opentelemetry.rb +1 -0
  103. data/lib/datadog/opentracer.rb +9 -0
  104. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +14 -19
  105. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
  106. data/lib/datadog/profiling/collectors/thread_context.rb +9 -1
  107. data/lib/datadog/profiling/component.rb +24 -99
  108. data/lib/datadog/profiling/ext.rb +0 -12
  109. data/lib/datadog/profiling/flush.rb +0 -3
  110. data/lib/datadog/profiling/http_transport.rb +6 -3
  111. data/lib/datadog/profiling/native_extension.rb +0 -21
  112. data/lib/datadog/profiling/profiler.rb +36 -13
  113. data/lib/datadog/profiling/scheduler.rb +16 -9
  114. data/lib/datadog/profiling.rb +8 -81
  115. data/lib/datadog/tracing/component.rb +10 -4
  116. data/lib/datadog/tracing/configuration/agent_settings_resolver.rb +13 -0
  117. data/lib/datadog/tracing/configuration/ext.rb +4 -2
  118. data/lib/datadog/tracing/configuration/settings.rb +14 -7
  119. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +1 -1
  120. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +1 -1
  121. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +4 -0
  122. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +106 -197
  123. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +3 -0
  124. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +7 -0
  125. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +14 -14
  126. data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +3 -10
  127. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +2 -1
  128. data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +8 -1
  129. data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +22 -0
  130. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  131. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +6 -0
  132. data/lib/datadog/tracing/contrib/dalli/ext.rb +7 -0
  133. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +9 -2
  134. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +1 -1
  135. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +5 -0
  136. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +5 -0
  137. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +8 -0
  138. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -0
  139. data/lib/datadog/tracing/contrib/ext.rb +3 -0
  140. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +1 -1
  141. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -0
  142. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +21 -1
  143. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +11 -1
  144. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +18 -0
  145. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +0 -4
  146. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +3 -3
  147. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -0
  148. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -0
  149. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +5 -0
  150. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +7 -0
  151. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +13 -3
  152. data/lib/datadog/tracing/contrib/opensearch/integration.rb +2 -2
  153. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +7 -0
  154. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +5 -0
  155. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +5 -0
  156. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
  157. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +1 -1
  158. data/lib/datadog/tracing/contrib/racecar/event.rb +5 -0
  159. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +14 -4
  160. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +4 -4
  161. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +1 -1
  162. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +1 -1
  163. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +3 -38
  164. data/lib/datadog/tracing/contrib/redis/tags.rb +7 -2
  165. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +46 -33
  166. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +1 -1
  167. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -0
  168. data/lib/datadog/tracing/contrib/sequel/utils.rb +5 -0
  169. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +1 -1
  170. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -1
  171. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -1
  172. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +2 -2
  173. data/lib/datadog/tracing/diagnostics/environment_logger.rb +6 -0
  174. data/lib/datadog/tracing/distributed/propagation.rb +13 -33
  175. data/lib/datadog/tracing/metadata/tagging.rb +3 -3
  176. data/lib/datadog/tracing/sync_writer.rb +3 -3
  177. data/lib/datadog/tracing/tracer.rb +2 -0
  178. data/lib/datadog/{core → tracing}/transport/http/api/instance.rb +1 -1
  179. data/lib/datadog/{core → tracing}/transport/http/api/spec.rb +1 -1
  180. data/lib/datadog/tracing/transport/http/api.rb +43 -0
  181. data/lib/datadog/{core → tracing}/transport/http/builder.rb +13 -68
  182. data/lib/datadog/tracing/transport/http/client.rb +57 -0
  183. data/lib/datadog/tracing/transport/http/statistics.rb +47 -0
  184. data/lib/datadog/tracing/transport/http/traces.rb +152 -0
  185. data/lib/datadog/tracing/transport/http.rb +124 -0
  186. data/lib/datadog/tracing/transport/io/client.rb +89 -0
  187. data/lib/datadog/tracing/transport/io/response.rb +27 -0
  188. data/lib/datadog/tracing/transport/io/traces.rb +101 -0
  189. data/lib/datadog/tracing/transport/io.rb +30 -0
  190. data/lib/datadog/tracing/transport/serializable_trace.rb +126 -0
  191. data/lib/datadog/tracing/transport/statistics.rb +77 -0
  192. data/lib/datadog/tracing/transport/trace_formatter.rb +209 -0
  193. data/lib/datadog/tracing/transport/traces.rb +224 -0
  194. data/lib/datadog/tracing/workers/trace_writer.rb +5 -3
  195. data/lib/datadog/tracing/workers.rb +3 -2
  196. data/lib/datadog/tracing/writer.rb +5 -2
  197. data/lib/ddtrace/transport/ext.rb +17 -15
  198. data/lib/ddtrace/version.rb +1 -1
  199. data/lib/ddtrace.rb +1 -1
  200. metadata +73 -96
  201. data/lib/datadog/ci/configuration/components.rb +0 -32
  202. data/lib/datadog/ci/configuration/settings.rb +0 -51
  203. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +0 -35
  204. data/lib/datadog/ci/contrib/cucumber/ext.rb +0 -22
  205. data/lib/datadog/ci/contrib/cucumber/formatter.rb +0 -94
  206. data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +0 -28
  207. data/lib/datadog/ci/contrib/cucumber/integration.rb +0 -47
  208. data/lib/datadog/ci/contrib/cucumber/patcher.rb +0 -27
  209. data/lib/datadog/ci/contrib/minitest/configuration/settings.rb +0 -35
  210. data/lib/datadog/ci/contrib/minitest/ext.rb +0 -21
  211. data/lib/datadog/ci/contrib/minitest/integration.rb +0 -49
  212. data/lib/datadog/ci/contrib/minitest/patcher.rb +0 -27
  213. data/lib/datadog/ci/contrib/minitest/test_helper.rb +0 -68
  214. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +0 -35
  215. data/lib/datadog/ci/contrib/rspec/example.rb +0 -68
  216. data/lib/datadog/ci/contrib/rspec/ext.rb +0 -21
  217. data/lib/datadog/ci/contrib/rspec/integration.rb +0 -48
  218. data/lib/datadog/ci/contrib/rspec/patcher.rb +0 -27
  219. data/lib/datadog/ci/ext/app_types.rb +0 -9
  220. data/lib/datadog/ci/ext/environment.rb +0 -575
  221. data/lib/datadog/ci/ext/settings.rb +0 -10
  222. data/lib/datadog/ci/ext/test.rb +0 -35
  223. data/lib/datadog/ci/extensions.rb +0 -19
  224. data/lib/datadog/ci/flush.rb +0 -38
  225. data/lib/datadog/ci/test.rb +0 -81
  226. data/lib/datadog/ci.rb +0 -21
  227. data/lib/datadog/core/configuration/dependency_resolver.rb +0 -28
  228. data/lib/datadog/core/configuration/option_definition_set.rb +0 -22
  229. data/lib/datadog/core/configuration/option_set.rb +0 -10
  230. data/lib/datadog/core/transport/config.rb +0 -58
  231. data/lib/datadog/core/transport/http/api.rb +0 -57
  232. data/lib/datadog/core/transport/http/client.rb +0 -45
  233. data/lib/datadog/core/transport/http/config.rb +0 -278
  234. data/lib/datadog/core/transport/http/negotiation.rb +0 -144
  235. data/lib/datadog/core/transport/http.rb +0 -169
  236. data/lib/datadog/core/utils/object_set.rb +0 -43
  237. data/lib/datadog/core/utils/string_table.rb +0 -47
  238. data/lib/datadog/profiling/backtrace_location.rb +0 -34
  239. data/lib/datadog/profiling/buffer.rb +0 -43
  240. data/lib/datadog/profiling/collectors/old_stack.rb +0 -301
  241. data/lib/datadog/profiling/encoding/profile.rb +0 -41
  242. data/lib/datadog/profiling/event.rb +0 -15
  243. data/lib/datadog/profiling/events/stack.rb +0 -82
  244. data/lib/datadog/profiling/old_recorder.rb +0 -107
  245. data/lib/datadog/profiling/pprof/builder.rb +0 -125
  246. data/lib/datadog/profiling/pprof/converter.rb +0 -102
  247. data/lib/datadog/profiling/pprof/message_set.rb +0 -16
  248. data/lib/datadog/profiling/pprof/payload.rb +0 -20
  249. data/lib/datadog/profiling/pprof/pprof.proto +0 -212
  250. data/lib/datadog/profiling/pprof/pprof_pb.rb +0 -81
  251. data/lib/datadog/profiling/pprof/stack_sample.rb +0 -139
  252. data/lib/datadog/profiling/pprof/string_table.rb +0 -12
  253. data/lib/datadog/profiling/pprof/template.rb +0 -118
  254. data/lib/datadog/profiling/trace_identifiers/ddtrace.rb +0 -43
  255. data/lib/datadog/profiling/trace_identifiers/helper.rb +0 -45
  256. data/lib/ddtrace/transport/http/adapters/net.rb +0 -168
  257. data/lib/ddtrace/transport/http/adapters/registry.rb +0 -27
  258. data/lib/ddtrace/transport/http/adapters/test.rb +0 -85
  259. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +0 -77
  260. data/lib/ddtrace/transport/http/api/endpoint.rb +0 -29
  261. data/lib/ddtrace/transport/http/api/fallbacks.rb +0 -24
  262. data/lib/ddtrace/transport/http/api/instance.rb +0 -35
  263. data/lib/ddtrace/transport/http/api/map.rb +0 -16
  264. data/lib/ddtrace/transport/http/api/spec.rb +0 -17
  265. data/lib/ddtrace/transport/http/api.rb +0 -39
  266. data/lib/ddtrace/transport/http/builder.rb +0 -176
  267. data/lib/ddtrace/transport/http/client.rb +0 -52
  268. data/lib/ddtrace/transport/http/env.rb +0 -58
  269. data/lib/ddtrace/transport/http/response.rb +0 -58
  270. data/lib/ddtrace/transport/http/statistics.rb +0 -43
  271. data/lib/ddtrace/transport/http/traces.rb +0 -144
  272. data/lib/ddtrace/transport/http.rb +0 -117
  273. data/lib/ddtrace/transport/io/client.rb +0 -85
  274. data/lib/ddtrace/transport/io/response.rb +0 -25
  275. data/lib/ddtrace/transport/io/traces.rb +0 -99
  276. data/lib/ddtrace/transport/io.rb +0 -28
  277. data/lib/ddtrace/transport/parcel.rb +0 -20
  278. data/lib/ddtrace/transport/request.rb +0 -15
  279. data/lib/ddtrace/transport/response.rb +0 -60
  280. data/lib/ddtrace/transport/serializable_trace.rb +0 -122
  281. data/lib/ddtrace/transport/statistics.rb +0 -75
  282. data/lib/ddtrace/transport/trace_formatter.rb +0 -207
  283. data/lib/ddtrace/transport/traces.rb +0 -216
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright 2023 Datadog, Inc
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ // Originally imported from https://github.com/DataDog/java-profiler/blob/11fe6206c31a14c6e5134e8401eaec8b22c618d7/ddprof-lib/src/main/cpp/pidController.cpp
18
+
19
+ #include "pid_controller.h"
20
+
21
+ #include <math.h>
22
+
23
+ inline static double computeAlpha(float cutoff) {
24
+ if (cutoff <= 0)
25
+ return 1;
26
+ // α(fₙ) = cos(2πfₙ) - 1 + √( cos(2πfₙ)² - 4 cos(2πfₙ) + 3 )
27
+ const double c = cos(2 * ((double) M_PI) * cutoff);
28
+ return c - 1 + sqrt(c * c - 4 * c + 3);
29
+ }
30
+
31
+ void pid_controller_init(pid_controller *controller, u64 target_per_second, double proportional_gain, double integral_gain, double derivative_gain, int sampling_window, double cutoff_secs) {
32
+ controller->_target = target_per_second * sampling_window;
33
+ controller->_proportional_gain = proportional_gain;
34
+ controller->_integral_gain = integral_gain * sampling_window;
35
+ controller->_derivative_gain = derivative_gain / sampling_window;
36
+ controller->_alpha = computeAlpha(sampling_window / cutoff_secs);
37
+ controller->_avg_error= 0;
38
+ controller->_integral_value = 0;
39
+ }
40
+
41
+ double pid_controller_compute(pid_controller *controller, u64 input, double time_delta_coefficient) {
42
+ // time_delta_coefficient allows variable sampling window
43
+ // the values are linearly scaled using that coefficient to reinterpret the given value within the expected sampling window
44
+ double absolute_error = (((double) controller->_target) - ((double) input)) * time_delta_coefficient;
45
+
46
+ double avg_error = (controller->_alpha * absolute_error) + ((1 - controller->_alpha) * controller->_avg_error);
47
+ double derivative = avg_error - controller->_avg_error;
48
+
49
+ // PID formula:
50
+ // u[k] = Kp e[k] + Ki e_i[k] + Kd e_d[k], control signal
51
+ double signal = controller->_proportional_gain * absolute_error + controller->_integral_gain * controller->_integral_value + controller->_derivative_gain * derivative;
52
+
53
+ controller->_integral_value += absolute_error;
54
+ controller->_avg_error = avg_error;
55
+
56
+ return signal;
57
+ }
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Copyright 2023 Datadog, Inc
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ // Originally imported from https://github.com/DataDog/java-profiler/blob/11fe6206c31a14c6e5134e8401eaec8b22c618d7/ddprof-lib/src/main/cpp/pidController.h
18
+
19
+ #ifndef _PIDCONTROLLER_H
20
+ #define _PIDCONTROLLER_H
21
+
22
+ // From arch.h in java-profiler
23
+ typedef unsigned long long u64;
24
+
25
+ /*
26
+ * A simple implementation of a PID controller.
27
+ * Heavily influenced by https://tttapa.github.io/Pages/Arduino/Control-Theory/Motor-Fader/PID-Cpp-Implementation.html
28
+ */
29
+
30
+ typedef struct {
31
+ u64 _target;
32
+ double _proportional_gain;
33
+ double _derivative_gain;
34
+ double _integral_gain;
35
+ double _alpha;
36
+
37
+ double _avg_error;
38
+ long long _integral_value;
39
+ } pid_controller;
40
+
41
+ void pid_controller_init(pid_controller *controller, u64 target_per_second, double proportional_gain, double integral_gain, double derivative_gain, int sampling_window, double cutoff_secs);
42
+
43
+ double pid_controller_compute(pid_controller *controller, u64 input, double time_delta_seconds);
44
+
45
+ #endif
@@ -82,6 +82,16 @@ bool is_current_thread_holding_the_gvl(void) {
82
82
  return owner.valid && pthread_equal(pthread_self(), owner.owner);
83
83
  }
84
84
 
85
+ #ifdef HAVE_RUBY_RACTOR_H
86
+ static inline rb_ractor_t *ddtrace_get_ractor(void) {
87
+ #ifndef USE_RACTOR_INTERNAL_APIS_DIRECTLY // Ruby >= 3.3
88
+ return thread_struct_from_object(rb_thread_current())->ractor;
89
+ #else
90
+ return GET_RACTOR();
91
+ #endif
92
+ }
93
+ #endif
94
+
85
95
  #ifndef NO_GVL_OWNER // Ruby < 2.6 doesn't have the owner/running field
86
96
  // NOTE: Reading the owner in this is a racy read, because we're not grabbing the lock that Ruby uses to protect it.
87
97
  //
@@ -94,9 +104,9 @@ bool is_current_thread_holding_the_gvl(void) {
94
104
  current_gvl_owner gvl_owner(void) {
95
105
  const rb_thread_t *current_owner =
96
106
  #ifndef NO_RB_THREAD_SCHED // Introduced in Ruby 3.2 as a replacement for struct rb_global_vm_lock_struct
97
- GET_RACTOR()->threads.sched.running;
107
+ ddtrace_get_ractor()->threads.sched.running;
98
108
  #elif HAVE_RUBY_RACTOR_H
99
- GET_RACTOR()->threads.gvl.owner;
109
+ ddtrace_get_ractor()->threads.gvl.owner;
100
110
  #else
101
111
  GET_VM()->gvl.owner;
102
112
  #endif
@@ -234,7 +244,7 @@ void ddtrace_thread_list(VALUE result_array) {
234
244
  // I suspect the design in `rb_ractor_thread_list` may be done that way to perhaps in the future expose it to be
235
245
  // called from a different Ractor, but I'm not sure...
236
246
  #ifdef HAVE_RUBY_RACTOR_H
237
- rb_ractor_t *current_ractor = GET_RACTOR();
247
+ rb_ractor_t *current_ractor = ddtrace_get_ractor();
238
248
  ccan_list_for_each(&current_ractor->threads.set, thread, lt_node) {
239
249
  #else
240
250
  rb_vm_t *vm =
@@ -736,15 +746,10 @@ check_method_entry(VALUE obj, int can_be_svar)
736
746
  // versions, so we need to do a bit more work.
737
747
  struct rb_ractor_struct *ruby_single_main_ractor = NULL;
738
748
 
739
- // Taken from upstream ractor.c at commit a1b01e7701f9fc370f8dff777aad6d39a2c5a3e3 (May 2023, Ruby 3.3.0-preview1)
740
- // to allow us to ensure that we're always operating on the main ractor (if Ruby has ractors)
741
- // Modifications:
742
- // * None
743
- bool rb_ractor_main_p_(void)
744
- {
745
- VM_ASSERT(rb_multi_ractor_p());
746
- rb_execution_context_t *ec = GET_EC();
747
- return rb_ec_ractor_ptr(ec) == rb_ec_vm_ptr(ec)->ractor.main_ractor;
749
+ // Alternative implementation of rb_ractor_main_p_ that avoids relying on non-public symbols
750
+ bool rb_ractor_main_p_(void) {
751
+ // We need to get the main ractor in a bit of a roundabout way, since Ruby >= 3.3 hid `GET_VM()`
752
+ return ddtrace_get_ractor() == thread_struct_from_object(rb_thread_current())->vm->ractor.main_ractor;
748
753
  }
749
754
  #else
750
755
  // Directly access Ruby internal fast path for detecting multiple Ractors.
@@ -41,8 +41,6 @@ void DDTRACE_EXPORT Init_ddtrace_profiling_native_extension(void) {
41
41
  rb_define_singleton_method(native_extension_module, "native_working?", native_working_p, 0);
42
42
  rb_funcall(native_extension_module, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("native_working?")));
43
43
 
44
- rb_define_singleton_method(native_extension_module, "clock_id_for", clock_id_for, 1); // from clock_id.h
45
-
46
44
  collectors_cpu_and_wall_time_worker_init(profiling_module);
47
45
  collectors_dynamic_sampling_rate_init(profiling_module);
48
46
  collectors_idle_sampling_helper_init(profiling_module);
@@ -165,10 +165,10 @@ static const uint8_t all_value_types_positions[] = {CPU_TIME_VALUE_ID, CPU_SAMPL
165
165
  // Contains native state for each instance
166
166
  struct stack_recorder_state {
167
167
  pthread_mutex_t slot_one_mutex;
168
- ddog_prof_Profile *slot_one_profile;
168
+ ddog_prof_Profile slot_one_profile;
169
169
 
170
170
  pthread_mutex_t slot_two_mutex;
171
- ddog_prof_Profile *slot_two_profile;
171
+ ddog_prof_Profile slot_two_profile;
172
172
 
173
173
  short active_slot; // MUST NEVER BE ACCESSED FROM record_sample; this is NOT for the sampler thread to use.
174
174
 
@@ -197,6 +197,7 @@ struct call_serialize_without_gvl_arguments {
197
197
 
198
198
  static VALUE _native_new(VALUE klass);
199
199
  static void initialize_slot_concurrency_control(struct stack_recorder_state *state);
200
+ static void initialize_profiles(struct stack_recorder_state *state, ddog_prof_Slice_ValueType sample_types);
200
201
  static void stack_recorder_typed_data_free(void *data);
201
202
  static VALUE _native_initialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE cpu_time_enabled, VALUE alloc_samples_enabled);
202
203
  static VALUE _native_serialize(VALUE self, VALUE recorder_instance);
@@ -211,8 +212,9 @@ static VALUE _native_is_slot_two_mutex_locked(DDTRACE_UNUSED VALUE _self, VALUE
211
212
  static VALUE test_slot_mutex_state(VALUE recorder_instance, int slot);
212
213
  static ddog_Timespec system_epoch_now_timespec(void);
213
214
  static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_instance);
214
- static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec timestamp);
215
+ static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec start_time);
215
216
  static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint);
217
+ static void reset_profile(ddog_prof_Profile *profile, ddog_Timespec *start_time /* Can be null */);
216
218
 
217
219
  void stack_recorder_init(VALUE profiling_module) {
218
220
  stack_recorder_class = rb_define_class_under(profiling_module, "StackRecorder", rb_cObject);
@@ -256,18 +258,25 @@ static const rb_data_type_t stack_recorder_typed_data = {
256
258
  static VALUE _native_new(VALUE klass) {
257
259
  struct stack_recorder_state *state = ruby_xcalloc(1, sizeof(struct stack_recorder_state));
258
260
 
261
+ // Note: Any exceptions raised from this note until the TypedData_Wrap_Struct call will lead to the state memory
262
+ // being leaked.
263
+
259
264
  ddog_prof_Slice_ValueType sample_types = {.ptr = all_value_types, .len = ALL_VALUE_TYPES_COUNT};
260
265
 
261
266
  initialize_slot_concurrency_control(state);
262
267
  for (uint8_t i = 0; i < ALL_VALUE_TYPES_COUNT; i++) { state->position_for[i] = all_value_types_positions[i]; }
263
268
  state->enabled_values_count = ALL_VALUE_TYPES_COUNT;
264
269
 
270
+ // Note: At this point, slot_one_profile and slot_two_profile contain null pointers. Libdatadog validates pointers
271
+ // before using them so it's ok for us to go ahead and create the StackRecorder object.
272
+
273
+ VALUE stack_recorder = TypedData_Wrap_Struct(klass, &stack_recorder_typed_data, state);
274
+
265
275
  // Note: Don't raise exceptions after this point, since it'll lead to libdatadog memory leaking!
266
276
 
267
- state->slot_one_profile = ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
268
- state->slot_two_profile = ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
277
+ initialize_profiles(state, sample_types);
269
278
 
270
- return TypedData_Wrap_Struct(klass, &stack_recorder_typed_data, state);
279
+ return stack_recorder;
271
280
  }
272
281
 
273
282
  static void initialize_slot_concurrency_control(struct stack_recorder_state *state) {
@@ -280,14 +289,36 @@ static void initialize_slot_concurrency_control(struct stack_recorder_state *sta
280
289
  state->active_slot = 1;
281
290
  }
282
291
 
292
+ static void initialize_profiles(struct stack_recorder_state *state, ddog_prof_Slice_ValueType sample_types) {
293
+ ddog_prof_Profile_NewResult slot_one_profile_result =
294
+ ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
295
+
296
+ if (slot_one_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
297
+ rb_raise(rb_eRuntimeError, "Failed to initialize slot one profile: %"PRIsVALUE, get_error_details_and_drop(&slot_one_profile_result.err));
298
+ }
299
+
300
+ ddog_prof_Profile_NewResult slot_two_profile_result =
301
+ ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
302
+
303
+ if (slot_two_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
304
+ // Uff! Though spot. We need to make sure to properly clean up the other profile as well first
305
+ ddog_prof_Profile_drop(&slot_one_profile_result.ok);
306
+ // And now we can raise...
307
+ rb_raise(rb_eRuntimeError, "Failed to initialize slot two profile: %"PRIsVALUE, get_error_details_and_drop(&slot_two_profile_result.err));
308
+ }
309
+
310
+ state->slot_one_profile = slot_one_profile_result.ok;
311
+ state->slot_two_profile = slot_two_profile_result.ok;
312
+ }
313
+
283
314
  static void stack_recorder_typed_data_free(void *state_ptr) {
284
315
  struct stack_recorder_state *state = (struct stack_recorder_state *) state_ptr;
285
316
 
286
317
  pthread_mutex_destroy(&state->slot_one_mutex);
287
- ddog_prof_Profile_drop(state->slot_one_profile);
318
+ ddog_prof_Profile_drop(&state->slot_one_profile);
288
319
 
289
320
  pthread_mutex_destroy(&state->slot_two_mutex);
290
- ddog_prof_Profile_drop(state->slot_two_profile);
321
+ ddog_prof_Profile_drop(&state->slot_two_profile);
291
322
 
292
323
  ruby_xfree(state);
293
324
  }
@@ -333,13 +364,11 @@ static VALUE _native_initialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_insta
333
364
  state->position_for[ALLOC_SAMPLES_VALUE_ID] = next_disabled_pos++;
334
365
  }
335
366
 
336
- ddog_prof_Slice_ValueType sample_types = {.ptr = enabled_value_types, .len = state->enabled_values_count};
337
-
338
- ddog_prof_Profile_drop(state->slot_one_profile);
339
- ddog_prof_Profile_drop(state->slot_two_profile);
367
+ ddog_prof_Profile_drop(&state->slot_one_profile);
368
+ ddog_prof_Profile_drop(&state->slot_two_profile);
340
369
 
341
- state->slot_one_profile = ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
342
- state->slot_two_profile = ddog_prof_Profile_new(sample_types, NULL /* period is optional */, NULL /* start_time is optional */);
370
+ ddog_prof_Slice_ValueType sample_types = {.ptr = enabled_value_types, .len = state->enabled_values_count};
371
+ initialize_profiles(state, sample_types);
343
372
 
344
373
  return Qtrue;
345
374
  }
@@ -386,10 +415,6 @@ static VALUE _native_serialize(DDTRACE_UNUSED VALUE _self, VALUE recorder_instan
386
415
  VALUE start = ruby_time_from(ddprof_start);
387
416
  VALUE finish = ruby_time_from(ddprof_finish);
388
417
 
389
- if (!ddog_prof_Profile_reset(args.profile, NULL /* start_time is optional */ )) {
390
- return rb_ary_new_from_args(2, error_symbol, rb_str_new_cstr("Failed to reset profile"));
391
- }
392
-
393
418
  return rb_ary_new_from_args(2, ok_symbol, rb_ary_new_from_args(3, start, finish, encoded_pprof));
394
419
  }
395
420
 
@@ -399,7 +424,7 @@ static VALUE ruby_time_from(ddog_Timespec ddprof_time) {
399
424
  return rb_time_timespec_new(&time, utc);
400
425
  }
401
426
 
402
- void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, ddog_prof_Slice_Label labels) {
427
+ void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, sample_labels labels) {
403
428
  struct stack_recorder_state *state;
404
429
  TypedData_Get_Struct(recorder_instance, struct stack_recorder_state, &stack_recorder_typed_data, state);
405
430
 
@@ -413,22 +438,23 @@ void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations,
413
438
  uint8_t *position_for = state->position_for;
414
439
 
415
440
  metric_values[position_for[CPU_TIME_VALUE_ID]] = values.cpu_time_ns;
416
- metric_values[position_for[CPU_SAMPLES_VALUE_ID]] = values.cpu_samples;
441
+ metric_values[position_for[CPU_SAMPLES_VALUE_ID]] = values.cpu_or_wall_samples;
417
442
  metric_values[position_for[WALL_TIME_VALUE_ID]] = values.wall_time_ns;
418
443
  metric_values[position_for[ALLOC_SAMPLES_VALUE_ID]] = values.alloc_samples;
419
444
 
420
- ddog_prof_Profile_AddResult result = ddog_prof_Profile_add(
445
+ ddog_prof_Profile_Result result = ddog_prof_Profile_add(
421
446
  active_slot.profile,
422
447
  (ddog_prof_Sample) {
423
448
  .locations = locations,
424
449
  .values = (ddog_Slice_I64) {.ptr = metric_values, .len = state->enabled_values_count},
425
- .labels = labels
426
- }
450
+ .labels = labels.labels
451
+ },
452
+ labels.end_timestamp_ns
427
453
  );
428
454
 
429
455
  sampler_unlock_active_profile(active_slot);
430
456
 
431
- if (result.tag == DDOG_PROF_PROFILE_ADD_RESULT_ERR) {
457
+ if (result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
432
458
  rb_raise(rb_eArgError, "Failed to record sample: %"PRIsVALUE, get_error_details_and_drop(&result.err));
433
459
  }
434
460
  }
@@ -439,16 +465,21 @@ void record_endpoint(VALUE recorder_instance, uint64_t local_root_span_id, ddog_
439
465
 
440
466
  struct active_slot_pair active_slot = sampler_lock_active_profile(state);
441
467
 
442
- ddog_prof_Profile_set_endpoint(active_slot.profile, local_root_span_id, endpoint);
468
+ ddog_prof_Profile_Result result = ddog_prof_Profile_set_endpoint(active_slot.profile, local_root_span_id, endpoint);
443
469
 
444
470
  sampler_unlock_active_profile(active_slot);
471
+
472
+ if (result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
473
+ rb_raise(rb_eArgError, "Failed to record endpoint: %"PRIsVALUE, get_error_details_and_drop(&result.err));
474
+ }
445
475
  }
446
476
 
447
477
  static void *call_serialize_without_gvl(void *call_args) {
448
478
  struct call_serialize_without_gvl_arguments *args = (struct call_serialize_without_gvl_arguments *) call_args;
449
479
 
450
480
  args->profile = serializer_flip_active_and_inactive_slots(args->state);
451
- args->result = ddog_prof_Profile_serialize(args->profile, &args->finish_timestamp, NULL /* duration_nanos is optional */);
481
+ // Note: The profile gets reset by the serialize call
482
+ args->result = ddog_prof_Profile_serialize(args->profile, &args->finish_timestamp, NULL /* duration_nanos is optional */, NULL /* start_time is optional */);
452
483
  args->serialize_ran = true;
453
484
 
454
485
  return NULL; // Unused
@@ -467,7 +498,7 @@ static struct active_slot_pair sampler_lock_active_profile(struct stack_recorder
467
498
  if (error && error != EBUSY) ENFORCE_SUCCESS_GVL(error);
468
499
 
469
500
  // Slot one is active
470
- if (!error) return (struct active_slot_pair) {.mutex = &state->slot_one_mutex, .profile = state->slot_one_profile};
501
+ if (!error) return (struct active_slot_pair) {.mutex = &state->slot_one_mutex, .profile = &state->slot_one_profile};
471
502
 
472
503
  // If we got here, slot one was not active, let's try slot two
473
504
 
@@ -475,7 +506,7 @@ static struct active_slot_pair sampler_lock_active_profile(struct stack_recorder
475
506
  if (error && error != EBUSY) ENFORCE_SUCCESS_GVL(error);
476
507
 
477
508
  // Slot two is active
478
- if (!error) return (struct active_slot_pair) {.mutex = &state->slot_two_mutex, .profile = state->slot_two_profile};
509
+ if (!error) return (struct active_slot_pair) {.mutex = &state->slot_two_mutex, .profile = &state->slot_two_profile};
479
510
  }
480
511
 
481
512
  // We already tried both multiple times, and we did not succeed. This is not expected to happen. Let's stop sampling.
@@ -506,7 +537,7 @@ static ddog_prof_Profile *serializer_flip_active_and_inactive_slots(struct stack
506
537
  state->active_slot = (previously_active_slot == 1) ? 2 : 1;
507
538
 
508
539
  // Return profile for previously active slot (now inactive)
509
- return (previously_active_slot == 1) ? state->slot_one_profile : state->slot_two_profile;
540
+ return (previously_active_slot == 1) ? &state->slot_one_profile : &state->slot_two_profile;
510
541
  }
511
542
 
512
543
  // This method exists only to enable testing Datadog::Profiling::StackRecorder behavior using RSpec.
@@ -565,19 +596,18 @@ static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE recorder_
565
596
  // resulting state is inconsistent, we make sure to reset it back to the initial state.
566
597
  initialize_slot_concurrency_control(state);
567
598
 
568
- ddog_prof_Profile_reset(state->slot_one_profile, /* start_time: */ NULL);
569
- ddog_prof_Profile_reset(state->slot_two_profile, /* start_time: */ NULL);
599
+ reset_profile(&state->slot_one_profile, /* start_time: */ NULL);
600
+ reset_profile(&state->slot_two_profile, /* start_time: */ NULL);
570
601
 
571
602
  return Qtrue;
572
603
  }
573
604
 
574
- // Assumption 1: This method is called with the GVL being held, because `ddog_prof_Profile_reset` mutates the profile and should
605
+ // Assumption 1: This method is called with the GVL being held, because `ddog_prof_Profile_reset` mutates the profile and must
575
606
  // not be interrupted part-way through by a VM fork.
576
- static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec timestamp) {
577
- // Before making this profile active, we reset it so that it uses the correct timestamp for its start
578
- ddog_prof_Profile *next_profile = (state->active_slot == 1) ? state->slot_two_profile : state->slot_one_profile;
579
-
580
- if (!ddog_prof_Profile_reset(next_profile, &timestamp)) rb_raise(rb_eRuntimeError, "Failed to reset profile");
607
+ static void serializer_set_start_timestamp_for_next_profile(struct stack_recorder_state *state, ddog_Timespec start_time) {
608
+ // Before making this profile active, we reset it so that it uses the correct start_time for its start
609
+ ddog_prof_Profile *next_profile = (state->active_slot == 1) ? &state->slot_two_profile : &state->slot_one_profile;
610
+ reset_profile(next_profile, &start_time);
581
611
  }
582
612
 
583
613
  static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_instance, VALUE local_root_span_id, VALUE endpoint) {
@@ -585,3 +615,10 @@ static VALUE _native_record_endpoint(DDTRACE_UNUSED VALUE _self, VALUE recorder_
585
615
  record_endpoint(recorder_instance, NUM2ULL(local_root_span_id), char_slice_from_ruby_string(endpoint));
586
616
  return Qtrue;
587
617
  }
618
+
619
+ static void reset_profile(ddog_prof_Profile *profile, ddog_Timespec *start_time /* Can be null */) {
620
+ ddog_prof_Profile_Result reset_result = ddog_prof_Profile_reset(profile, start_time);
621
+ if (reset_result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
622
+ rb_raise(rb_eRuntimeError, "Failed to reset profile: %"PRIsVALUE, get_error_details_and_drop(&reset_result.err));
623
+ }
624
+ }
@@ -2,13 +2,23 @@
2
2
 
3
3
  #include <datadog/profiling.h>
4
4
 
5
- typedef struct sample_values {
5
+ typedef struct {
6
6
  int64_t cpu_time_ns;
7
7
  int64_t wall_time_ns;
8
- uint32_t cpu_samples;
8
+ uint32_t cpu_or_wall_samples;
9
9
  uint32_t alloc_samples;
10
10
  } sample_values;
11
11
 
12
- void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, ddog_prof_Slice_Label labels);
12
+ typedef struct sample_labels {
13
+ ddog_prof_Slice_Label labels;
14
+
15
+ // This is used to allow the `Collectors::Stack` to modify the existing label, if any. This MUST be NULL or point
16
+ // somewhere inside the labels slice above.
17
+ ddog_prof_Label *state_label;
18
+
19
+ int64_t end_timestamp_ns;
20
+ } sample_labels;
21
+
22
+ void record_sample(VALUE recorder_instance, ddog_prof_Slice_Location locations, sample_values values, sample_labels labels);
13
23
  void record_endpoint(VALUE recorder_instance, uint64_t local_root_span_id, ddog_CharSlice endpoint);
14
24
  VALUE enforce_recorder_instance(VALUE object);
@@ -0,0 +1,92 @@
1
+ [
2
+ {
3
+ "id": "processor-001",
4
+ "generator": "extract_schema",
5
+ "conditions": [
6
+ {
7
+ "operator": "equals",
8
+ "parameters": {
9
+ "inputs": [
10
+ {
11
+ "address": "waf.context.processor",
12
+ "key_path": [
13
+ "extract-schema"
14
+ ]
15
+ }
16
+ ],
17
+ "type": "boolean",
18
+ "value": true
19
+ }
20
+ }
21
+ ],
22
+ "parameters": {
23
+ "mappings": [
24
+ {
25
+ "inputs": [
26
+ {
27
+ "address": "server.request.body"
28
+ }
29
+ ],
30
+ "output": "_dd.appsec.s.req.body"
31
+ },
32
+ {
33
+ "inputs": [
34
+ {
35
+ "address": "server.request.headers.no_cookies"
36
+ }
37
+ ],
38
+ "output": "_dd.appsec.s.req.headers"
39
+ },
40
+ {
41
+ "inputs": [
42
+ {
43
+ "address": "server.request.query"
44
+ }
45
+ ],
46
+ "output": "_dd.appsec.s.req.query"
47
+ },
48
+ {
49
+ "inputs": [
50
+ {
51
+ "address": "server.request.path_params"
52
+ }
53
+ ],
54
+ "output": "_dd.appsec.s.req.params"
55
+ },
56
+ {
57
+ "inputs": [
58
+ {
59
+ "address": "server.request.cookies"
60
+ }
61
+ ],
62
+ "output": "_dd.appsec.s.req.cookies"
63
+ },
64
+ {
65
+ "inputs": [
66
+ {
67
+ "address": "server.response.headers.no_cookies"
68
+ }
69
+ ],
70
+ "output": "_dd.appsec.s.res.headers"
71
+ },
72
+ {
73
+ "inputs": [
74
+ {
75
+ "address": "server.response.body"
76
+ }
77
+ ],
78
+ "output": "_dd.appsec.s.res.body"
79
+ }
80
+ ],
81
+ "scanners": [
82
+ {
83
+ "tags": {
84
+ "category": "pii"
85
+ }
86
+ }
87
+ ]
88
+ },
89
+ "evaluate": false,
90
+ "output": true
91
+ }
92
+ ]