datadog 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -2
  3. data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +3 -3
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +57 -18
  5. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +93 -106
  6. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +8 -2
  7. data/ext/datadog_profiling_native_extension/extconf.rb +8 -8
  8. data/ext/datadog_profiling_native_extension/heap_recorder.c +174 -28
  9. data/ext/datadog_profiling_native_extension/heap_recorder.h +11 -0
  10. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +1 -1
  11. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +1 -1
  12. data/ext/datadog_profiling_native_extension/ruby_helpers.c +14 -11
  13. data/ext/datadog_profiling_native_extension/stack_recorder.c +58 -22
  14. data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -0
  15. data/ext/libdatadog_extconf_helpers.rb +1 -1
  16. data/lib/datadog/appsec/configuration/settings.rb +8 -0
  17. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +1 -5
  18. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +7 -20
  19. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -15
  20. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +6 -18
  21. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +7 -20
  22. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +5 -18
  23. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +3 -1
  24. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -5
  25. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +5 -18
  26. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -10
  27. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +7 -20
  28. data/lib/datadog/appsec/event.rb +24 -0
  29. data/lib/datadog/appsec/ext.rb +4 -0
  30. data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -5
  31. data/lib/datadog/appsec/monitor/reactive/set_user.rb +7 -20
  32. data/lib/datadog/appsec/processor/context.rb +109 -0
  33. data/lib/datadog/appsec/processor.rb +7 -71
  34. data/lib/datadog/appsec/scope.rb +1 -4
  35. data/lib/datadog/appsec/utils/trace_operation.rb +15 -0
  36. data/lib/datadog/appsec/utils.rb +2 -0
  37. data/lib/datadog/appsec.rb +1 -0
  38. data/lib/datadog/core/configuration/agent_settings_resolver.rb +26 -25
  39. data/lib/datadog/core/configuration/settings.rb +12 -0
  40. data/lib/datadog/core/configuration.rb +1 -3
  41. data/lib/datadog/core/crashtracking/component.rb +8 -5
  42. data/lib/datadog/core/environment/yjit.rb +5 -0
  43. data/lib/datadog/core/remote/transport/http.rb +5 -0
  44. data/lib/datadog/core/remote/worker.rb +1 -1
  45. data/lib/datadog/core/runtime/ext.rb +1 -0
  46. data/lib/datadog/core/runtime/metrics.rb +4 -0
  47. data/lib/datadog/core/semaphore.rb +35 -0
  48. data/lib/datadog/core/telemetry/logging.rb +10 -10
  49. data/lib/datadog/core/transport/ext.rb +1 -0
  50. data/lib/datadog/core/workers/async.rb +1 -1
  51. data/lib/datadog/di/code_tracker.rb +11 -13
  52. data/lib/datadog/di/instrumenter.rb +301 -0
  53. data/lib/datadog/di/probe.rb +29 -0
  54. data/lib/datadog/di/probe_builder.rb +7 -1
  55. data/lib/datadog/di/probe_notification_builder.rb +207 -0
  56. data/lib/datadog/di/probe_notifier_worker.rb +244 -0
  57. data/lib/datadog/di/serializer.rb +23 -1
  58. data/lib/datadog/di/transport.rb +67 -0
  59. data/lib/datadog/di/utils.rb +39 -0
  60. data/lib/datadog/di.rb +43 -0
  61. data/lib/datadog/profiling/collectors/thread_context.rb +9 -11
  62. data/lib/datadog/profiling/component.rb +1 -0
  63. data/lib/datadog/profiling/stack_recorder.rb +37 -9
  64. data/lib/datadog/tracing/component.rb +13 -0
  65. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -0
  66. data/lib/datadog/tracing/contrib/excon/middleware.rb +3 -0
  67. data/lib/datadog/tracing/contrib/faraday/middleware.rb +3 -0
  68. data/lib/datadog/tracing/contrib/grape/endpoint.rb +5 -2
  69. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +9 -0
  70. data/lib/datadog/tracing/contrib/http/instrumentation.rb +4 -0
  71. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +4 -0
  72. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -0
  73. data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
  74. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +3 -0
  75. data/lib/datadog/tracing/sampling/rule_sampler.rb +6 -4
  76. data/lib/datadog/tracing/tracer.rb +15 -10
  77. data/lib/datadog/tracing/transport/http.rb +4 -0
  78. data/lib/datadog/tracing/workers.rb +1 -1
  79. data/lib/datadog/tracing/writer.rb +26 -28
  80. data/lib/datadog/version.rb +1 -1
  81. metadata +22 -14
