datadog 2.3.0 → 2.5.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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -2
  3. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +9 -1
  4. data/ext/datadog_profiling_loader/extconf.rb +10 -22
  5. data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +3 -3
  6. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +198 -41
  7. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +4 -2
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +89 -46
  9. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +645 -107
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +15 -1
  11. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +0 -27
  12. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +0 -4
  13. data/ext/datadog_profiling_native_extension/extconf.rb +42 -25
  14. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +50 -0
  15. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +75 -0
  16. data/ext/datadog_profiling_native_extension/heap_recorder.c +194 -34
  17. data/ext/datadog_profiling_native_extension/heap_recorder.h +11 -0
  18. data/ext/datadog_profiling_native_extension/http_transport.c +38 -6
  19. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +1 -1
  20. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +53 -2
  21. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -0
  22. data/ext/datadog_profiling_native_extension/profiling.c +1 -1
  23. data/ext/datadog_profiling_native_extension/ruby_helpers.c +14 -11
  24. data/ext/datadog_profiling_native_extension/stack_recorder.c +58 -22
  25. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -0
  26. data/ext/libdatadog_api/crashtracker.c +20 -18
  27. data/ext/libdatadog_api/datadog_ruby_common.c +0 -27
  28. data/ext/libdatadog_api/datadog_ruby_common.h +0 -4
  29. data/ext/libdatadog_extconf_helpers.rb +1 -1
  30. data/lib/datadog/appsec/assets/waf_rules/recommended.json +2184 -108
  31. data/lib/datadog/appsec/assets/waf_rules/strict.json +1430 -2
  32. data/lib/datadog/appsec/component.rb +29 -8
  33. data/lib/datadog/appsec/configuration/settings.rb +10 -2
  34. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +1 -0
  35. data/lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb +21 -0
  36. data/lib/datadog/appsec/contrib/devise/patcher.rb +12 -2
  37. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +0 -14
  38. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +67 -31
  39. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +14 -15
  40. data/lib/datadog/appsec/contrib/graphql/integration.rb +14 -1
  41. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +7 -20
  42. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +2 -5
  43. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -15
  44. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +6 -18
  45. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +7 -20
  46. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +5 -18
  47. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +3 -1
  48. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -5
  49. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +5 -18
  50. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -10
  51. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +7 -20
  52. data/lib/datadog/appsec/event.rb +25 -1
  53. data/lib/datadog/appsec/ext.rb +4 -0
  54. data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -5
  55. data/lib/datadog/appsec/monitor/reactive/set_user.rb +7 -20
  56. data/lib/datadog/appsec/processor/context.rb +109 -0
  57. data/lib/datadog/appsec/processor/rule_loader.rb +3 -1
  58. data/lib/datadog/appsec/processor/rule_merger.rb +33 -15
  59. data/lib/datadog/appsec/processor.rb +42 -107
  60. data/lib/datadog/appsec/rate_limiter.rb +25 -40
  61. data/lib/datadog/appsec/remote.rb +7 -3
  62. data/lib/datadog/appsec/scope.rb +1 -4
  63. data/lib/datadog/appsec/utils/trace_operation.rb +15 -0
  64. data/lib/datadog/appsec/utils.rb +2 -0
  65. data/lib/datadog/appsec.rb +3 -2
  66. data/lib/datadog/core/configuration/agent_settings_resolver.rb +26 -25
  67. data/lib/datadog/core/configuration/components.rb +4 -3
  68. data/lib/datadog/core/configuration/settings.rb +96 -5
  69. data/lib/datadog/core/configuration.rb +1 -3
  70. data/lib/datadog/core/crashtracking/component.rb +9 -6
  71. data/lib/datadog/core/environment/execution.rb +5 -5
  72. data/lib/datadog/core/environment/yjit.rb +5 -0
  73. data/lib/datadog/core/metrics/client.rb +7 -0
  74. data/lib/datadog/core/rate_limiter.rb +183 -0
  75. data/lib/datadog/core/remote/client/capabilities.rb +4 -3
  76. data/lib/datadog/core/remote/component.rb +4 -2
  77. data/lib/datadog/core/remote/negotiation.rb +4 -4
  78. data/lib/datadog/core/remote/tie.rb +2 -0
  79. data/lib/datadog/core/remote/transport/http.rb +5 -0
  80. data/lib/datadog/core/remote/worker.rb +1 -1
  81. data/lib/datadog/core/runtime/ext.rb +1 -0
  82. data/lib/datadog/core/runtime/metrics.rb +5 -1
  83. data/lib/datadog/core/semaphore.rb +35 -0
  84. data/lib/datadog/core/telemetry/component.rb +2 -0
  85. data/lib/datadog/core/telemetry/event.rb +12 -7
  86. data/lib/datadog/core/telemetry/logger.rb +51 -0
  87. data/lib/datadog/core/telemetry/logging.rb +50 -14
  88. data/lib/datadog/core/telemetry/request.rb +13 -1
  89. data/lib/datadog/core/transport/ext.rb +1 -0
  90. data/lib/datadog/core/utils/time.rb +12 -0
  91. data/lib/datadog/core/workers/async.rb +1 -1
  92. data/lib/datadog/di/code_tracker.rb +166 -0
  93. data/lib/datadog/di/configuration/settings.rb +163 -0
  94. data/lib/datadog/di/configuration.rb +11 -0
  95. data/lib/datadog/di/error.rb +31 -0
  96. data/lib/datadog/di/extensions.rb +16 -0
  97. data/lib/datadog/di/instrumenter.rb +301 -0
  98. data/lib/datadog/di/probe.rb +162 -0
  99. data/lib/datadog/di/probe_builder.rb +47 -0
  100. data/lib/datadog/di/probe_notification_builder.rb +207 -0
  101. data/lib/datadog/di/probe_notifier_worker.rb +244 -0
  102. data/lib/datadog/di/redactor.rb +188 -0
  103. data/lib/datadog/di/serializer.rb +215 -0
  104. data/lib/datadog/di/transport.rb +67 -0
  105. data/lib/datadog/di/utils.rb +39 -0
  106. data/lib/datadog/di.rb +57 -0
  107. data/lib/datadog/opentelemetry/sdk/propagator.rb +2 -0
  108. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +12 -10
  109. data/lib/datadog/profiling/collectors/info.rb +12 -3
  110. data/lib/datadog/profiling/collectors/thread_context.rb +32 -8
  111. data/lib/datadog/profiling/component.rb +21 -4
  112. data/lib/datadog/profiling/http_transport.rb +6 -1
  113. data/lib/datadog/profiling/scheduler.rb +2 -0
  114. data/lib/datadog/profiling/stack_recorder.rb +40 -9
  115. data/lib/datadog/single_step_instrument.rb +12 -0
  116. data/lib/datadog/tracing/component.rb +13 -0
  117. data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +8 -12
  118. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -0
  119. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +78 -0
  120. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +33 -0
  121. data/lib/datadog/tracing/contrib/action_pack/patcher.rb +2 -0
  122. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +4 -0
  123. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +3 -1
  124. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +3 -1
  125. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +5 -1
  126. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +5 -0
  127. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  128. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -0
  129. data/lib/datadog/tracing/contrib/excon/middleware.rb +3 -0
  130. data/lib/datadog/tracing/contrib/faraday/middleware.rb +12 -0
  131. data/lib/datadog/tracing/contrib/grape/endpoint.rb +24 -2
  132. data/lib/datadog/tracing/contrib/graphql/patcher.rb +9 -12
  133. data/lib/datadog/tracing/contrib/graphql/trace_patcher.rb +3 -3
  134. data/lib/datadog/tracing/contrib/graphql/tracing_patcher.rb +3 -3
  135. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +13 -9
  136. data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +6 -3
  137. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +9 -0
  138. data/lib/datadog/tracing/contrib/http/instrumentation.rb +22 -15
  139. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +10 -5
  140. data/lib/datadog/tracing/contrib/httpclient/patcher.rb +1 -14
  141. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +9 -0
  142. data/lib/datadog/tracing/contrib/httprb/patcher.rb +1 -14
  143. data/lib/datadog/tracing/contrib/lograge/patcher.rb +1 -2
  144. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
  145. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -6
  146. data/lib/datadog/tracing/contrib/patcher.rb +2 -1
  147. data/lib/datadog/tracing/contrib/presto/patcher.rb +1 -13
  148. data/lib/datadog/tracing/contrib/rack/middlewares.rb +27 -0
  149. data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
  150. data/lib/datadog/tracing/contrib/redis/tags.rb +4 -0
  151. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +3 -0
  152. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +4 -0
  153. data/lib/datadog/tracing/contrib/stripe/request.rb +3 -2
  154. data/lib/datadog/tracing/distributed/propagation.rb +7 -0
  155. data/lib/datadog/tracing/metadata/ext.rb +2 -0
  156. data/lib/datadog/tracing/remote.rb +5 -2
  157. data/lib/datadog/tracing/sampling/matcher.rb +6 -1
  158. data/lib/datadog/tracing/sampling/rate_sampler.rb +1 -1
  159. data/lib/datadog/tracing/sampling/rule.rb +2 -0
  160. data/lib/datadog/tracing/sampling/rule_sampler.rb +15 -9
  161. data/lib/datadog/tracing/sampling/span/ext.rb +1 -1
  162. data/lib/datadog/tracing/sampling/span/rule.rb +2 -2
  163. data/lib/datadog/tracing/trace_operation.rb +26 -2
  164. data/lib/datadog/tracing/tracer.rb +29 -22
  165. data/lib/datadog/tracing/transport/http/client.rb +1 -0
  166. data/lib/datadog/tracing/transport/http.rb +4 -0
  167. data/lib/datadog/tracing/transport/io/client.rb +1 -0
  168. data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
  169. data/lib/datadog/tracing/workers.rb +2 -2
  170. data/lib/datadog/tracing/writer.rb +26 -28
  171. data/lib/datadog/version.rb +1 -1
  172. metadata +40 -15
  173. data/lib/datadog/tracing/sampling/rate_limiter.rb +0 -185
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-22 00:00:00.000000000 Z
11
+ date: 2024-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -25,47 +25,47 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: debase-ruby_core_source
28
+ name: datadog-ruby_core_source
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 3.3.1
33
+ version: '3.3'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 3.3.1
40
+ version: '3.3'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: libddwaf
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.14.0.0.0
47
+ version: 1.15.0.0.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.14.0.0.0
54
+ version: 1.15.0.0.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: libdatadog
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 11.0.0.1.0
61
+ version: 13.1.0.1.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 11.0.0.1.0
68
+ version: 13.1.0.1.0
69
69
  description: |
