datadog 2.12.1 → 2.13.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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -2
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +14 -13
  4. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +8 -0
  5. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  6. data/lib/datadog/appsec/actions_handler.rb +22 -1
  7. data/lib/datadog/appsec/anonymizer.rb +16 -0
  8. data/lib/datadog/appsec/configuration/settings.rb +62 -10
  9. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  10. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  11. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +79 -0
  12. data/lib/datadog/appsec/contrib/devise/ext.rb +21 -0
  13. data/lib/datadog/appsec/contrib/devise/integration.rb +0 -1
  14. data/lib/datadog/appsec/contrib/devise/patcher.rb +36 -23
  15. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  16. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  17. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  18. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +93 -0
  19. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  20. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +27 -0
  21. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +3 -2
  22. data/lib/datadog/appsec/event.rb +1 -1
  23. data/lib/datadog/appsec/ext.rb +4 -2
  24. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +4 -2
  25. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  26. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  27. data/lib/datadog/appsec/monitor/gateway/watcher.rb +8 -3
  28. data/lib/datadog/appsec/processor/rule_merger.rb +2 -1
  29. data/lib/datadog/appsec/remote.rb +7 -0
  30. data/lib/datadog/appsec/security_engine/runner.rb +2 -2
  31. data/lib/datadog/appsec/utils.rb +0 -2
  32. data/lib/datadog/core/configuration/components.rb +2 -1
  33. data/lib/datadog/core/configuration/ext.rb +4 -0
  34. data/lib/datadog/core/configuration/options.rb +2 -2
  35. data/lib/datadog/core/configuration/settings.rb +53 -30
  36. data/lib/datadog/core/environment/agent_info.rb +4 -3
  37. data/lib/datadog/core/remote/component.rb +3 -6
  38. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  39. data/lib/datadog/core/remote/negotiation.rb +9 -9
  40. data/lib/datadog/core/remote/transport/config.rb +4 -3
  41. data/lib/datadog/core/remote/transport/http/client.rb +4 -3
  42. data/lib/datadog/core/remote/transport/http/config.rb +6 -32
  43. data/lib/datadog/core/remote/transport/http/negotiation.rb +6 -32
  44. data/lib/datadog/core/remote/transport/http.rb +22 -57
  45. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  46. data/lib/datadog/core/runtime/metrics.rb +8 -1
  47. data/lib/datadog/core/telemetry/http/adapters/net.rb +1 -1
  48. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  49. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  50. data/lib/datadog/core/transport/http/builder.rb +5 -3
  51. data/lib/datadog/core/transport/http.rb +39 -2
  52. data/lib/datadog/di/component.rb +0 -2
  53. data/lib/datadog/di/probe_notifier_worker.rb +16 -16
  54. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  55. data/lib/datadog/di/transport/http/api.rb +2 -12
  56. data/lib/datadog/di/transport/http/client.rb +4 -3
  57. data/lib/datadog/di/transport/http/diagnostics.rb +7 -33
  58. data/lib/datadog/di/transport/http/input.rb +7 -33
  59. data/lib/datadog/di/transport/http.rb +14 -56
  60. data/lib/datadog/di/transport/input.rb +4 -3
  61. data/lib/datadog/di/utils.rb +5 -0
  62. data/lib/datadog/kit/appsec/events.rb +9 -0
  63. data/lib/datadog/kit/identity.rb +5 -1
  64. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  65. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  66. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  67. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  68. data/lib/datadog/opentelemetry.rb +2 -1
  69. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  70. data/lib/datadog/profiling.rb +5 -2
  71. data/lib/datadog/tracing/component.rb +15 -12
  72. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  73. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  74. data/lib/datadog/tracing/context_provider.rb +1 -1
  75. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  76. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  77. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  78. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  79. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  80. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  81. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  82. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  83. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -5
  84. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -11
  85. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +6 -10
  86. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  87. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  88. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  89. data/lib/datadog/tracing/correlation.rb +9 -2
  90. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  91. data/lib/datadog/tracing/distributed/datadog.rb +2 -0
  92. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  93. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  94. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  95. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  96. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  97. data/lib/datadog/tracing/metadata.rb +2 -0
  98. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  99. data/lib/datadog/tracing/span.rb +10 -1
  100. data/lib/datadog/tracing/span_operation.rb +8 -2
  101. data/lib/datadog/tracing/sync_writer.rb +1 -2
  102. data/lib/datadog/tracing/trace_digest.rb +9 -2
  103. data/lib/datadog/tracing/trace_operation.rb +29 -17
  104. data/lib/datadog/tracing/trace_segment.rb +6 -4
  105. data/lib/datadog/tracing/tracer.rb +38 -2
  106. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  107. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  108. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  109. data/lib/datadog/tracing/transport/http.rb +11 -44
  110. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  111. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  112. data/lib/datadog/tracing/transport/traces.rb +21 -9
  113. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  114. data/lib/datadog/tracing/writer.rb +2 -6
  115. data/lib/datadog/tracing.rb +16 -3
  116. data/lib/datadog/version.rb +2 -2
  117. metadata +20 -13
  118. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  119. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  120. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  121. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  122. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  123. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