data/lib/datadog/di.rb CHANGED
@@ -1,7 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'di/error'
3
4
  require_relative 'di/configuration'
5
+ require_relative 'di/code_tracker'
4
6
  require_relative 'di/extensions'
7
+ require_relative 'di/instrumenter'
8
+ require_relative 'di/probe'
9
+ require_relative 'di/redactor'
10
+ require_relative 'di/serializer'
11
+ require_relative 'di/transport'
12
+ require_relative 'di/utils'
5
13
 
6
14
  module Datadog
7
15
  # Namespace for Datadog dynamic instrumentation.
@@ -10,5 +18,40 @@ module Datadog
10
18
  module DI
11
19
  # Expose DI to global shared objects
12
20
  Extensions.activate!
21
+
22
+ class << self
23
+ attr_reader :code_tracker
24
+
25
+ # Activates code tracking. Normally this method should be called
26
+ # when the application starts. If instrumenting third-party code,
27
+ # code tracking needs to be enabled before the third-party libraries
28
+ # are loaded. If you definitely will not be instrumenting
29
+ # third-party libraries, activating tracking after third-party libraries
30
+ # have been loaded may improve lookup performance.
31
+ #
32
+ # TODO test that activating tracker multiple times preserves
33
+ # existing mappings in the registry
34
+ def activate_tracking!
35
+ (@code_tracker ||= CodeTracker.new).start
36
+ end
37
+
38
+ # Deactivates code tracking. In normal usage of DI this method should
39
+ # never be called, however it is used by DI's test suite to reset
40
+ # state for individual tests.
41
+ #
42
+ # Note that deactivating tracking clears out the registry, losing
43
+ # the ability to look up files that have been loaded into the process
44
+ # already.
45
+ def deactivate_tracking!
46
+ code_tracker&.stop
47
+ end
48
+
49
+ # Returns whether code tracking is available.
50
+ # This method should be used instead of querying #code_tracker
51
+ # because the latter one may be nil.
52
+ def code_tracking_active?
53
+ code_tracker&.active? || false
54
+ end
55
+ end
13
56
  end
14
57
  end
@@ -21,20 +21,18 @@ module Datadog
21
21
  endpoint_collection_enabled:,
22
22
  timeline_enabled:,
23
23
  waiting_for_gvl_threshold_ns:,
24
- otel_context_enabled:,
25
- allocation_type_enabled: true
24
+ otel_context_enabled:
26
25
  )
27
26
  tracer_context_key = safely_extract_context_key_from(tracer)
28
27
  self.class._native_initialize(
29
- self,
30
- recorder,
31
- max_frames,
32
- tracer_context_key,
33
- endpoint_collection_enabled,
34
- timeline_enabled,
35
- waiting_for_gvl_threshold_ns,
36
- otel_context_enabled,
37
- allocation_type_enabled,
28
+ self_instance: self,
29
+ recorder: recorder,
30
+ max_frames: max_frames,
31
+ tracer_context_key: tracer_context_key,
32
+ endpoint_collection_enabled: endpoint_collection_enabled,
33
+ timeline_enabled: timeline_enabled,
34
+ waiting_for_gvl_threshold_ns: waiting_for_gvl_threshold_ns,
35
+ otel_context_enabled: otel_context_enabled,
38
36
  )
39
37
  end
40
38
 
@@ -53,6 +53,7 @@ module Datadog
53
53
  heap_size_enabled: heap_size_profiling_enabled,
54
54
  heap_sample_every: heap_sample_every,
55
55
  timeline_enabled: timeline_enabled,
56
+ heap_clean_after_gc_enabled: settings.profiling.advanced.heap_clean_after_gc_enabled,
56
57
  )
57
58
  thread_context_collector = build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled)