70
70
  datadog is Datadog's client library for Ruby. It includes a suite of tools
71
71
  which provide visibility into the performance and security of Ruby applications,
@@ -110,6 +110,8 @@ files:
110
110
  - ext/datadog_profiling_native_extension/datadog_ruby_common.c
111
111
  - ext/datadog_profiling_native_extension/datadog_ruby_common.h
112
112
  - ext/datadog_profiling_native_extension/extconf.rb
113
+ - ext/datadog_profiling_native_extension/gvl_profiling_helper.c
114
+ - ext/datadog_profiling_native_extension/gvl_profiling_helper.h
113
115
  - ext/datadog_profiling_native_extension/heap_recorder.c
114
116
  - ext/datadog_profiling_native_extension/heap_recorder.h
115
117
  - ext/datadog_profiling_native_extension/helpers.h
@@ -156,6 +158,7 @@ files:
156
158
  - lib/datadog/appsec/contrib/devise/patcher.rb
157
159
  - lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb
158
160
  - lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb
161
+ - lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb
159
162
  - lib/datadog/appsec/contrib/devise/resource.rb
160
163
  - lib/datadog/appsec/contrib/devise/tracking.rb
161
164
  - lib/datadog/appsec/contrib/graphql/appsec_trace.rb
@@ -206,6 +209,7 @@ files:
206
209
  - lib/datadog/appsec/monitor/reactive/set_user.rb