@@ -53,10 +53,12 @@ module Datadog
53
53
  end
54
54
 
55
55
  # rubocop:disable Metrics/MethodLength
56
+ # rubocop:disable Metrics/CyclomaticComplexity
56
57
  def receivers(telemetry)
57
58
  return [] unless remote_features_enabled?
58
59
 
59
60
  matcher = Core::Remote::Dispatcher::Matcher::Product.new(ASM_PRODUCTS)
61
+ # rubocop:disable Metrics/BlockLength
60
62
  receiver = Core::Remote::Dispatcher::Receiver.new(matcher) do |repository, changes|
61
63
  changes.each do |change|
62
64
  Datadog.logger.debug { "remote config change: '#{change.path}'" }
@@ -67,6 +69,7 @@ module Datadog
67
69
  data = []
68
70
  overrides = []
69
71
  exclusions = []
72
+ actions = []
70
73
 
71
74
  repository.contents.each do |content|
72
75
  parsed_content = parse_content(content)
@@ -80,6 +83,7 @@ module Datadog
80
83
  overrides << parsed_content['rules_override'] if parsed_content['rules_override']
81
84
  exclusions << parsed_content['exclusions'] if parsed_content['exclusions']
82
85
  custom_rules << parsed_content['custom_rules'] if parsed_content['custom_rules']
86
+ actions.concat(parsed_content['actions']) if parsed_content['actions']
83
87
  end
84
88
  end
85
89
 