58
59
  worker = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new(
@@ -9,8 +9,13 @@ module Datadog
9
9
  # Methods prefixed with _native_ are implemented in `stack_recorder.c`
10
10
  class StackRecorder
11
11
  def initialize(
12
- cpu_time_enabled:, alloc_samples_enabled:, heap_samples_enabled:, heap_size_enabled:,
13
- heap_sample_every:, timeline_enabled:
12
+ cpu_time_enabled:,
13
+ alloc_samples_enabled:,
14
+ heap_samples_enabled:,
15
+ heap_size_enabled:,
16
+ heap_sample_every:,
17
+ timeline_enabled:,
18
+ heap_clean_after_gc_enabled:
14
19
  )
15
20
  # This mutex works in addition to the fancy C-level mutexes we have in the native side (see the docs there).
16
21
  # It prevents multiple Ruby threads calling serialize at the same time -- something like
@@ -21,13 +26,36 @@ module Datadog
21
26
  @no_concurrent_synchronize_mutex = Mutex.new
22
27
 
23
28
  self.class._native_initialize(
24
- self,
25
- cpu_time_enabled,
26
- alloc_samples_enabled,
27
- heap_samples_enabled,
28
- heap_size_enabled,
29
- heap_sample_every,
30
- timeline_enabled,
29
+ self_instance: self,
30
+ cpu_time_enabled: cpu_time_enabled,
31
+ alloc_samples_enabled: alloc_samples_enabled,
32
+ heap_samples_enabled: heap_samples_enabled,
33
+ heap_size_enabled: heap_size_enabled,
34
+ heap_sample_every: heap_sample_every,
35
+ timeline_enabled: timeline_enabled,
36
+ heap_clean_after_gc_enabled: heap_clean_after_gc_enabled,
37
+ )
38
+ end
39
+
40
+ def self.for_testing(
41
+ cpu_time_enabled: true,
42
+ alloc_samples_enabled: false,
43
+ heap_samples_enabled: false,
44
+ heap_size_enabled: false,
45
+ heap_sample_every: 1,
46
+ timeline_enabled: false,
47
+ heap_clean_after_gc_enabled: true,
48
+ **options
49
+ )
50
+ new(
51
+ cpu_time_enabled: cpu_time_enabled,
52
+ alloc_samples_enabled: alloc_samples_enabled,
53
+ heap_samples_enabled: heap_samples_enabled,
54
+ heap_size_enabled: heap_size_enabled,
55
+ heap_sample_every: heap_sample_every,
56
+ timeline_enabled: timeline_enabled,
57
+ heap_clean_after_gc_enabled: heap_clean_after_gc_enabled,
58
+ **options,
31
59
  )
32
60
  end
33
61
 
@@ -73,6 +73,19 @@ module Datadog
73
73
  return sampler
74
74
  end
75
75
 
76
+ # AppSec events are sent to the backend using traces.
77
+ # Standalone ASM billing means that we don't want to charge clients for APM traces,
78
+ # so we want to send the minimum amount of traces possible (idealy only traces that contains security events),
79
+ # but for features such as API Security, we need to send at least one trace per minute,
80
+ # to keep the service alive on the backend side.
81
+ if settings.appsec.standalone.enabled
82
+ post_sampler = Tracing::Sampling::RuleSampler.new(
83
+ [Tracing::Sampling::SimpleRule.new(sample_rate: 1.0)],
84
+ rate_limiter: Datadog::Core::TokenBucket.new(1.0 / 60, 1.0),
85
+ default_sample_rate: 1.0 / 60
86
+ )
87
+ end
88
+
76
89
  # Sampling rules are provided
77
90
  if (rules = settings.tracing.sampling.rules)
78
91
  post_sampler = Tracing::Sampling::RuleSampler.parse(
@@ -110,6 +110,10 @@ module Datadog
110
110
 
111
111
  datadog_tag_request
112
112
 
113
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(datadog_trace)
114
+ datadog_trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
115
+ end
116
+
113
117
  if datadog_configuration[:distributed_tracing]
114
118
  @datadog_original_headers ||= {}
115
119
  Contrib::HTTP.inject(datadog_trace, @datadog_original_headers)
@@ -30,6 +30,9 @@ module Datadog
30
30
  trace = Tracing.active_trace
31
31
  datum[:datadog_span] = span
32
32
  annotate!(span, datum)
33
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
34
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
35
+ end
33
36
  propagate!(trace, span, datum) if distributed_tracing?
34
37
 
35
38
  span
@@ -29,6 +29,9 @@ module Datadog
29
29
 
30
30
  Tracing.trace(Ext::SPAN_REQUEST, on_error: request_options[:on_error]) do |span, trace|
31
31
  annotate!(span, env, request_options)
32
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
33
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
34
+ end
32
35
  propagate!(trace, span, env) if request_options[:distributed_tracing] && Tracing.enabled?
33
36
  app.call(env).on_complete { |resp| handle_response(span, resp, request_options) }
34
37
  end
@@ -267,8 +267,11 @@ module Datadog
267
267
  route_path = endpoint.options[:path]
268
268
  namespace = endpoint.routes.first && endpoint.routes.first.namespace || ''
269
269
 
270
- parts = (namespace.split('/') + route_path).reject { |p| p.blank? || p.eql?('/') }
271
- parts.join('/').prepend('/')
270
+ path = (namespace.split('/') + route_path)
271
+ .reject { |p| p.blank? || p.eql?('/') }
272
+ .join('/')
273
+ path.prepend('/') if path[0] != '/'
274
+ path
272
275
  end
273
276
 
274
277
  def service_name
@@ -29,6 +29,15 @@ module Datadog
29
29
  end
30
30
 
31
31
  def should_skip_distributed_tracing?(client_config)
32
+ if Datadog.configuration.appsec.standalone.enabled
33
+ # Skip distributed tracing so that we don't bill distributed traces in case of absence of
34
+ # upstream ASM event (_dd.p.appsec:1) and no local security event (which sets _dd.p.appsec:1 locally).
35
+ # If there is an ASM event, we still have to check if distributed tracing is enabled or not
36
+ return true unless Tracing.active_trace
37
+
38
+ return true if Tracing.active_trace.get_tag(Datadog::AppSec::Ext::TAG_DISTRIBUTED_APPSEC_EVENT) != '1'
39
+ end
40
+
32
41
  return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)
33
42
 
34
43
  !Datadog.configuration.tracing[:http][:distributed_tracing]
@@ -35,6 +35,10 @@ module Datadog
35
35
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
36
36
  span.resource = req.method
37
37
 
38
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
39
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
40
+ end
41
+
38
42
  if Tracing.enabled? && !Contrib::HTTP.should_skip_distributed_tracing?(client_config)
39
43
  Contrib::HTTP.inject(trace, req)
40
44
  end
@@ -30,6 +30,10 @@ module Datadog
30
30
  span.service = service_name(host, request_options, client_config)
31
31
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
32
32
 
33
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
34
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
35
+ end
36
+
33
37
  if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)