207
210
  - lib/datadog/appsec/processor.rb
208
211
  - lib/datadog/appsec/processor/actions.rb
212
+ - lib/datadog/appsec/processor/context.rb
209
213
  - lib/datadog/appsec/processor/rule_loader.rb
210
214
  - lib/datadog/appsec/processor/rule_merger.rb
211
215
  - lib/datadog/appsec/rate_limiter.rb
@@ -221,6 +225,7 @@ files:
221
225
  - lib/datadog/appsec/utils/http.rb
222
226
  - lib/datadog/appsec/utils/http/media_range.rb
223
227
  - lib/datadog/appsec/utils/http/media_type.rb
228
+ - lib/datadog/appsec/utils/trace_operation.rb
224
229
  - lib/datadog/auto_instrument.rb
225
230
  - lib/datadog/auto_instrument_base.rb
226
231
  - lib/datadog/core.rb
@@ -271,6 +276,7 @@ files:
271
276
  - lib/datadog/core/metrics/metric.rb
272
277
  - lib/datadog/core/metrics/options.rb
273
278
  - lib/datadog/core/pin.rb
279
+ - lib/datadog/core/rate_limiter.rb
274
280
  - lib/datadog/core/remote.rb
275
281
  - lib/datadog/core/remote/client.rb
276
282
  - lib/datadog/core/remote/client/capabilities.rb