@@ -97,6 +101,7 @@ module Datadog
97
101
  ruleset = AppSec::Processor::RuleMerger.merge(
98
102
  rules: rules,
99
103
  data: data,
104
+ actions: actions,
100
105
  overrides: overrides,
101
106
  exclusions: exclusions,
102
107
  custom_rules: custom_rules,
@@ -109,10 +114,12 @@ module Datadog
109
114
  content.applied if ASM_PRODUCTS.include?(content.path.product)
110
115
  end
111
116
  end
117
+ # rubocop:enable Metrics/BlockLength
112
118
 
113
119
  [receiver]
114
120
  end
115
121
  # rubocop:enable Metrics/MethodLength
122
+ # rubocop:enable Metrics/CyclomaticComplexity
116
123
 
117
124
  private
118
125
 
@@ -24,13 +24,13 @@ module Datadog
24
24
  persistent_data.reject! do |_, v|
25
25
  next false if v.is_a?(TrueClass) || v.is_a?(FalseClass)
26
26
 
27
- v.nil? ? true : v.empty?
27
+ v.nil? || v.empty?
28
28
  end
29
29
 
30
30
  ephemeral_data.reject! do |_, v|
31
31
  next false if v.is_a?(TrueClass) || v.is_a?(FalseClass)
32
32
 
33
- v.nil? ? true : v.empty?
33
+ v.nil? || v.empty?
34
34
  end
35
35
 
36
36
  _code, result = try_run(persistent_data, ephemeral_data, timeout)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'utils/trace_operation'
4
-
5
3
  module Datadog
6
4
  module AppSec
7
5
  # Utilities for AppSec
@@ -45,6 +45,7 @@ module Datadog
45
45
  options = { enabled: settings.runtime_metrics.enabled }
46
46
  options[:statsd] = settings.runtime_metrics.statsd unless settings.runtime_metrics.statsd.nil?
47
47
  options[:services] = [settings.service] unless settings.service.nil?
48
+ options[:experimental_runtime_id_enabled] = settings.runtime_metrics.experimental_runtime_id_enabled
48
49
 
49
50
  Core::Runtime::Metrics.new(logger: logger, **options)
50
51
  end
@@ -101,7 +102,7 @@ module Datadog
101
102
  agent_settings = AgentSettingsResolver.call(settings, logger: @logger)
102
103
 
103
104
  # Exposes agent capability information for detection by any components
104
- @agent_info = Core::Environment::AgentInfo.new(agent_settings)
105
+ @agent_info = Core::Environment::AgentInfo.new(agent_settings, logger: @logger)
105
106
 
106
107
  @telemetry = self.class.build_telemetry(settings, agent_settings, @logger)
107
108
 
@@ -18,6 +18,10 @@ module Datadog
18
18
  ENV_DEFAULT_PORT = 'DD_METRIC_AGENT_PORT'
19
19
  end
20
20
 
21
+ module APM
22
+ ENV_TRACING_ENABLED = 'DD_APM_TRACING_ENABLED'
23
+ end
24
+
21
25
  module Agent
22
26
  ENV_DEFAULT_HOST = 'DD_AGENT_HOST'
23
27
  # Some env vars have "trace" in them, but they apply to all products
@@ -45,7 +45,7 @@ module Datadog
45
45
  option_name.to_sym => proc do
46
46
  get_option(option_name)
47
47
  end,
48
- "#{option_name}=".to_sym => proc do |value|
48
+ :"#{option_name}=" => proc do |value|
49
49
  set_option(option_name, value)
50
50
  end
51
51
  }
@@ -117,7 +117,7 @@ module Datadog
117
117
  end
118
118
 
119
119
  def resolved_env(name)
120
- return options[name].resolved_env if options.key?(name)
120
+ options[name].resolved_env if options.key?(name)
121
121
  end
122
122
 
123
123
  def assert_valid_option!(name)
@@ -570,6 +570,12 @@ module Datadog
570
570
  o.type :bool
571
571
  end
572
572
 
573
+ option :experimental_runtime_id_enabled do |o|
574
+ o.type :bool
575
+ o.env 'DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED'
576
+ o.default false
577
+ end
578
+
573
579
  option :opts, default: {}, type: :hash
574
580
  option :statsd
575
581
  end
@@ -619,38 +625,31 @@ module Datadog
619
625
  o.type :hash, nilable: true
620
626
  o.env [Core::Environment::Ext::ENV_TAGS, Core::Environment::Ext::ENV_OTEL_RESOURCE_ATTRIBUTES]
621
627
  o.env_parser do |env_value|
