ddtrace 1.3.0 → 1.4.1

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -2
  3. data/README.md +1 -1
  4. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +10 -1
  5. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +5 -4
  6. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +1 -1
  7. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +391 -0
  8. data/ext/ddtrace_profiling_native_extension/extconf.rb +2 -0
  9. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +9 -0
  10. data/ext/ddtrace_profiling_native_extension/profiling.c +2 -0
  11. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +2 -1
  12. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +8 -7
  13. data/lib/datadog/ci/contrib/cucumber/integration.rb +1 -1
  14. data/lib/datadog/ci/contrib/rspec/integration.rb +1 -1
  15. data/lib/datadog/core/configuration/base.rb +9 -0
  16. data/lib/datadog/core/configuration/components.rb +26 -6
  17. data/lib/datadog/core/configuration/settings.rb +25 -0
  18. data/lib/datadog/core/configuration.rb +4 -1
  19. data/lib/datadog/core/telemetry/client.rb +79 -0
  20. data/lib/datadog/core/telemetry/collector.rb +234 -0
  21. data/lib/datadog/core/telemetry/emitter.rb +48 -0
  22. data/lib/datadog/core/telemetry/event.rb +71 -0
  23. data/lib/datadog/core/telemetry/ext.rb +11 -0
  24. data/lib/datadog/core/telemetry/heartbeat.rb +37 -0
  25. data/lib/datadog/core/telemetry/http/adapters/net.rb +113 -0
  26. data/lib/datadog/core/telemetry/http/env.rb +20 -0
  27. data/lib/datadog/core/telemetry/http/ext.rb +20 -0
  28. data/lib/datadog/core/telemetry/http/response.rb +68 -0
  29. data/lib/datadog/core/telemetry/http/transport.rb +53 -0
  30. data/lib/datadog/core/telemetry/v1/app_event.rb +52 -0
  31. data/lib/datadog/core/telemetry/v1/application.rb +86 -0
  32. data/lib/datadog/core/telemetry/v1/configuration.rb +25 -0
  33. data/lib/datadog/core/telemetry/v1/dependency.rb +36 -0
  34. data/lib/datadog/core/telemetry/v1/host.rb +51 -0
  35. data/lib/datadog/core/telemetry/v1/integration.rb +58 -0
  36. data/lib/datadog/core/telemetry/v1/product.rb +28 -0
  37. data/lib/datadog/core/telemetry/v1/telemetry_request.rb +100 -0
  38. data/lib/datadog/core/utils/sequence.rb +5 -0
  39. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +74 -0
  40. data/lib/datadog/profiling/stack_recorder.rb +1 -1
  41. data/lib/datadog/profiling.rb +1 -0
  42. data/lib/datadog/tracing/contrib/extensions.rb +2 -0
  43. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +9 -0
  44. data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
  45. data/lib/datadog/tracing/contrib/patcher.rb +11 -0
  46. data/lib/datadog/tracing/contrib/rack/patcher.rb +8 -0
  47. data/lib/datadog/tracing/trace_operation.rb +1 -1
  48. data/lib/ddtrace/auto_instrument.rb +7 -0
  49. data/lib/ddtrace/transport/ext.rb +0 -1
  50. data/lib/ddtrace/transport/http/adapters/net.rb +1 -0
  51. data/lib/ddtrace/version.rb +2 -2
  52. metadata +26 -5