@@ -299,6 +305,7 @@ files:
299
305
  - lib/datadog/core/remote/worker.rb
300
306
  - lib/datadog/core/runtime/ext.rb
301
307
  - lib/datadog/core/runtime/metrics.rb
308
+ - lib/datadog/core/semaphore.rb
302
309
  - lib/datadog/core/telemetry/component.rb
303
310
  - lib/datadog/core/telemetry/emitter.rb
304
311
  - lib/datadog/core/telemetry/event.rb
@@ -308,6 +315,7 @@ files:
308
315
  - lib/datadog/core/telemetry/http/ext.rb
309
316
  - lib/datadog/core/telemetry/http/response.rb
310
317
  - lib/datadog/core/telemetry/http/transport.rb
318
+ - lib/datadog/core/telemetry/logger.rb
311
319
  - lib/datadog/core/telemetry/logging.rb
312
320
  - lib/datadog/core/telemetry/metric.rb
313
321
  - lib/datadog/core/telemetry/metrics_collection.rb
@@ -354,6 +362,21 @@ files:
354
362
  - lib/datadog/core/workers/polling.rb
355
363
  - lib/datadog/core/workers/queue.rb
356
364
  - lib/datadog/core/workers/runtime_metrics.rb
365
+ - lib/datadog/di.rb
366
+ - lib/datadog/di/code_tracker.rb
367
+ - lib/datadog/di/configuration.rb
368
+ - lib/datadog/di/configuration/settings.rb
369
+ - lib/datadog/di/error.rb
370
+ - lib/datadog/di/extensions.rb
371
+ - lib/datadog/di/instrumenter.rb
372
+ - lib/datadog/di/probe.rb
373
+ - lib/datadog/di/probe_builder.rb
374
+ - lib/datadog/di/probe_notification_builder.rb
375
+ - lib/datadog/di/probe_notifier_worker.rb
376
+ - lib/datadog/di/redactor.rb
377
+ - lib/datadog/di/serializer.rb
378
+ - lib/datadog/di/transport.rb
379
+ - lib/datadog/di/utils.rb
357
380
  - lib/datadog/kit.rb
358
381
  - lib/datadog/kit/appsec/events.rb
359
382
  - lib/datadog/kit/enable_core_dumps.rb
@@ -391,6 +414,7 @@ files:
391
414
  - lib/datadog/profiling/tasks/exec.rb
392
415
  - lib/datadog/profiling/tasks/help.rb
393
416
  - lib/datadog/profiling/tasks/setup.rb