622
- values = if env_value.include?(',')
623
- env_value.split(',')
624
- else
625
- env_value.split(' ') # rubocop:disable Style/RedundantArgument
626
- end
627
- values.map! do |v|
628
- v.gsub!(/\A[\s,]*|[\s,]*\Z/, '')
629
-
630
- v.empty? ? nil : v
631
- end
632
-
633
- values.compact!
634
- values.each_with_object({}) do |tag, tags|
635
- key, value = tag.split(':', 2)
636
- if value.nil?
637
- # support tags/attributes delimited by the OpenTelemetry separator (`=`)
638
- key, value = tag.split('=', 2)
639
- end
640
- next if value.nil? || value.empty?
641
-
642
- # maps OpenTelemetry semantic attributes to Datadog tags
643
- case key.downcase
644
- when 'deployment.environment'
645
- tags['env'] = value
646
- when 'service.version'
647
- tags['version'] = value
648
- when 'service.name'
649
- tags['service'] = value
650
- else
651
- tags[key] = value
628
+ # Parses a string containing key-value pairs and returns a hash.
629
+ # Key-value pairs are delimited by ':' OR `=`, and pairs are separated by whitespace, comma, OR BOTH.
630
+ result = {}
631
+ unless env_value.nil? || env_value.empty?
632
+ # falling back to comma as separator
633
+ sep = env_value.include?(',') ? ',' : ' '
634
+ # split by separator
635
+ env_value.split(sep).each do |tag|
636
+ tag.strip!
637
+ next if tag.empty?
638
+
639
+ # tag by : or = (for OpenTelemetry)
640
+ key, val = tag.split(/[:=]/, 2).map(&:strip)
641
+ val ||= ''
642
+ # maps OpenTelemetry semantic attributes to Datadog tags
643
+ key = case key.downcase
644
+ when 'deployment.environment' then 'env'
645
+ when 'service.version' then 'version'
646
+ when 'service.name' then 'service'
647
+ else key
648
+ end
649
+ result[key] = val unless key.empty?
652
650
  end
653
651
  end
652
+ result
654
653
  end
655
654
  o.setter do |new_value, old_value|
656
655
  raw_tags = new_value || {}
@@ -958,6 +957,30 @@ module Datadog
958
957
  end
959
958
  end
960
959
 
960
+ # Tracer specific configuration starting with APM (e.g. DD_APM_TRACING_ENABLED).
961
+ # @public_api
962
+ settings :apm do
963
+ # Tracing as a transport
964
+ # @public_api
965
+ settings :tracing do
966
+ # Enables tracing as transport.
967
+ # Disabling it will set sampling priority to -1 (FORCE_DROP) on most traces,
968
+ # (which tells to the agent to drop these traces)
969
+ # except heartbeat ones (1 per minute) and manually kept ones (sampling priority to 2) (e.g. appsec events)
970
+ #
971
+ # This is different than `DD_TRACE_ENABLED`, which completely disables tracing (sends no trace at all),
972
+ # while this will send heartbeat traces (1 per minute) so that the service is considered alive in the backend.
973
+ #
974
+ # @default `DD_APM_TRACING_ENABLED` environment variable, otherwise `true`
975
+ # @return [Boolean]
976
+ option :enabled do |o|
977
+ o.env Configuration::Ext::APM::ENV_TRACING_ENABLED
978
+ o.default true
979
+ o.type :bool
980
+ end
981
+ end
982
+ end
983
+
961
984
  # TODO: Tracing should manage its own settings.
962
985
  # Keep this extension here for now to keep things working.
963
986
  extend Datadog::Tracing::Configuration::Settings
@@ -51,11 +51,12 @@ module Datadog
51
51
  #
52
52
  # @see https://github.com/DataDog/datadog-agent/blob/f07df0a3c1fca0c83b5a15f553bd994091b0c8ac/pkg/trace/api/info.go#L20
53
53
  class AgentInfo
54
- attr_reader :agent_settings
54
+ attr_reader :agent_settings, :logger
55
55
 
56
- def initialize(agent_settings)
56
+ def initialize(agent_settings, logger:)
57
57
  @agent_settings = agent_settings
58
- @client = Remote::Transport::HTTP.root(agent_settings: agent_settings)
58
+ @logger = logger
59
+ @client = Remote::Transport::HTTP.root(agent_settings: agent_settings, logger: logger)
59
60
  end