@@ -0,0 +1,100 @@
1
+ module Datadog
2
+ module Core
3
+ module Telemetry
4
+ module V1
5
+ # Describes attributes for telemetry API request
6
+ class TelemetryRequest
7
+ ERROR_NIL_API_VERSION_MESSAGE = ':api_version must not be nil'.freeze
8
+ ERROR_NIL_APPLICATION_MESSAGE = ':application must not be nil'.freeze
9
+ ERROR_NIL_HOST_MESSAGE = ':host must not be nil'.freeze
10
+ ERROR_NIL_PAYLOAD_MESSAGE = ':payload must not be nil'.freeze
11
+ ERROR_NIL_REQUEST_TYPE_MESSAGE = ':request_type must not be nil'.freeze
12
+ ERROR_NIL_RUNTIME_ID_MESSAGE = ':runtime_id must not be nil'.freeze
13
+ ERROR_NIL_SEQ_ID_MESSAGE = ':seq_id must not be nil'.freeze
14
+ ERROR_NIL_TRACER_TIME_MESSAGE = ':tracer_time must not be nil'.freeze
15
+
16
+ attr_reader \
17
+ :api_version,
18
+ :application,
19
+ :debug,
20
+ :host,
21
+ :payload,
22
+ :request_type,
23
+ :runtime_id,
24
+ :seq_id,
25
+ :session_id,
26
+ :tracer_time
27
+
28
+ # @param api_version [String] Requested API version, `v1`
29
+ # @param application [Telemetry::V1::Application] Object that contains information about the environment of the
30
+ # application
31
+ # @param host [Telemetry::V1::Host] Object that holds host related information
32
+ # @param payload [Telemetry::V1::AppEvent] The payload of the request, type impacted by :request_type
33
+ # @param request_type [String] Requested API function impacting the Payload type, `app-started`
34
+ # @param runtime_id [String] V4 UUID that represents a tracer session
35
+ # @param seq_id [Integer] Counter that should be auto incremented every time an API call is being made
36
+ # @param tracer_time [Integer] Unix timestamp (in seconds) of when the message is being sent
37
+ # @param debug [Boolean] Flag that enables payload debug mode
38
+ # @param session_id [String] V4 UUID that represents the session of the top level tracer process, often same\
39
+ # as runtime_id
40
+ def initialize(
41
+ api_version:, application:, host:, payload:, request_type:, runtime_id:, seq_id:, tracer_time:,
42
+ debug: nil, session_id: nil
43
+ )
44
+ validate(
45
+ api_version: api_version,
46
+ application: application,
47
+ host: host,
48
+ payload: payload,
49
+ request_type: request_type,
50
+ runtime_id: runtime_id,
51
+ seq_id: seq_id,
52
+ tracer_time: tracer_time
53
+ )
54
+ @api_version = api_version
55
+ @application = application
56
+ @debug = debug
57
+ @host = host
58
+ @payload = payload
59
+ @request_type = request_type
60
+ @runtime_id = runtime_id
61
+ @seq_id = seq_id
62
+ @session_id = session_id
63
+ @tracer_time = tracer_time
64
+ end
65
+
66
+ def to_h
67
+ {
68
+ api_version: @api_version,
69
+ application: @application.to_h,
70
+ debug: @debug,
71
+ host: @host.to_h,
72
+ payload: @payload.to_h,
73
+ request_type: @request_type,
74
+ runtime_id: @runtime_id,
75
+ seq_id: @seq_id,
76
+ session_id: @session_id,
77
+ tracer_time: @tracer_time
78
+ }
79
+ end
80
+
81
+ private
82
+
83
+ # Validates all required arguments passed to the class on initialization are not nil
84
+ #
85
+ # @!visibility private
86
+ def validate(api_version:, application:, host:, payload:, request_type:, runtime_id:, seq_id:, tracer_time:)
87
+ raise ArgumentError, ERROR_NIL_API_VERSION_MESSAGE if api_version.nil?
88
+ raise ArgumentError, ERROR_NIL_APPLICATION_MESSAGE if application.nil?
89
+ raise ArgumentError, ERROR_NIL_HOST_MESSAGE if host.nil?
90
+ raise ArgumentError, ERROR_NIL_PAYLOAD_MESSAGE if payload.nil?
91
+ raise ArgumentError, ERROR_NIL_REQUEST_TYPE_MESSAGE if request_type.nil?
92
+ raise ArgumentError, ERROR_NIL_RUNTIME_ID_MESSAGE if runtime_id.nil?
93
+ raise ArgumentError, ERROR_NIL_SEQ_ID_MESSAGE if seq_id.nil?
94
+ raise ArgumentError, ERROR_NIL_TRACER_TIME_MESSAGE if tracer_time.nil?
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -6,6 +6,7 @@ module Datadog
6
6
  # Generates values from a consistent sequence
7
7
  class Sequence
8
8
  def initialize(seed = 0, &block)
9
+ @seed = seed
9
10
  @current = seed
10
11
  @next_item = block
11
12
  end
@@ -15,6 +16,10 @@ module Datadog
15
16
  @current += 1