34
38
  Contrib::HTTP.inject(trace, req.header)
35
39
  end
@@ -30,6 +30,10 @@ module Datadog
30
30
  span.service = service_name(host, request_options, client_config)
31
31
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
32
32
 
33
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
34
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
35
+ end
36
+
33
37
  Contrib::HTTP.inject(trace, req) if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)
34
38
 
35
39
  # Add additional request specific tags to the span.
@@ -58,7 +58,7 @@ module Datadog
58
58
  # Capture the executed source code when provided from STDIN.
59
59
  def eval(*args)
60
60
  span = Datadog::Tracing.active_span
61
- if span.name == Ext::SPAN_RUNNER_STDIN
61
+ if span&.name == Ext::SPAN_RUNNER_STDIN
62
62
  source = args[0]
63
63
  span.set_tag(
64
64
  Ext::TAG_RUNNER_SOURCE,
@@ -25,6 +25,9 @@ module Datadog
25
25
  return super(&block) unless Tracing.enabled?
26
26
 
27
27
  datadog_trace_request(uri) do |_span, trace|
28
+ if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
29
+ trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
30
+ end
28
31
  Contrib::HTTP.inject(trace, processed_headers) if datadog_configuration[:distributed_tracing]
29
32
 
30
33
  super(&block)
@@ -29,7 +29,12 @@ module Datadog
29
29
  default_sample_rate: Datadog.configuration.tracing.sampling.default_rate,
30
30
  default_sampler: nil
31
31
  )
32
- @rules = rules
32
+ @rules = if default_sample_rate && !default_sampler
33
+ # Add to the end of the rule list a rule always matches any trace
34
+ rules << SimpleRule.new(sample_rate: default_sample_rate)
35
+ else
36
+ rules
37
+ end
33
38
  @rate_limiter = if rate_limiter
34
39
  rate_limiter
35
40
  elsif rate_limit
@@ -37,12 +42,9 @@ module Datadog
37
42
  else
38
43
  Core::UnlimitedLimiter.new