60
61
 
61
62
  # Fetches the information from the agent.
@@ -18,11 +18,8 @@ module Datadog
18
18
  def initialize(settings, capabilities, agent_settings, logger:)
19
19
  @logger = logger
20
20
 
21
- transport_options = {}
22
- transport_options[:agent_settings] = agent_settings if agent_settings
23
-
24
- negotiation = Negotiation.new(settings, agent_settings)
25
- transport_v7 = Datadog::Core::Remote::Transport::HTTP.v7(**transport_options) # steep:ignore
21
+ negotiation = Negotiation.new(settings, agent_settings, logger: logger)
22
+ transport_v7 = Datadog::Core::Remote::Transport::HTTP.v7(agent_settings: agent_settings, logger: logger)
26
23
 
27
24
  @barrier = Barrier.new(settings.remote.boot_timeout_seconds)
28
25
 
@@ -49,7 +46,7 @@ module Datadog
49
46
  # In case of unexpected errors, reset the negotiation object
50
47
  # given external conditions have changed and the negotiation
51
48
  # negotiation object stores error logging state that should be reset.
52
- negotiation = Negotiation.new(settings, agent_settings)
49
+ negotiation = Negotiation.new(settings, agent_settings, logger: logger)
53
50
 
54
51
  # Transient errors due to network or agent. Logged the error but not via telemetry
55
52
  logger.error do
@@ -272,7 +272,8 @@ module Datadog
272
272
 
273
273
  return deleted(path, previous) if previous && content.nil?
274
274
  return inserted(path, content) if content && previous.nil?
275
- return updated(path, content, previous) if content && previous
275
+
276
+ updated(path, content, previous) if content && previous
276
277
  end
277
278
 
278
279
  def deleted(path, previous)
@@ -7,11 +7,11 @@ module Datadog
7
7
  module Remote
8
8
  # Endpoint negotiation
9
9
  class Negotiation
10
- def initialize(_settings, agent_settings, suppress_logging: {})
11
- transport_options = {}
12
- transport_options[:agent_settings] = agent_settings if agent_settings
10
+ attr_reader :logger
13
11
 
14
- @transport_root = Datadog::Core::Remote::Transport::HTTP.root(**transport_options) # steep:ignore
12
+ def initialize(_settings, agent_settings, logger:, suppress_logging: {})
13
+ @logger = logger
14
+ @transport_root = Datadog::Core::Remote::Transport::HTTP.root(agent_settings: agent_settings, logger: logger)
15
15
  @logged = suppress_logging
16
16
  end
17
17
 
@@ -20,7 +20,7 @@ module Datadog
20
20
 
21
21
  if res.internal_error? && network_error?(res.error)
22
22
  unless @logged[:agent_unreachable]
23
- Datadog.logger.warn { "agent unreachable: cannot negotiate #{path}" }
23
+ logger.warn { "agent unreachable: cannot negotiate #{path}" }
24
24
  @logged[:agent_unreachable] = true
25
25
  end
26
26
 
@@ -29,7 +29,7 @@ module Datadog
29
29
 
30
30
  if res.not_found?
31
31
  unless @logged[:no_info_endpoint]
32
- Datadog.logger.warn { "agent reachable but has no /info endpoint: cannot negotiate #{path}" }
32
+ logger.warn { "agent reachable but has no /info endpoint: cannot negotiate #{path}" }
33
33
  @logged[:no_info_endpoint] = true
34
34
  end
35
35
 
@@ -38,7 +38,7 @@ module Datadog
38
38
 
39
39
  unless res.ok?
40
40
  unless @logged[:unexpected_response]
41
- Datadog.logger.warn { "agent reachable but unexpected response: cannot negotiate #{path}" }
41
+ logger.warn { "agent reachable but unexpected response: cannot negotiate #{path}" }
42
42
  @logged[:unexpected_response] = true