16
17
  next_item
17
18
  end
19
+
20
+ def reset!
21
+ @current = @seed
22
+ end
18
23
  end
19
24
  end
20
25
  end
@@ -0,0 +1,74 @@
1
+ # typed: false
2
+
3
+ module Datadog
4
+ module Profiling
5
+ module Collectors
6
+ # Used to trigger the periodic execution of Collectors::CpuAndWallTime, which implements all of the sampling logic
7
+ # itself; this class only implements the "doing it periodically" part.
8
+ # Almost all of this class is implemented as native code.
9
+ #
10
+ # Methods prefixed with _native_ are implemented in `collectors_cpu_and_wall_time_worker.c`
11
+ class CpuAndWallTimeWorker
12
+ private
13
+
14
+ attr_accessor :failure_exception
15
+
16
+ public
17
+
18
+ def initialize(
19
+ recorder:,
20
+ max_frames:,
21
+ cpu_and_wall_time_collector: CpuAndWallTime.new(recorder: recorder, max_frames: max_frames)
22
+ )
23
+ self.class._native_initialize(self, cpu_and_wall_time_collector)
24
+ @worker_thread = nil
25
+ @failure_exception = nil
26
+ @start_stop_mutex = Mutex.new
27
+ end
28
+
29
+ def start
30
+ @start_stop_mutex.synchronize do
31
+ return if @worker_thread
32
+
33
+ Datadog.logger.debug { "Starting thread for: #{self}" }
34
+ @worker_thread = Thread.new do
35
+ begin
36
+ Thread.current.name = self.class.name unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
37
+
38
+ self.class._native_sampling_loop(self)
39
+
40
+ Datadog.logger.debug('CpuAndWallTimeWorker thread stopping cleanly')
41
+ rescue Exception => e # rubocop:disable Lint/RescueException
42
+ @failure_exception = e
43
+ Datadog.logger.warn(
44
+ "Worker thread error. Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
45
+ )
46
+ end
47
+ end
48
+ end
49
+
50
+ true
51
+ end
52
+
53
+ # TODO: Provided only for compatibility with the API for Collectors::OldStack used in the Profiler class.
54
+ # Can be removed once we remove OldStack.
55
+ def enabled=(_); end
56
+
57
+ def stop(*_)
58
+ @start_stop_mutex.synchronize do
59
+ Datadog.logger.debug('Requesting CpuAndWallTimeWorker thread shut down')
60
+
61
+ return unless @worker_thread
62
+
63
+ @worker_thread.kill
64
+ self.class._native_stop(self)
65
+
66
+ @worker_thread.join
67
+ @worker_thread = nil
68
+ @failure_exception = nil
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -13,7 +13,7 @@ module Datadog
13
13
  # This isn't something we expect to happen normally, but because it would break the assumptions of the
14
14
  # C-level mutexes (that there is a single serializer thread), we add it here as an extra safeguard against it
15
15
  # accidentally happening.
16
- @no_concurrent_synchronize_mutex = Thread::Mutex.new
16
+ @no_concurrent_synchronize_mutex = Mutex.new
17
17
  end
18
18
 
19
19
  def serialize
@@ -148,6 +148,7 @@ module Datadog
148
148
  require_relative 'profiling/ext/forking'
149
149
  require_relative 'profiling/collectors/code_provenance'
150
150
  require_relative 'profiling/collectors/cpu_and_wall_time'
151
+ require_relative 'profiling/collectors/cpu_and_wall_time_worker'
151
152
  require_relative 'profiling/collectors/old_stack'
152
153
  require_relative 'profiling/collectors/stack'
153
154
  require_relative 'profiling/stack_recorder'
@@ -97,6 +97,8 @@ module Datadog
97
97
  Datadog.logger.warn("Unable to patch #{patch_results[:name]} (#{desc})")
98
98
  end
99
99
 
100
+ components.telemetry.integrations_change! if configuration.integrations_pending_activation
101
+
100
102
  configuration.integrations_pending_activation.clear
101
103
  end
102
104
 
@@ -44,6 +44,9 @@ module Datadog
44
44
  host, _port = find_host_port(call)
45
45
  span.set_tag(Tracing::Metadata::Ext::TAG_PEER_HOSTNAME, host) if host