39
44
  end
40
-
41
45
  @default_sampler = if default_sampler
42
46
  default_sampler
43
47
  elsif default_sample_rate
44
- # Add to the end of the rule list a rule always matches any trace
45
- @rules << SimpleRule.new(sample_rate: default_sample_rate)
46
48
  nil
47
49
  else
48
50
  # TODO: Simplify .tags access, as `Tracer#tags` can't be arbitrarily changed anymore
@@ -406,7 +406,7 @@ module Datadog
406
406
  on_error: on_error,
407
407
  resource: resource,
408
408
  service: service,
409
- tags: resolve_tags(tags),
409
+ tags: resolve_tags(tags, service),
410
410
  type: type,
411
411
  id: id,
412
412
  &block
@@ -420,7 +420,7 @@ module Datadog
420
420
  resource: resource,
421
421
  service: service,
422
422
  start_time: start_time,
423
- tags: resolve_tags(tags),
423
+ tags: resolve_tags(tags, service),
424
424
  type: type,
425
425
  id: id
426
426
  )
@@ -432,15 +432,20 @@ module Datadog
432
432
  end
433
433
  # rubocop:enable Lint/UnderscorePrefixedVariableName
434
434
 
435
- def resolve_tags(tags)
436
- if @tags.any? && tags
437
- # Combine default tags with provided tags,
438
- # preferring provided tags.
439
- @tags.merge(tags)
440
- else
441
- # Use provided tags or default tags if none.
442
- tags || @tags.dup
435
+ def resolve_tags(tags, service)
436
+ merged_tags = if @tags.any? && tags
437
+ # Combine default tags with provided tags,
438
+ # preferring provided tags.
439
+ @tags.merge(tags)
440
+ else
441
+ # Use provided tags or default tags if none.
442
+ tags || @tags.dup
443
+ end
444
+ # Remove version tag if service is not the default service
445
+ if merged_tags.key?(Core::Environment::Ext::TAG_VERSION) && service != @default_service
446
+ merged_tags.delete(Core::Environment::Ext::TAG_VERSION)
443
447
  end
448
+ merged_tags
444
449
  end
445
450
 
446
451
  # Manually activate and deactivate the trace, when the span completes.
@@ -74,6 +74,10 @@ module Datadog
74
74
  # Add container ID, if present.
75
75
  container_id = Datadog::Core::Environment::Container.container_id
76
76
  headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id unless container_id.nil?
77
+ # Pretend that stats computation are already done by the client
78
+ if Datadog.configuration.appsec.standalone.enabled
79
+ headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
80
+ end
77
81
  end
78
82
  end
79
83
 
@@ -70,7 +70,7 @@ module Datadog
70
70
  @run = true
71
71
  Datadog.logger.debug { "Starting thread for: #{self}" }
72
72
  @worker = Thread.new { perform }
73
- @worker.name = self.class.name unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
73
+ @worker.name = self.class.name
74
74
  @worker.thread_variable_set(:fork_safe, true)
75
75
 
76
76
  nil
@@ -68,21 +68,6 @@ module Datadog
68
68
  end
69
69
  end
70
70
 
71
- # spawns a worker for spans; they share the same transport which is thread-safe
72
- # @!visibility private
73
- def start_worker
74
- @trace_handler = ->(items, transport) { send_spans(items, transport) }
75
- @worker = Workers::AsyncTransport.new(
76
- transport: @transport,
77
- buffer_size: @buff_size,
78
- on_trace: @trace_handler,
79
- interval: @flush_interval,
80
- shutdown_timeout: @shutdown_timeout
81
- )
82
-
83
- @worker.start
84
- end
85
-
86
71
  # Gracefully shuts down this writer.
87
72
  #
88
73
  # Once stopped methods calls won't fail, but
@@ -93,19 +78,6 @@ module Datadog
93
78
  @mutex_after_fork.synchronize { stop_worker }
94
79
  end
95
80
 
96
- def stop_worker
97
- @stopped = true
98
-
99
- return if @worker.nil?
100
-
101
- @worker.stop
102
- @worker = nil
103
-
104
- true
105
- end
106
-
107
- private :start_worker, :stop_worker
108
-
109
81
  # flush spans to the trace-agent, handles spans only
110
82
  # @!visibility private
111
83
  def send_spans(traces, transport)