43
43
  end
44
44
 
@@ -47,14 +47,14 @@ module Datadog
47
47
 
48
48
  unless res.endpoints.include?(path)
49
49
  unless @logged[:no_config_endpoint]
50
- Datadog.logger.warn { "agent reachable but does not report #{path}" }
50
+ logger.warn { "agent reachable but does not report #{path}" }
51
51
  @logged[:no_config_endpoint] = true
52
52
  end
53
53
 
54
54
  return false
55
55
  end
56
56
 
57
- Datadog.logger.debug { "agent reachable and reports #{path}" }
57
+ logger.debug { "agent reachable and reports #{path}" }
58
58
 
59
59
  true
60
60
  end
@@ -32,12 +32,13 @@ module Datadog
32
32
 
33
33
  # Config transport
34
34
  class Transport
35
- attr_reader :client, :apis, :default_api, :current_api_id
35
+ attr_reader :client, :apis, :default_api, :current_api_id, :logger
36
36
 
37
- def initialize(apis, default_api)
37
+ def initialize(apis, default_api, logger)
38
38
  @apis = apis
39
+ @logger = logger
39
40
 
40
- @client = HTTP::Client.new(current_api)
41
+ @client = HTTP::Client.new(current_api, logger)
41
42
  end
42
43
 
43
44
  ##### there is only one transport! it's negotiation!
@@ -15,10 +15,11 @@ module Datadog
15
15
  module HTTP
16
16
  # Routes, encodes, and sends tracer data to the trace agent via HTTP.
17
17
  class Client
18
- attr_reader :api
18
+ attr_reader :api, :logger
19
19
 
20
- def initialize(api)
20
+ def initialize(api, logger)
21
21
  @api = api
22
+ @logger = logger
22
23
  end
23
24
 
24
25
  def send_request(request, &block)
@@ -32,7 +33,7 @@ module Datadog
32
33
  "Internal error during #{self.class.name} request. Cause: #{e.class.name} #{e.message} " \
33
34
  "Location: #{Array(e.backtrace).first}"
34
35
 
35
- Datadog.logger.debug(message)
36
+ logger.debug(message)
36
37
 
37
38
  Datadog::Core::Transport::InternalErrorResponse.new(e)
38
39
  end
@@ -177,51 +177,25 @@ module Datadog
177
177
  end
178
178
 
179
179
  def send_config(env, &block)
180
- raise NoConfigEndpointDefinedError, self if config.nil?
180
+ raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('config', self) if config.nil?
181
181
 
182
182
  config.call(env, &block)
183
183
  end
184
-
185
- # Raised when traces sent but no traces endpoint is defined
186
- class NoConfigEndpointDefinedError < StandardError
187
- attr_reader :spec
188
-
189
- def initialize(spec)
190
- super()
191
-
192
- @spec = spec
193
- end
194
-
195
- def message
196
- 'No config endpoint is defined for API specification!'
197
- end
198
- end
199
184
  end
200
185
 
201
186
  # Extensions for HTTP API Instance
202
187
  module Instance
203
188
  def send_config(env)
204
- raise ConfigNotSupportedError, spec unless spec.is_a?(Config::API::Spec)
189
+ unless spec.is_a?(Config::API::Spec)
190
+ raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
191
+ 'config', self
192
+ )
193
+ end
205
194
 
206
195
  spec.send_config(env) do |request_env|
207
196
  call(request_env)
208
197
  end
209
198
  end
210
-
211
- # Raised when traces sent to API that does not support traces
212
- class ConfigNotSupportedError < StandardError
213
- attr_reader :spec
214
-
215
- def initialize(spec)
216
- super()
217
-
218
- @spec = spec
219
- end
220
-
221
- def message
222
- 'Config not supported for this API!'
223
- end
224
- end
225
199
  end
226
200
 
227
201
  # Endpoint for remote configuration
