datadog 2.11.0 → 2.12.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -2
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +23 -6
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +63 -12
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +39 -0
- data/lib/datadog/appsec.rb +1 -0
- data/lib/datadog/core/configuration/components.rb +10 -9
- data/lib/datadog/core/metrics/client.rb +9 -8
- data/lib/datadog/core/remote/client.rb +5 -4
- data/lib/datadog/core/remote/component.rb +14 -12
- data/lib/datadog/core/remote/negotiation.rb +1 -1
- data/lib/datadog/core/remote/transport/http.rb +4 -33
- data/lib/datadog/core/remote/worker.rb +10 -7
- data/lib/datadog/core/telemetry/component.rb +5 -1
- data/lib/datadog/core/telemetry/worker.rb +9 -5
- data/lib/datadog/core/transport/http.rb +38 -0
- data/lib/datadog/core/workers/runtime_metrics.rb +1 -1
- data/lib/datadog/di/component.rb +1 -3
- data/lib/datadog/di/probe_notifier_worker.rb +20 -4
- data/lib/datadog/di/transport/diagnostics.rb +61 -0
- data/lib/datadog/di/transport/http/api.rb +52 -0
- data/lib/datadog/di/transport/http/client.rb +46 -0
- data/lib/datadog/di/transport/http/diagnostics.rb +92 -0
- data/lib/datadog/di/transport/http/input.rb +94 -0
- data/lib/datadog/di/transport/http.rb +105 -0
- data/lib/datadog/di/transport/input.rb +61 -0
- data/lib/datadog/di.rb +2 -1
- data/lib/datadog/tracing/component.rb +1 -0
- data/lib/datadog/tracing/sync_writer.rb +9 -4
- data/lib/datadog/tracing/tracer.rb +15 -7
- data/lib/datadog/tracing/transport/http.rb +3 -32
- data/lib/datadog/tracing/workers/trace_writer.rb +10 -3
- data/lib/datadog/tracing/workers.rb +5 -4
- data/lib/datadog/tracing/writer.rb +12 -4
- data/lib/datadog/version.rb +2 -2
- metadata +15 -5
- data/lib/datadog/di/transport.rb +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d150a054dd119a853c1f7c0653a2ea2dedb1b20ce4b538168ead98ed3abc8720
|
4
|
+
data.tar.gz: 69ff582e245644c0c867d48ecd20fd2b493fc97b778235d163bef193aa8ea298
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8845d2c09585196054cdf50b353dbf1a226a58d468c3ed9c99b8a12bfa12e659b41c4e67abf6e20288fa740692c9bd4ea874004e523bbe29b1a30b6bc997a53b
|
7
|
+
data.tar.gz: c4e4b6a42acc8af8675287440b437db002201d5eb5a1371e141b6ffdef82c752f063f8c4fd679fdaa4196530612bdc066e81897a1c14c41ec62ac77e65afafe2
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,19 @@
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## [2.12.1] - 2025-03-05
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
|
9
|
+
* AppSec: Fix `ArgumentError` from ActiveRecord for Ruby < 2.7 ([#4437][])
|
10
|
+
|
11
|
+
## [2.12.0] - 2025-02-27
|
12
|
+
|
13
|
+
### Added
|
14
|
+
|
15
|
+
* AppSec: Add detection of Server-Side Request Forgery attacks for `rest-client` ([#4424][])
|
16
|
+
* Dynamic Instrumentation: Add support for unix domain sockets ([#4426][])
|
17
|
+
|
5
18
|
## [2.11.0] - 2025-02-24
|
6
19
|
|
7
20
|
### Added
|
@@ -3126,7 +3139,9 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
|
|
3126
3139
|
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
3127
3140
|
|
3128
3141
|
|
3129
|
-
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.
|
3142
|
+
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.12.1...master
|
3143
|
+
[2.12.1]: https://github.com/DataDog/dd-trace-rb/compare/v2.12.0...v2.12.1
|
3144
|
+
[2.12.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.11.0...v2.12.0
|
3130
3145
|
[2.11.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.10.0...v2.11.0
|
3131
3146
|
[2.10.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.9.0...v2.10.0
|
3132
3147
|
[2.9.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.8.0...v2.9.0
|
@@ -4624,7 +4639,10 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
4624
4639
|
[#4406]: https://github.com/DataDog/dd-trace-rb/issues/4406
|
4625
4640
|
[#4411]: https://github.com/DataDog/dd-trace-rb/issues/4411
|
4626
4641
|
[#4422]: https://github.com/DataDog/dd-trace-rb/issues/4422
|
4642
|
+
[#4424]: https://github.com/DataDog/dd-trace-rb/issues/4424
|
4627
4643
|
[#4425]: https://github.com/DataDog/dd-trace-rb/issues/4425
|
4644
|
+
[#4426]: https://github.com/DataDog/dd-trace-rb/issues/4426
|
4645
|
+
[#4437]: https://github.com/DataDog/dd-trace-rb/issues/4437
|
4628
4646
|
[@AdrianLC]: https://github.com/AdrianLC
|
4629
4647
|
[@Azure7111]: https://github.com/Azure7111
|
4630
4648
|
[@BabyGroot]: https://github.com/BabyGroot
|
@@ -4776,4 +4794,4 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
4776
4794
|
[@y-yagi]: https://github.com/y-yagi
|
4777
4795
|
[@yujideveloper]: https://github.com/yujideveloper
|
4778
4796
|
[@yukimurasawa]: https://github.com/yukimurasawa
|
4779
|
-
[@zachmccormick]: https://github.com/zachmccormick
|
4797
|
+
[@zachmccormick]: https://github.com/zachmccormick
|
@@ -43,7 +43,7 @@ module Datadog
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
# patch for
|
46
|
+
# patch for mysql2, sqlite3, and postgres+jdbc adapters in ActiveRecord >= 7.1
|
47
47
|
module InternalExecQueryAdapterPatch
|
48
48
|
def internal_exec_query(sql, *args, **rest)
|
49
49
|
Instrumentation.detect_sql_injection(sql, adapter_name)
|
@@ -52,7 +52,25 @@ module Datadog
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
# patch for postgres
|
55
|
+
# patch for mysql2, sqlite3, and postgres+jdbc adapters in ActiveRecord < 7.1
|
56
|
+
module ExecQueryAdapterPatch
|
57
|
+
def exec_query(sql, *args, **rest)
|
58
|
+
Instrumentation.detect_sql_injection(sql, adapter_name)
|
59
|
+
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# patch for mysql2, sqlite3, and postgres+jdbc db adapters in ActiveRecord 4
|
65
|
+
module Rails4ExecQueryAdapterPatch
|
66
|
+
def exec_query(sql, *args)
|
67
|
+
Instrumentation.detect_sql_injection(sql, adapter_name)
|
68
|
+
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# patch for non-jdbc postgres adapter in ActiveRecord > 4
|
56
74
|
module ExecuteAndClearAdapterPatch
|
57
75
|
def execute_and_clear(sql, *args, **rest)
|
58
76
|
Instrumentation.detect_sql_injection(sql, adapter_name)
|
@@ -61,10 +79,9 @@ module Datadog
|
|
61
79
|
end
|
62
80
|
end
|
63
81
|
|
64
|
-
# patch for
|
65
|
-
|
66
|
-
|
67
|
-
def exec_query(sql, *args, **rest)
|
82
|
+
# patch for non-jdbc postgres adapter in ActiveRecord 4
|
83
|
+
module Rails4ExecuteAndClearAdapterPatch
|
84
|
+
def execute_and_clear(sql, name, binds)
|
68
85
|
Instrumentation.detect_sql_injection(sql, adapter_name)
|
69
86
|
|
70
87
|
super
|
@@ -19,30 +19,81 @@ module Datadog
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def patch
|
22
|
+
# Rails 7.0 intruduced new on-load hooks for sqlite3 and postgresql adapters
|
23
|
+
# The load hook for mysql2 adapter was introduced in Rails 7.1
|
24
|
+
#
|
25
|
+
# If the adapter is not loaded when the :active_record load hook is called,
|
26
|
+
# we need to add a load hook for the adapter
|
22
27
|
ActiveSupport.on_load :active_record do
|
23
|
-
instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
|
24
|
-
Instrumentation::InternalExecQueryAdapterPatch
|
25
|
-
else
|
26
|
-
Instrumentation::ExecQueryAdapterPatch
|
27
|
-
end
|
28
|
-
|
29
28
|
if defined?(::ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
30
|
-
::ActiveRecord::
|
29
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_sqlite3_adapter
|
30
|
+
else
|
31
|
+
ActiveSupport.on_load :active_record_sqlite3adapter do
|
32
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_sqlite3_adapter
|
33
|
+
end
|
31
34
|
end
|
32
35
|
|
33
36
|
if defined?(::ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
34
|
-
::ActiveRecord::
|
37
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_mysql2_adapter
|
38
|
+
else
|
39
|
+
ActiveSupport.on_load :active_record_mysql2adapter do
|
40
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_mysql2_adapter
|
41
|
+
end
|
35
42
|
end
|
36
43
|
|
37
44
|
if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
38
|
-
|
39
|
-
|
45
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_postgresql_adapter
|
46
|
+
else
|
47
|
+
ActiveSupport.on_load :active_record_postgresqladapter do
|
48
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_postgresql_adapter
|
40
49
|
end
|
41
|
-
|
42
|
-
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(instrumentation_module)
|
43
50
|
end
|
44
51
|
end
|
45
52
|
end
|
53
|
+
|
54
|
+
def patch_sqlite3_adapter
|
55
|
+
instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
|
56
|
+
Instrumentation::InternalExecQueryAdapterPatch
|
57
|
+
elsif ::ActiveRecord.gem_version.segments.first == 4
|
58
|
+
Instrumentation::Rails4ExecQueryAdapterPatch
|
59
|
+
else
|
60
|
+
Instrumentation::ExecQueryAdapterPatch
|
61
|
+
end
|
62
|
+
|
63
|
+
::ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(instrumentation_module)
|
64
|
+
end
|
65
|
+
|
66
|
+
def patch_mysql2_adapter
|
67
|
+
instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
|
68
|
+
Instrumentation::InternalExecQueryAdapterPatch
|
69
|
+
elsif ::ActiveRecord.gem_version.segments.first == 4
|
70
|
+
Instrumentation::Rails4ExecQueryAdapterPatch
|
71
|
+
else
|
72
|
+
Instrumentation::ExecQueryAdapterPatch
|
73
|
+
end
|
74
|
+
|
75
|
+
::ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(instrumentation_module)
|
76
|
+
end
|
77
|
+
|
78
|
+
def patch_postgresql_adapter
|
79
|
+
instrumentation_module = if ::ActiveRecord.gem_version.segments.first == 4
|
80
|
+
Instrumentation::Rails4ExecuteAndClearAdapterPatch
|
81
|
+
else
|
82
|
+
Instrumentation::ExecuteAndClearAdapterPatch
|
83
|
+
end
|
84
|
+
|
85
|
+
if defined?(::ActiveRecord::ConnectionAdapters::JdbcAdapter)
|
86
|
+
instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
|
87
|
+
Instrumentation::InternalExecQueryAdapterPatch
|
88
|
+
elsif ::ActiveRecord.gem_version.segments.first == 4
|
89
|
+
Instrumentation::Rails4ExecQueryAdapterPatch
|
90
|
+
else
|
91
|
+
Instrumentation::ExecQueryAdapterPatch
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(instrumentation_module)
|
96
|
+
end
|
46
97
|
end
|
47
98
|
end
|
48
99
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../integration'
|
4
|
+
require_relative 'patcher'
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module AppSec
|
8
|
+
module Contrib
|
9
|
+
module RestClient
|
10
|
+
# This class defines properties of rest-client AppSec integration
|
11
|
+
class Integration
|
12
|
+
include Datadog::AppSec::Contrib::Integration
|
13
|
+
|
14
|
+
MINIMUM_VERSION = Gem::Version.new('1.8')
|
15
|
+
|
16
|
+
register_as :rest_client
|
17
|
+
|
18
|
+
def self.gem_name
|
19
|
+
'rest-client'
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.version
|
23
|
+
Gem.loaded_specs['rest-client'] && Gem.loaded_specs['rest-client'].version
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.loaded?
|
27
|
+
!defined?(::RestClient::Request).nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.compatible?
|
31
|
+
super && version >= MINIMUM_VERSION
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.auto_instrument?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
def patcher
|
39
|
+
Patcher
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module Contrib
|
6
|
+
module RestClient
|
7
|
+
# Patcher for RestClient gem
|
8
|
+
module Patcher
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def patched?
|
12
|
+
Patcher.instance_variable_get(:@patched)
|
13
|
+
end
|
14
|
+
|
15
|
+
def target_version
|
16
|
+
Integration.version
|
17
|
+
end
|
18
|
+
|
19
|
+
def patch
|
20
|
+
require_relative 'request_ssrf_detection_patch'
|
21
|
+
|
22
|
+
::RestClient::Request.prepend(RequestSSRFDetectionPatch)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# rubocop:disable Naming/FileName
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Datadog
|
5
|
+
module AppSec
|
6
|
+
module Contrib
|
7
|
+
module RestClient
|
8
|
+
# Module that adds SSRF detection to RestClient::Request#execute
|
9
|
+
module RequestSSRFDetectionPatch
|
10
|
+
def execute(&block)
|
11
|
+
return super unless AppSec.rasp_enabled? && AppSec.active_context
|
12
|
+
|
13
|
+
context = AppSec.active_context
|
14
|
+
|
15
|
+
ephemeral_data = { 'server.io.net.url' => url }
|
16
|
+
result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, Datadog.configuration.appsec.waf_timeout)
|
17
|
+
|
18
|
+
if result.match?
|
19
|
+
Datadog::AppSec::Event.tag_and_keep!(context, result)
|
20
|
+
|
21
|
+
context.events << {
|
22
|
+
waf_result: result,
|
23
|
+
trace: context.trace,
|
24
|
+
span: context.span,
|
25
|
+
request_url: url,
|
26
|
+
actions: result.actions
|
27
|
+
}
|
28
|
+
|
29
|
+
ActionsHandler.handle(result.actions)
|
30
|
+
end
|
31
|
+
|
32
|
+
super(&block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
# rubocop:enable Naming/FileName
|
data/lib/datadog/appsec.rb
CHANGED
@@ -70,5 +70,6 @@ require_relative 'appsec/contrib/devise/integration'
|
|
70
70
|
require_relative 'appsec/contrib/graphql/integration'
|
71
71
|
require_relative 'appsec/contrib/faraday/integration'
|
72
72
|
require_relative 'appsec/contrib/excon/integration'
|
73
|
+
require_relative 'appsec/contrib/rest_client/integration'
|
73
74
|
|
74
75
|
require_relative 'appsec/autoload'
|
@@ -26,12 +26,12 @@ module Datadog
|
|
26
26
|
class << self
|
27
27
|
include Datadog::Tracing::Component
|
28
28
|
|
29
|
-
def build_health_metrics(settings)
|
29
|
+
def build_health_metrics(settings, logger)
|
30
30
|
settings = settings.health_metrics
|
31
31
|
options = { enabled: settings.enabled }
|
32
32
|
options[:statsd] = settings.statsd unless settings.statsd.nil?
|
33
33
|
|
34
|
-
Core::Diagnostics::Health::Metrics.new(**options)
|
34
|
+
Core::Diagnostics::Health::Metrics.new(logger: logger, **options)
|
35
35
|
end
|
36
36
|
|
37
37
|
def build_logger(settings)
|
@@ -41,19 +41,20 @@ module Datadog
|
|
41
41
|
logger
|
42
42
|
end
|
43
43
|
|
44
|
-
def build_runtime_metrics(settings)
|
44
|
+
def build_runtime_metrics(settings, logger)
|
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
48
|
|
49
|
-
Core::Runtime::Metrics.new(**options)
|
49
|
+
Core::Runtime::Metrics.new(logger: logger, **options)
|
50
50
|
end
|
51
51
|
|
52
|
-
def build_runtime_metrics_worker(settings)
|
52
|
+
def build_runtime_metrics_worker(settings, logger)
|
53
53
|
# NOTE: Should we just ignore building the worker if its not enabled?
|
54
54
|
options = settings.runtime_metrics.opts.merge(
|
55
55
|
enabled: settings.runtime_metrics.enabled,
|
56
|
-
metrics: build_runtime_metrics(settings)
|
56
|
+
metrics: build_runtime_metrics(settings, logger),
|
57
|
+
logger: logger,
|
57
58
|
)
|
58
59
|
|
59
60
|
Core::Workers::RuntimeMetrics.new(options)
|
@@ -104,7 +105,7 @@ module Datadog
|
|
104
105
|
|
105
106
|
@telemetry = self.class.build_telemetry(settings, agent_settings, @logger)
|
106
107
|
|
107
|
-
@remote = Remote::Component.build(settings, agent_settings, telemetry: telemetry)
|
108
|
+
@remote = Remote::Component.build(settings, agent_settings, logger: @logger, telemetry: telemetry)
|
108
109
|
@tracer = self.class.build_tracer(settings, agent_settings, logger: @logger)
|
109
110
|
@crashtracker = self.class.build_crashtracker(settings, agent_settings, logger: @logger)
|
110
111
|
|
@@ -116,8 +117,8 @@ module Datadog
|
|
116
117
|
)
|
117
118
|
@environment_logger_extra.merge!(profiler_logger_extra) if profiler_logger_extra
|
118
119
|
|
119
|
-
@runtime_metrics = self.class.build_runtime_metrics_worker(settings)
|
120
|
-
@health_metrics = self.class.build_health_metrics(settings)
|
120
|
+
@runtime_metrics = self.class.build_runtime_metrics_worker(settings, @logger)
|
121
|
+
@health_metrics = self.class.build_health_metrics(settings, @logger)
|
121
122
|
@appsec = Datadog::AppSec::Component.build_appsec_component(settings, telemetry: telemetry)
|
122
123
|
@dynamic_instrumentation = Datadog::DI::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
|
123
124
|
@environment_logger_extra[:dynamic_instrumentation_enabled] = !!@dynamic_instrumentation
|
@@ -21,9 +21,10 @@ module Datadog
|
|
21
21
|
extend Options
|
22
22
|
extend Helpers
|
23
23
|
|
24
|
-
attr_reader :statsd
|
24
|
+
attr_reader :statsd, :logger
|
25
25
|
|
26
|
-
def initialize(statsd: nil, enabled: true, **_)
|
26
|
+
def initialize(logger:, statsd: nil, enabled: true, **_)
|
27
|
+
@logger = logger
|
27
28
|
@statsd =
|
28
29
|
if supported?
|
29
30
|
statsd || default_statsd_client
|
@@ -98,7 +99,7 @@ module Datadog
|
|
98
99
|
|
99
100
|
statsd.count(stat, value, metric_options(options))
|
100
101
|
rescue StandardError => e
|
101
|
-
|
102
|
+
logger.error(
|
102
103
|
"Failed to send count stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
103
104
|
)
|
104
105
|
Telemetry::Logger.report(e, description: 'Failed to send count stat')
|
@@ -112,7 +113,7 @@ module Datadog
|
|
112
113
|
|
113
114
|
statsd.distribution(stat, value, metric_options(options))
|
114
115
|
rescue StandardError => e
|
115
|
-
|
116
|
+
logger.error(
|
116
117
|
"Failed to send distribution stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
117
118
|
)
|
118
119
|
Telemetry::Logger.report(e, description: 'Failed to send distribution stat')
|
@@ -125,7 +126,7 @@ module Datadog
|
|
125
126
|
|
126
127
|
statsd.increment(stat, metric_options(options))
|
127
128
|
rescue StandardError => e
|
128
|
-
|
129
|
+
logger.error(
|
129
130
|
"Failed to send increment stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
130
131
|
)
|
131
132
|
Telemetry::Logger.report(e, description: 'Failed to send increment stat')
|
@@ -139,7 +140,7 @@ module Datadog
|
|
139
140
|
|
140
141
|
statsd.gauge(stat, value, metric_options(options))
|
141
142
|
rescue StandardError => e
|
142
|
-
|
143
|
+
logger.error(
|
143
144
|
"Failed to send gauge stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
144
145
|
)
|
145
146
|
Telemetry::Logger.report(e, description: 'Failed to send gauge stat')
|
@@ -159,7 +160,7 @@ module Datadog
|
|
159
160
|
end
|
160
161
|
rescue StandardError => e
|
161
162
|
# TODO: Likely to be redundant, since `distribution` handles its own errors.
|
162
|
-
|
163
|
+
logger.error(
|
163
164
|
"Failed to send time stat. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
|
164
165
|
)
|
165
166
|
Telemetry::Logger.report(e, description: 'Failed to send time stat')
|
@@ -194,7 +195,7 @@ module Datadog
|
|
194
195
|
|
195
196
|
def ignored_statsd_warning
|
196
197
|
IGNORED_STATSD_ONLY_ONCE.run do
|
197
|
-
|
198
|
+
logger.warn(
|
198
199
|
'Ignoring user-supplied statsd instance as currently-installed version of dogstastd-ruby is incompatible. ' \
|
199
200
|
"To fix this, ensure that you have `gem 'dogstatsd-ruby', '~> 5.3'` on your Gemfile or gems.rb file."
|
200
201
|
)
|
@@ -13,10 +13,11 @@ module Datadog
|
|
13
13
|
class TransportError < StandardError; end
|
14
14
|
class SyncError < StandardError; end
|
15
15
|
|
16
|
-
attr_reader :transport, :repository, :id, :dispatcher
|
16
|
+
attr_reader :transport, :repository, :id, :dispatcher, :logger
|
17
17
|
|
18
|
-
def initialize(transport, capabilities, repository: Configuration::Repository.new)
|
18
|
+
def initialize(transport, capabilities, logger:, repository: Configuration::Repository.new)
|
19
19
|
@transport = transport
|
20
|
+
@logger = logger
|
20
21
|
|
21
22
|
@repository = repository
|
22
23
|
@id = SecureRandom.uuid
|
@@ -40,7 +41,7 @@ module Datadog
|
|
40
41
|
def process_response(response)
|
41
42
|
# when response is completely empty, do nothing as in: leave as is
|
42
43
|
if response.empty?
|
43
|
-
|
44
|
+
logger.debug { 'remote: empty response => NOOP' }
|
44
45
|
|
45
46
|
return
|
46
47
|
end
|
@@ -112,7 +113,7 @@ module Datadog
|
|
112
113
|
end
|
113
114
|
|
114
115
|
if changes.empty?
|
115
|
-
|
116
|
+
logger.debug { 'remote: no changes' }
|
116
117
|
else
|
117
118
|
dispatcher.dispatch(changes, repository)
|
118
119
|
end
|
@@ -13,22 +13,24 @@ module Datadog
|
|
13
13
|
# Configures the HTTP transport to communicate with the agent
|
14
14
|
# to fetch and sync the remote configuration
|
15
15
|
class Component
|
16
|
-
attr_reader :client, :healthy
|
16
|
+
attr_reader :logger, :client, :healthy
|
17
|
+
|
18
|
+
def initialize(settings, capabilities, agent_settings, logger:)
|
19
|
+
@logger = logger
|
17
20
|
|
18
|
-
def initialize(settings, capabilities, agent_settings)
|
19
21
|
transport_options = {}
|
20
22
|
transport_options[:agent_settings] = agent_settings if agent_settings
|
21
23
|
|
22
24
|
negotiation = Negotiation.new(settings, agent_settings)
|
23
|
-
transport_v7 = Datadog::Core::Remote::Transport::HTTP.v7(**transport_options
|
25
|
+
transport_v7 = Datadog::Core::Remote::Transport::HTTP.v7(**transport_options) # steep:ignore
|
24
26
|
|
25
27
|
@barrier = Barrier.new(settings.remote.boot_timeout_seconds)
|
26
28
|
|
27
|
-
@client = Client.new(transport_v7, capabilities)
|
29
|
+
@client = Client.new(transport_v7, capabilities, logger: logger)
|
28
30
|
@healthy = false
|
29
|
-
|
31
|
+
logger.debug { "new remote configuration client: #{@client.id}" }
|
30
32
|
|
31
|
-
@worker = Worker.new(interval: settings.remote.poll_interval_seconds) do
|
33
|
+
@worker = Worker.new(interval: settings.remote.poll_interval_seconds, logger: logger) do
|
32
34
|
unless @healthy || negotiation.endpoint?('/v0.7/config')
|
33
35
|
@barrier.lift
|
34
36
|
|
@@ -40,7 +42,7 @@ module Datadog
|
|
40
42
|
@healthy ||= true
|
41
43
|
rescue Client::SyncError => e
|
42
44
|
# Transient errors due to network or agent. Logged the error but not via telemetry
|
43
|
-
|
45
|
+
logger.error do
|
44
46
|
"remote worker client sync error: #{e.message} location: #{Array(e.backtrace).first}. skipping sync"
|
45
47
|
end
|
46
48
|
rescue StandardError => e
|
@@ -50,15 +52,15 @@ module Datadog
|
|
50
52
|
negotiation = Negotiation.new(settings, agent_settings)
|
51
53
|
|
52
54
|
# Transient errors due to network or agent. Logged the error but not via telemetry
|
53
|
-
|
55
|
+
logger.error do
|
54
56
|
"remote worker error: #{e.class.name} #{e.message} location: #{Array(e.backtrace).first}. "\
|
55
57
|
'reseting client state'
|
56
58
|
end
|
57
59
|
|
58
60
|
# client state is unknown, state might be corrupted
|
59
|
-
@client = Client.new(transport_v7, capabilities)
|
61
|
+
@client = Client.new(transport_v7, capabilities, logger: logger)
|
60
62
|
@healthy = false
|
61
|
-
|
63
|
+
logger.debug { "new remote configuration client: #{@client.id}" }
|
62
64
|
|
63
65
|
# TODO: bail out if too many errors?
|
64
66
|
end
|
@@ -152,10 +154,10 @@ module Datadog
|
|
152
154
|
#
|
153
155
|
# Those checks are instead performed inside the worker loop.
|
154
156
|
# This allows users to upgrade their agent while keeping their application running.
|
155
|
-
def build(settings, agent_settings, telemetry:)
|
157
|
+
def build(settings, agent_settings, logger:, telemetry:)
|
156
158
|
return unless settings.remote.enabled
|
157
159
|
|
158
|
-
new(settings, Client::Capabilities.new(settings, telemetry), agent_settings)
|
160
|
+
new(settings, Client::Capabilities.new(settings, telemetry), agent_settings, logger: logger)
|
159
161
|
end
|
160
162
|
end
|
161
163
|
end
|
@@ -11,7 +11,7 @@ module Datadog
|
|
11
11
|
transport_options = {}
|
12
12
|
transport_options[:agent_settings] = agent_settings if agent_settings
|
13
13
|
|
14
|
-
@transport_root = Datadog::Core::Remote::Transport::HTTP.root(**transport_options
|
14
|
+
@transport_root = Datadog::Core::Remote::Transport::HTTP.root(**transport_options) # steep:ignore
|
15
15
|
@logged = suppress_logging
|
16
16
|
end
|
17
17
|
|
@@ -1,14 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'uri'
|
4
|
-
|
5
3
|
require_relative '../../environment/container'
|
6
4
|
require_relative '../../environment/ext'
|
7
5
|
require_relative '../../transport/ext'
|
8
|
-
require_relative '../../transport/http
|
9
|
-
require_relative '../../transport/http/adapters/net'
|
10
|
-
require_relative '../../transport/http/adapters/unix_socket'
|
11
|
-
require_relative '../../transport/http/adapters/test'
|
6
|
+
require_relative '../../transport/http'
|
12
7
|
|
13
8
|
# TODO: Improve negotiation to allow per endpoint selection
|
14
9
|
#
|
@@ -32,21 +27,11 @@ module Datadog
|
|
32
27
|
module Transport
|
33
28
|
# Namespace for HTTP transport components
|
34
29
|
module HTTP
|
35
|
-
# NOTE: Due to... legacy reasons... This class likes having a default `AgentSettings` instance to fall back to.
|
36
|
-
# Because we generate this instance with an empty instance of `Settings`, the resulting `AgentSettings` below
|
37
|
-
# represents only settings specified via environment variables + the usual defaults.
|
38
|
-
#
|
39
|
-
# DO NOT USE THIS IN NEW CODE, as it ignores any settings specified by users via `Datadog.configure`.
|
40
|
-
DO_NOT_USE_ENVIRONMENT_AGENT_SETTINGS = Datadog::Core::Configuration::AgentSettingsResolver.call(
|
41
|
-
Datadog::Core::Configuration::Settings.new,
|
42
|
-
logger: nil,
|
43
|
-
)
|
44
|
-
|
45
30
|
module_function
|
46
31
|
|
47
32
|
# Builds a new Transport::HTTP::Client
|
48
33
|
def new(klass, &block)
|
49
|
-
Core::Transport::HTTP
|
34
|
+
Core::Transport::HTTP.build(
|
50
35
|
api_instance_class: API::Instance, &block
|
51
36
|
).to_transport(klass)
|
52
37
|
end
|
@@ -54,7 +39,7 @@ module Datadog
|
|
54
39
|
# Builds a new Transport::HTTP::Client with default settings
|
55
40
|
# Pass a block to override any settings.
|
56
41
|
def root(
|
57
|
-
agent_settings
|
42
|
+
agent_settings:,
|
58
43
|
**options
|
59
44
|
)
|
60
45
|
new(Core::Remote::Transport::Negotiation::Transport) do |transport|
|
@@ -79,7 +64,7 @@ module Datadog
|
|
79
64
|
# Builds a new Transport::HTTP::Client with default settings
|
80
65
|
# Pass a block to override any settings.
|
81
66
|
def v7(
|
82
|
-
agent_settings
|
67
|
+
agent_settings:,
|
83
68
|
**options
|
84
69
|
)
|
85
70
|
new(Core::Remote::Transport::Config::Transport) do |transport|
|
@@ -126,20 +111,6 @@ module Datadog
|
|
126
111
|
def default_adapter
|
127
112
|
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
128
113
|
end
|
129
|
-
|
130
|
-
# Add adapters to registry
|
131
|
-
Core::Transport::HTTP::Builder::REGISTRY.set(
|
132
|
-
Datadog::Core::Transport::HTTP::Adapters::Net,
|
133
|
-
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
134
|
-
)
|
135
|
-
Core::Transport::HTTP::Builder::REGISTRY.set(
|
136
|
-
Datadog::Core::Transport::HTTP::Adapters::Test,
|
137
|
-
Datadog::Core::Transport::Ext::Test::ADAPTER
|
138
|
-
)
|
139
|
-
Core::Transport::HTTP::Builder::REGISTRY.set(
|
140
|
-
Datadog::Core::Transport::HTTP::Adapters::UnixSocket,
|
141
|
-
Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER
|
142
|
-
)
|
143
114
|
end
|
144
115
|
end
|
145
116
|
end
|