417
+ - lib/datadog/single_step_instrument.rb
394
418
  - lib/datadog/tracing.rb
395
419
  - lib/datadog/tracing/analytics.rb
396
420
  - lib/datadog/tracing/buffer.rb
@@ -424,6 +448,8 @@ files:
424
448
  - lib/datadog/tracing/contrib/action_mailer/patcher.rb
425
449
  - lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb
426
450
  - lib/datadog/tracing/contrib/action_pack/action_controller/patcher.rb
451
+ - lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb
452
+ - lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb
427
453
  - lib/datadog/tracing/contrib/action_pack/configuration/settings.rb
428
454
  - lib/datadog/tracing/contrib/action_pack/ext.rb
429
455
  - lib/datadog/tracing/contrib/action_pack/integration.rb
@@ -824,7 +850,6 @@ files:
824
850
  - lib/datadog/tracing/sampling/priority_sampler.rb
825
851
  - lib/datadog/tracing/sampling/rate_by_key_sampler.rb
826
852
  - lib/datadog/tracing/sampling/rate_by_service_sampler.rb
827
- - lib/datadog/tracing/sampling/rate_limiter.rb
828
853
  - lib/datadog/tracing/sampling/rate_sampler.rb
829
854
  - lib/datadog/tracing/sampling/rule.rb
830
855
  - lib/datadog/tracing/sampling/rule_sampler.rb
@@ -870,8 +895,8 @@ licenses:
870
895
  - Apache-2.0
871
896
  metadata:
872
897
  allowed_push_host: https://rubygems.org
873
- changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.3.0/CHANGELOG.md
874
- source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.3.0
898
+ changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.5.0/CHANGELOG.md
899
+ source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.5.0
875
900
  post_install_message:
876
901
  rdoc_options: []
877
902
  require_paths:
@@ -890,7 +915,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
890
915
  - !ruby/object:Gem::Version
891
916
  version: 2.0.0
892
917
  requirements: []
893
- rubygems_version: 3.5.16
918
+ rubygems_version: 3.4.10
894
919
  signing_key:
895
920
  specification_version: 4
896
921
  summary: Datadog tracing code for your Ruby applications