@@ -50,51 +50,25 @@ module Datadog
50
50
  end
51
51
 
52
52
  def send_info(env, &block)
53
- raise NoNegotiationEndpointDefinedError, self if info.nil?
53
+ raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('info', self) if info.nil?
54
54
 
55
55
  info.call(env, &block)
56
56
  end
57
-
58
- # Raised when traces sent but no traces endpoint is defined
59
- class NoNegotiationEndpointDefinedError < StandardError
60
- attr_reader :spec
61
-
62
- def initialize(spec)
63
- super()
64
-
65
- @spec = spec
66
- end
67
-
68
- def message
69
- 'No info endpoint is defined for API specification!'
70
- end
71
- end
72
57
  end
73
58
 
74
59
  # Extensions for HTTP API Instance
75
60
  module Instance
76
61
  def send_info(env)
77
- raise NegotiationNotSupportedError, spec unless spec.is_a?(Negotiation::API::Spec)
62
+ unless spec.is_a?(Negotiation::API::Spec)
63
+ raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new(
64
+ 'info', self
65
+ )
66
+ end
78
67
 
79
68
  spec.send_info(env) do |request_env|
80
69
  call(request_env)
81
70
  end
82
71
  end
83
-
84
- # Raised when traces sent to API that does not support traces
85
- class NegotiationNotSupportedError < StandardError
86
- attr_reader :spec
87
-
88
- def initialize(spec)
89
- super()
90
-
91
- @spec = spec
92
- end
93
-
94
- def message
95
- 'Info not supported for this API!'
96
- end
97
- end
98
72
  end
99
73
 
100
74
  # Endpoint for negotiation
@@ -29,87 +29,52 @@ module Datadog
29
29
  module HTTP
30
30
  module_function
31
31
 
32
- # Builds a new Transport::HTTP::Client
33
- def new(klass, &block)
34
- Core::Transport::HTTP.build(
35
- api_instance_class: API::Instance, &block
36
- ).to_transport(klass)
37
- end
38
-
39
32
  # Builds a new Transport::HTTP::Client with default settings
40
33
  # Pass a block to override any settings.
41
34
  def root(
42
35
  agent_settings:,
43
- **options
36
+ logger:,
37
+ api_version: nil,
38
+ headers: nil
44
39
  )
45
- new(Core::Remote::Transport::Negotiation::Transport) do |transport|
46
- transport.adapter(agent_settings)
47
- transport.headers(default_headers)
48
-
40
+ Core::Transport::HTTP.build(
41
+ api_instance_class: API::Instance,
42
+ agent_settings: agent_settings,
43
+ logger: logger,
44
+ api_version: api_version,
45
+ headers: headers
46
+ ) do |transport|
49
47
  apis = API.defaults
50
48
 
51
49
  transport.api API::ROOT, apis[API::ROOT]
52
50
 
53
- # Apply any settings given by options
54
- unless options.empty?
55
- transport.default_api = options[:api_version] if options.key?(:api_version)
56
- transport.headers options[:headers] if options.key?(:headers)
57
- end
58
-
59
51
  # Call block to apply any customization, if provided
60
52
  yield(transport) if block_given?
61
- end
53
+ end.to_transport(Core::Remote::Transport::Negotiation::Transport)
62
54
  end
63
55
 
64
56
  # Builds a new Transport::HTTP::Client with default settings
65
57
  # Pass a block to override any settings.
66
58
  def v7(
67
59
  agent_settings:,
68
- **options
60
+ logger:,
61
+ api_version: nil,
62
+ headers: nil
69
63
  )
70
- new(Core::Remote::Transport::Config::Transport) do |transport|
71
- transport.adapter(agent_settings)
72
- transport.headers default_headers
73
-
64
+ Core::Transport::HTTP.build(
65
+ api_instance_class: API::Instance,
66
+ agent_settings: agent_settings,
67
+ logger: logger,
68
+ api_version: api_version,
69
+ headers: headers
70
+ ) do |transport|
74
71
  apis = API.defaults