@@ -179,6 +151,32 @@ module Datadog
179
151
 
180
152
  private
181
153
 
154
+ # spawns a worker for spans; they share the same transport which is thread-safe
155
+ # @!visibility private
156
+ def start_worker
157
+ @trace_handler = ->(items, transport) { send_spans(items, transport) }
158
+ @worker = Workers::AsyncTransport.new(
159
+ transport: @transport,
160
+ buffer_size: @buff_size,
161
+ on_trace: @trace_handler,
162
+ interval: @flush_interval,
163
+ shutdown_timeout: @shutdown_timeout
164
+ )
165
+
166
+ @worker.start
167
+ end
168
+
169
+ def stop_worker
170
+ @stopped = true
171
+
172
+ return if @worker.nil?
173
+
174
+ @worker.stop
175
+ @worker = nil
176
+
177
+ true
178
+ end
179
+
182
180
  def reset_stats!
183
181
  @traces_flushed = 0
184
182
  @transport.stats.reset!
@@ -3,7 +3,7 @@
3
3
  module Datadog
4
4
  module VERSION
5
5
  MAJOR = 2
6
- MINOR = 4
6
+ MINOR = 5
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
  BUILD = nil
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.4.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-10-11 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: 12.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: 12.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,
@@ -209,6 +209,7 @@ files:
209
209
  - lib/datadog/appsec/monitor/reactive/set_user.rb
210
210
  - lib/datadog/appsec/processor.rb
211
211
  - lib/datadog/appsec/processor/actions.rb
212
+ - lib/datadog/appsec/processor/context.rb
212
213
  - lib/datadog/appsec/processor/rule_loader.rb
213
214
  - lib/datadog/appsec/processor/rule_merger.rb
214
215
  - lib/datadog/appsec/rate_limiter.rb
@@ -224,6 +225,7 @@ files:
224
225
  - lib/datadog/appsec/utils/http.rb
225
226
  - lib/datadog/appsec/utils/http/media_range.rb
226
227
  - lib/datadog/appsec/utils/http/media_type.rb
228
+ - lib/datadog/appsec/utils/trace_operation.rb
227
229
  - lib/datadog/auto_instrument.rb
228
230
  - lib/datadog/auto_instrument_base.rb
229
231
  - lib/datadog/core.rb
@@ -303,6 +305,7 @@ files:
303
305
  - lib/datadog/core/remote/worker.rb
304
306
  - lib/datadog/core/runtime/ext.rb
305
307
  - lib/datadog/core/runtime/metrics.rb
308
+ - lib/datadog/core/semaphore.rb
306
309
  - lib/datadog/core/telemetry/component.rb
307
310
  - lib/datadog/core/telemetry/emitter.rb
308
311
  - lib/datadog/core/telemetry/event.rb
@@ -365,10 +368,15 @@ files:
365
368
  - lib/datadog/di/configuration/settings.rb
366
369
  - lib/datadog/di/error.rb
367
370
  - lib/datadog/di/extensions.rb
371
+ - lib/datadog/di/instrumenter.rb
368
372
  - lib/datadog/di/probe.rb
369
373
  - lib/datadog/di/probe_builder.rb
374
+ - lib/datadog/di/probe_notification_builder.rb
375
+ - lib/datadog/di/probe_notifier_worker.rb
370
376
  - lib/datadog/di/redactor.rb
371
377
  - lib/datadog/di/serializer.rb
378
+ - lib/datadog/di/transport.rb
379
+ - lib/datadog/di/utils.rb
372
380
  - lib/datadog/kit.rb
373
381
  - lib/datadog/kit/appsec/events.rb
374
382
  - lib/datadog/kit/enable_core_dumps.rb
@@ -887,8 +895,8 @@ licenses:
887
895
  - Apache-2.0
888
896
  metadata:
889
897
  allowed_push_host: https://rubygems.org
890
- changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.4.0/CHANGELOG.md
891
- source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.4.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
892
900
  post_install_message:
893
901
  rdoc_options: []
894
902
  require_paths:
@@ -907,7 +915,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
907
915
  - !ruby/object:Gem::Version
908
916
  version: 2.0.0
909
917
  requirements: []
910
- rubygems_version: 3.5.17
918
+ rubygems_version: 3.4.10
911
919
  signing_key:
912
920
  specification_version: 4
913
921
  summary: Datadog tracing code for your Ruby applications