@@ -1,185 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../core/utils/time'
4
-
5
- module Datadog
6
- module Tracing
7
- module Sampling
8
- # Checks for rate limiting on a resource.
9
- class RateLimiter
10
- # Checks if resource of specified size can be
11
- # conforms with the current limit.
12
- #
13
- # Implementations of this method are not guaranteed
14
- # to be side-effect free.
15
- #
16
- # @return [Boolean] whether a resource conforms with the current limit
17
- def allow?(size); end
18
-
19
- # The effective rate limiting ratio based on
20
- # recent calls to `allow?`.
21
- #
22
- # @return [Float] recent allowance ratio
23
- def effective_rate; end
24
- end
25
-
26
- # Implementation of the Token Bucket metering algorithm
27
- # for rate limiting.
28
- #
29
- # @see https://en.wikipedia.org/wiki/Token_bucket Token bucket
30
- class TokenBucket < RateLimiter
31
- attr_reader :rate, :max_tokens
32
-
33
- # @param rate [Numeric] Allowance rate, in units per second
34
- # if rate is negative, always allow
35
- # if rate is zero, never allow
36
- # @param max_tokens [Numeric] Limit of available tokens
37
- def initialize(rate, max_tokens = rate)
38
- super()
39
-
40
- raise ArgumentError, "rate must be a number: #{rate}" unless rate.is_a?(Numeric)
41
- raise ArgumentError, "max_tokens must be a number: #{max_tokens}" unless max_tokens.is_a?(Numeric)
42
-
43
- @rate = rate
44
- @max_tokens = max_tokens
45
-
46
- @tokens = max_tokens
47
- @total_messages = 0
48
- @conforming_messages = 0
49
- @prev_conforming_messages = nil
50
- @prev_total_messages = nil
51
- @current_window = nil
52
-
53
- @last_refill = Core::Utils::Time.get_time
54
- end
55
-
56
- # Checks if a message of provided +size+
57
- # conforms with the current bucket limit.
58
- #
59
- # If it does, return +true+ and remove +size+
60
- # tokens from the bucket.
61
- # If it does not, return +false+ without affecting
62
- # the tokens from the bucket.
63
- #
64
- # @return [Boolean] +true+ if message conforms with current bucket limit
65
- def allow?(size)
66
- allowed = should_allow?(size)
67
- update_rate_counts(allowed)
68
- allowed
69
- end
70
-
71
- # Ratio of 'conformance' per 'total messages' checked
72
- # averaged for the past 2 buckets
73
- #
74
- # Returns +1.0+ when no messages have been checked yet.
75
- #
76
- # @return [Float] Conformance ratio, between +[0,1]+
77
- def effective_rate
78
- return 0.0 if @rate.zero?
79
- return 1.0 if @rate < 0 || @total_messages.zero?
80
-
81
- return current_window_rate if @prev_conforming_messages.nil? || @prev_total_messages.nil?
82
-
83
- (@conforming_messages.to_f + @prev_conforming_messages.to_f) / (@total_messages + @prev_total_messages)
84
- end
85
-
86
- # Ratio of 'conformance' per 'total messages' checked
87
- # on this bucket
88
- #
89
- # Returns +1.0+ when no messages have been checked yet.
90
- #
91
- # @return [Float] Conformance ratio, between +[0,1]+
92
- def current_window_rate
93
- return 1.0 if @total_messages.zero?
94
-
95
- @conforming_messages.to_f / @total_messages
96
- end
97
-
98
- # @return [Numeric] number of tokens currently available
99
- def available_tokens
100
- @tokens
101
- end
102
-
103
- private
104
-
105
- def refill_since_last_message
106
- now = Core::Utils::Time.get_time
107
- elapsed = now - @last_refill
108
-
109
- # Update the number of available tokens, but ensure we do not exceed the max
110
- # we return the min of tokens + rate*elapsed, or max tokens
111
- refill_tokens(@rate * elapsed)
112
-
113
- @last_refill = now
114
- end
115
-
116
- def refill_tokens(size)
117
- @tokens += size
118
- @tokens = @max_tokens if @tokens > @max_tokens
119
- end
120
-
121
- def increment_total_count
122
- @total_messages += 1
123
- end
124
-
125
- def increment_conforming_count
126
- @conforming_messages += 1
127
- end
128
-
129
- def should_allow?(size)
130
- # rate limit of 0 blocks everything
131
- return false if @rate.zero?
132
-
133
- # negative rate limit disables rate limiting
134
- return true if @rate < 0
135
-
136
- refill_since_last_message
137
-
138
- # if tokens < 1 we don't allow?
139
- return false if @tokens < size
140
-
141
- @tokens -= size
142
-
143
- true
144
- end
145
-
146
- # Sets and Updates the past two 1 second windows for which
147
- # the rate limiter must compute it's rate over and updates
148
- # the total count, and conforming message count if +allowed+
149
- def update_rate_counts(allowed)
150
- now = Core::Utils::Time.get_time
151
-
152
- # No tokens have been seen yet, start a new window
153
- if @current_window.nil?
154
- @current_window = now
155
- # If more than 1 second has past since last window, reset
156
- elsif now - @current_window >= 1
157
- @prev_conforming_messages = @conforming_messages
158
- @prev_total_messages = @total_messages
159
- @conforming_messages = 0
160
- @total_messages = 0
161
- @current_window = now
162
- end
163
-
164
- increment_conforming_count if allowed
165
-
166
- increment_total_count
167
- end
168
- end
169
-
170
- # {Datadog::Tracing::Sampling::RateLimiter} that accepts all resources,
171
- # with no limits.
172
- class UnlimitedLimiter < RateLimiter
173
- # @return [Boolean] always +true+
174
- def allow?(_)
175
- true
176
- end
177
-
178
- # @return [Float] always 100%
179
- def effective_rate
180
- 1.0
181
- end
182
- end
183
- end
184
- end
185
- end