46
46
 
47
+ deadline = find_deadline(call)
48
+ span.set_tag(Ext::TAG_CLIENT_DEADLINE, deadline) if deadline
49
+
47
50
  # Set analytics sample rate
48
51
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
49
52
 
@@ -60,6 +63,12 @@ module Datadog
60
63
  .join('.')
61
64
  end
62
65
 
66
+ def find_deadline(call)
67
+ return unless call.respond_to?(:deadline) && call.deadline.is_a?(Time)
68
+
69
+ call.deadline.utc.iso8601(3)
70
+ end
71
+
63
72
  def find_host_port(call)
64
73
  return unless call
65
74
 
@@ -13,6 +13,7 @@ module Datadog
13
13
  DEFAULT_PEER_SERVICE_NAME = 'grpc'.freeze
14
14
  SPAN_CLIENT = 'grpc.client'.freeze
15
15
  SPAN_SERVICE = 'grpc.service'.freeze
16
+ TAG_CLIENT_DEADLINE = 'grpc.client.deadline'.freeze
16
17
  TAG_COMPONENT = 'grpc'.freeze
17
18
  TAG_OPERATION_CLIENT = 'client'.freeze
18
19
  TAG_OPERATION_SERVICE = 'service'.freeze
@@ -19,6 +19,10 @@ module Datadog
19
19
  # Prepended instance methods for all patchers
20
20
  # @public_api
21
21
  module CommonMethods
22
+ attr_accessor \
23
+ :patch_error_result,
24
+ :patch_successful
25
+
22
26
  def patch_name
23
27
  self.class != Class && self.class != Module ? self.class.name : name
24
28
  end
@@ -35,6 +39,7 @@ module Datadog
35
39
  super.tap do
36
40
  # Emit a metric
37
41
  Datadog.health_metrics.instrumentation_patched(1, tags: default_tags)
42
+ @patch_successful = true
38
43
  end
39
44
  rescue StandardError => e
40
45
  on_patch_error(e)
@@ -48,6 +53,12 @@ module Datadog
48
53
  # Log the error
49
54
  Datadog.logger.error("Failed to apply #{patch_name} patch. Cause: #{e} Location: #{Array(e.backtrace).first}")
50
55
 
56
+ @patch_error_result = {
57
+ type: e.class.name,
58
+ message: e.message,
59
+ line: Array(e.backtrace).first
60
+ }
61
+
51
62
  # Emit a metric
52
63
  tags = default_tags
53
64
  tags << "error:#{e.class.name}"
@@ -104,6 +104,14 @@ module Datadog
104
104
  def get_option(option)
105
105
  Datadog.configuration.tracing[:rack].get_option(option)
106
106
  end
107
+
108
+ def patch_successful
109
+ MiddlewarePatcher.patch_successful || MiddlewareNamePatcher.patch_successful
110
+ end
111
+
112
+ def patch_error_result
113
+ MiddlewarePatcher.patch_error_result || MiddlewareNamePatcher.patch_error_result
114
+ end
107
115
  end
108
116
  end
109
117
  end
@@ -74,7 +74,7 @@ module Datadog
74
74
  @id = id || Core::Utils.next_id
75
75
  @max_length = max_length || DEFAULT_MAX_LENGTH
76
76
  @parent_span_id = parent_span_id
77
- @sampled = sampled.nil? ? false : sampled
77
+ @sampled = sampled.nil? ? true : sampled
78
78
 
79
79
  # Tags
80
80
  @agent_sample_rate = agent_sample_rate
@@ -7,3 +7,10 @@ require_relative '../ddtrace'
7
7
  require_relative '../datadog/tracing/contrib/auto_instrument'
8
8
 
9
9
  Datadog::Profiling.start_if_enabled
10
+
11
+ module Datadog
12
+ module AutoInstrument
13
+ # Flag to determine if Auto Instrumentation was used
14
+ LOADED = true
15
+ end
16
+ end
@@ -9,7 +9,6 @@ module Datadog
9
9
  ADAPTER = :net_http # DEV: Rename to simply `:http`, as Net::HTTP is an implementation detail.
10
10
  DEFAULT_HOST = '127.0.0.1'.freeze