75
72
 
76
73
  transport.api API::V7, apis[API::V7]
77
74
 
78
- # Apply any settings given by options
79
- unless options.empty?
80
- transport.default_api = options[:api_version] if options.key?(:api_version)
81
- transport.headers options[:headers] if options.key?(:headers)
82
- end
83
-
84
75
  # Call block to apply any customization, if provided
85
76
  yield(transport) if block_given?
86
- end
87
- end
88
-
89
- def default_headers
90
- {
91
- Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_TOP_LEVEL => '1',
92
- Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG => Datadog::Core::Environment::Ext::LANG,
93
- Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_VERSION =>
94
- Datadog::Core::Environment::Ext::LANG_VERSION,
95
- Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER =>
96
- Datadog::Core::Environment::Ext::LANG_INTERPRETER,
97
- Datadog::Core::Transport::Ext::HTTP::HEADER_META_TRACER_VERSION =>
98
- Datadog::Core::Environment::Ext::GEM_DATADOG_VERSION
99
- }.tap do |headers|
100
- # Add container ID, if present.
101
- container_id = Datadog::Core::Environment::Container.container_id
102
- headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id unless container_id.nil?
103
- # Sending this header to the agent will disable metrics computation (and billing) on the agent side
104
- # by pretending it has already been done on the library side.
105
- if Datadog.configuration.appsec.standalone.enabled
106
- headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
107
- end
108
- end
109
- end
110
-
111
- def default_adapter
112
- Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
77
+ end.to_transport(Core::Remote::Transport::Config::Transport)
113
78
  end
114
79
  end
115
80
  end
@@ -49,12 +49,13 @@ module Datadog
49
49
 
50
50
  # Negotiation transport
51
51
  class Transport
52
- attr_reader :client, :apis, :default_api, :current_api_id
52
+ attr_reader :client, :apis, :default_api, :current_api_id, :logger
53
53
 
54
- def initialize(apis, default_api)
54
+ def initialize(apis, default_api, logger)
55
55
  @apis = apis
56
+ @logger = logger
56
57
 
57
- @client = HTTP::Client.new(current_api)
58
+ @client = HTTP::Client.new(current_api, logger)
58
59
  end
59
60
 
60
61
  def send_info
@@ -21,6 +21,9 @@ module Datadog
21
21
  @services = Set.new(options.fetch(:services, []))
22
22
  @service_tags = nil
23
23
  compile_service_tags!
24
+
25
+ # Initialize the collection of runtime-id
26
+ @runtime_id_enabled = options.fetch(:experimental_runtime_id_enabled, false)
24
27
  end
25
28
 
26
29
  # Associate service with runtime metrics
@@ -105,6 +108,9 @@ module Datadog
105
108
 
106
109
  # Add services dynamically because they might change during runtime.
107
110
  options[:tags].concat(service_tags) unless service_tags.nil?
111
+
112
+ # Add runtime-id dynamically because it might change during runtime.
113
+ options[:tags].concat(["runtime-id:#{Core::Environment::Identity.id}"]) if @runtime_id_enabled
108
114
  end
109
115
  end
110
116
 
@@ -112,7 +118,8 @@ module Datadog
112
118
 
113
119
  attr_reader \
114
120
  :service_tags,
115
- :services
121
+ :services,
122
+ :runtime_id_enabled
116
123
 
117
124
  def compile_service_tags!
118
125
  @service_tags = services.to_a.collect do |service|
@@ -21,7 +21,7 @@ module Datadog
21
21
  @hostname = hostname
22
22
  @port = port
23
23
  @timeout = timeout
24
- @ssl = ssl.nil? ? true : ssl
24
+ @ssl = ssl.nil? || ssl
25
25
  end
26
26
 
27
27
  def open(&block)