11
11
  DEFAULT_PORT = 8126
12
- DEFAULT_TIMEOUT_SECONDS = 1
13
12
 
14
13
  HEADER_CONTAINER_ID = 'Datadog-Container-ID'.freeze
15
14
  HEADER_DD_API_KEY = 'DD-API-KEY'.freeze
@@ -15,6 +15,7 @@ module Datadog
15
15
  :timeout,
16
16
  :ssl
17
17
 
18
+ # in seconds
18
19
  DEFAULT_TIMEOUT = 30
19
20
 
20
21
  # @deprecated Positional parameters are deprecated. Use named parameters instead.
@@ -3,8 +3,8 @@
3
3
  module DDTrace
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 3
7
- PATCH = 0
6
+ MINOR = 4
7
+ PATCH = 1
8
8
  PRE = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddtrace
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-04 00:00:00.000000000 Z
11
+ date: 2022-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.7.0.1.0
61
+ version: 0.7.0.1.1
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: 0.7.0.1.0
68
+ version: 0.7.0.1.1
69
69
  description: |
70
70
  ddtrace is Datadog's tracing client for Ruby. It is used to trace requests
71
71
  as they flow across web servers, databases and microservices so that developers
@@ -95,6 +95,7 @@ files:
95
95
  - ext/ddtrace_profiling_native_extension/clock_id_noop.c
96
96
  - ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c
97
97
  - ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h
98
+ - ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c
98
99
  - ext/ddtrace_profiling_native_extension/collectors_stack.c
99
100
  - ext/ddtrace_profiling_native_extension/collectors_stack.h
100
101
  - ext/ddtrace_profiling_native_extension/extconf.rb
@@ -227,6 +228,25 @@ files:
227
228
  - lib/datadog/core/pin.rb
228
229
  - lib/datadog/core/runtime/ext.rb
229
230
  - lib/datadog/core/runtime/metrics.rb
231
+ - lib/datadog/core/telemetry/client.rb
232
+ - lib/datadog/core/telemetry/collector.rb
233
+ - lib/datadog/core/telemetry/emitter.rb
234
+ - lib/datadog/core/telemetry/event.rb
235
+ - lib/datadog/core/telemetry/ext.rb
236
+ - lib/datadog/core/telemetry/heartbeat.rb
237
+ - lib/datadog/core/telemetry/http/adapters/net.rb
238
+ - lib/datadog/core/telemetry/http/env.rb
239
+ - lib/datadog/core/telemetry/http/ext.rb
240
+ - lib/datadog/core/telemetry/http/response.rb
241
+ - lib/datadog/core/telemetry/http/transport.rb
242
+ - lib/datadog/core/telemetry/v1/app_event.rb
243
+ - lib/datadog/core/telemetry/v1/application.rb
244
+ - lib/datadog/core/telemetry/v1/configuration.rb
245
+ - lib/datadog/core/telemetry/v1/dependency.rb
246
+ - lib/datadog/core/telemetry/v1/host.rb
247
+ - lib/datadog/core/telemetry/v1/integration.rb
248
+ - lib/datadog/core/telemetry/v1/product.rb
249
+ - lib/datadog/core/telemetry/v1/telemetry_request.rb
230
250
  - lib/datadog/core/utils.rb
231
251
  - lib/datadog/core/utils/compression.rb
232
252
  - lib/datadog/core/utils/forking.rb
@@ -274,6 +294,7 @@ files:
274
294
  - lib/datadog/profiling/buffer.rb
275
295
  - lib/datadog/profiling/collectors/code_provenance.rb
276
296
  - lib/datadog/profiling/collectors/cpu_and_wall_time.rb
297
+ - lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb
277
298
  - lib/datadog/profiling/collectors/old_stack.rb
278
299
  - lib/datadog/profiling/collectors/stack.rb
279
300
  - lib/datadog/profiling/encoding/profile.rb
@@ -757,7 +778,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
757
778
  - !ruby/object:Gem::Version
758
779
  version: 2.0.0
759
780
  requirements: []
760
- rubygems_version: 3.3.7
781
+ rubygems_version: 3.3.3
761
782
  signing_key:
762
783
  specification_version: 4
763
784
  summary: Datadog tracing code for your Ruby applications