datadog 2.12.0 → 2.12.2
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 +17 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +8 -0
- 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/rack/ext.rb +20 -0
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +20 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +3 -0
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
- data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
- data/lib/datadog/appsec/processor/rule_merger.rb +2 -1
- data/lib/datadog/appsec/remote.rb +7 -0
- data/lib/datadog/core/configuration/components.rb +9 -8
- 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 +3 -3
- data/lib/datadog/core/remote/negotiation.rb +1 -1
- data/lib/datadog/core/remote/transport/http.rb +4 -33
- data/lib/datadog/core/transport/http.rb +38 -0
- data/lib/datadog/core/workers/runtime_metrics.rb +1 -1
- data/lib/datadog/di/transport/http.rb +2 -16
- data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
- data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
- data/lib/datadog/tracing/metadata.rb +2 -0
- data/lib/datadog/tracing/span.rb +10 -1
- data/lib/datadog/tracing/span_operation.rb +6 -1
- data/lib/datadog/tracing/sync_writer.rb +4 -2
- data/lib/datadog/tracing/tracer.rb +6 -1
- data/lib/datadog/tracing/transport/http.rb +3 -32
- data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
- data/lib/datadog/tracing/workers/trace_writer.rb +6 -2
- data/lib/datadog/tracing/writer.rb +6 -2
- data/lib/datadog/version.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a27bb8e1291ee014e342297fc3d53aca8a895017281201b1b0a29cd376ba905
|
4
|
+
data.tar.gz: e26c326437e4edcbdfac0ad604514a48c23c31500a68dcc4affb53251aed5f8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8dab2f6ed8bc48fb95a4c9c3c28fce16b8eaaceb70179ee12b9a009498dabe498d73b08a25180fdb53642fc78da4388b2c80bbf76a61afd25af53449f2e9375
|
7
|
+
data.tar.gz: 4489a8e084f7873e59b4d2a13d27b9a75f2b95ae0c9b5129edfdb02a58c736890bd5226df765de216010512b9fd0ffad6f82cc373ea8ee995340ef838c721d65
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## [2.12.2] - 2025-03-17
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
|
9
|
+
* AppSec: Fix custom In-App WAF blocking response that was configured in the UI is now applied correctly ([#4497][])
|
10
|
+
|
11
|
+
## [2.12.1] - 2025-03-05
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
* AppSec: Fix `ArgumentError` from ActiveRecord for Ruby < 2.7 ([#4437][])
|
16
|
+
|
5
17
|
## [2.12.0] - 2025-02-27
|
6
18
|
|
7
19
|
### Added
|
@@ -3133,7 +3145,9 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
|
|
3133
3145
|
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
3134
3146
|
|
3135
3147
|
|
3136
|
-
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.12.
|
3148
|
+
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.12.2...master
|
3149
|
+
[2.12.2]: https://github.com/DataDog/dd-trace-rb/compare/v2.12.1...v2.12.2
|
3150
|
+
[2.12.1]: https://github.com/DataDog/dd-trace-rb/compare/v2.12.0...v2.12.1
|
3137
3151
|
[2.12.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.11.0...v2.12.0
|
3138
3152
|
[2.11.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.10.0...v2.11.0
|
3139
3153
|
[2.10.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.9.0...v2.10.0
|
@@ -4635,6 +4649,8 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
4635
4649
|
[#4424]: https://github.com/DataDog/dd-trace-rb/issues/4424
|
4636
4650
|
[#4425]: https://github.com/DataDog/dd-trace-rb/issues/4425
|
4637
4651
|
[#4426]: https://github.com/DataDog/dd-trace-rb/issues/4426
|
4652
|
+
[#4437]: https://github.com/DataDog/dd-trace-rb/issues/4437
|
4653
|
+
[#4497]: https://github.com/DataDog/dd-trace-rb/issues/4497
|
4638
4654
|
[@AdrianLC]: https://github.com/AdrianLC
|
4639
4655
|
[@Azure7111]: https://github.com/Azure7111
|
4640
4656
|
[@BabyGroot]: https://github.com/BabyGroot
|
@@ -312,6 +312,7 @@ VALUE thread_name_for(VALUE thread) {
|
|
312
312
|
// to support our custom rb_profile_frames (see below)
|
313
313
|
// Modifications:
|
314
314
|
// * Support int first_lineno for Ruby 3.2.0+ (https://github.com/ruby/ruby/pull/6430)
|
315
|
+
// * Validate iseq and pos before calling `rb_iseq_line_no` as a safety measure (see comment below for details)
|
315
316
|
//
|
316
317
|
// `node_id` gets used depending on Ruby VM compilation settings (USE_ISEQ_NODE_ID being defined).
|
317
318
|
// To avoid getting false "unused argument" warnings in setups where it's not used, we need to do this weird dance
|
@@ -358,6 +359,13 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
|
|
358
359
|
__builtin_trap();
|
359
360
|
}
|
360
361
|
#endif
|
362
|
+
|
363
|
+
// In PROF-11475 we spotted a crash when calling `rb_iseq_line_no` from this method. We couldn't reproduce or
|
364
|
+
// figure out the root cause, but "just in case", we're validating that the iseq looks valid and that the
|
365
|
+
// `n` used for the position is also sane, and if they don't look good, we don't calculate the line, rather
|
366
|
+
// than potentially trigger any issues.
|
367
|
+
if (RB_UNLIKELY(!RB_TYPE_P((VALUE) iseq, T_IMEMO) || n < 0 || n > ISEQ_BODY(iseq)->iseq_size)) return 0;
|
368
|
+
|
361
369
|
if (lineno) *lineno = rb_iseq_line_no(iseq, pos);
|
362
370
|
#ifdef USE_ISEQ_NODE_ID
|
363
371
|
if (node_id) *node_id = rb_iseq_node_id(iseq, pos);
|
@@ -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
|
@@ -6,6 +6,26 @@ module Datadog
|
|
6
6
|
module Rack
|
7
7
|
# Rack integration constants
|
8
8
|
module Ext
|
9
|
+
IDENTITY_COLLECTABLE_REQUEST_HEADERS = [
|
10
|
+
'accept-encoding',
|
11
|
+
'accept-language',
|
12
|
+
'cf-connecting-ip',
|
13
|
+
'cf-connecting-ipv6',
|
14
|
+
'content-encoding',
|
15
|
+
'content-language',
|
16
|
+
'content-length',
|
17
|
+
'fastly-client-ip',
|
18
|
+
'forwarded',
|
19
|
+
'forwarded-for',
|
20
|
+
'host',
|
21
|
+
'true-client-ip',
|
22
|
+
'via',
|
23
|
+
'x-client-ip',
|
24
|
+
'x-cluster-client-ip',
|
25
|
+
'x-forwarded',
|
26
|
+
'x-forwarded-for',
|
27
|
+
'x-real-ip'
|
28
|
+
].freeze
|
9
29
|
end
|
10
30
|
end
|
11
31
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../ext'
|
3
4
|
require_relative '../../../instrumentation/gateway'
|
4
5
|
require_relative '../../../event'
|
5
6
|
|
@@ -110,6 +111,25 @@ module Datadog
|
|
110
111
|
stack.call(gateway_request.request)
|
111
112
|
end
|
112
113
|
end
|
114
|
+
|
115
|
+
# NOTE: In the current state we unable to substibe twice to the same
|
116
|
+
# event within the same group. Ideally this code should live
|
117
|
+
# somewhere closer to identity related monitor.
|
118
|
+
# WARNING: The Gateway is a subject of refactoring
|
119
|
+
def watch_request_finish(gateway = Instrumentation.gateway)
|
120
|
+
gateway.watch('rack.request.finish', :appsec) do |stack, gateway_request|
|
121
|
+
context = gateway_request.env[AppSec::Ext::CONTEXT_KEY]
|
122
|
+
next stack.call(gateway_request.request) if context.span.nil? || !gateway.pushed?('identity.set_user')
|
123
|
+
|
124
|
+
gateway_request.headers.each do |name, value|
|
125
|
+
next unless Ext::IDENTITY_COLLECTABLE_REQUEST_HEADERS.include?(name)
|
126
|
+
|
127
|
+
context.span["http.request.headers.#{name}"] = value
|
128
|
+
end
|
129
|
+
|
130
|
+
stack.call(gateway_request.request)
|
131
|
+
end
|
132
|
+
end
|
113
133
|
end
|
114
134
|
end
|
115
135
|
end
|
@@ -77,6 +77,8 @@ module Datadog
|
|
77
77
|
gateway_response = nil
|
78
78
|
|
79
79
|
interrupt_params = catch(::Datadog::AppSec::Ext::INTERRUPT) do
|
80
|
+
# TODO: This event should be renamed into `rack.request.start` to
|
81
|
+
# reflect that it's the beginning of the request-cycle
|
80
82
|
http_response, _gateway_request = Instrumentation.gateway.push('rack.request', gateway_request) do
|
81
83
|
@app.call(env)
|
82
84
|
end
|
@@ -85,6 +87,7 @@ module Datadog
|
|
85
87
|
http_response[2], http_response[0], http_response[1], context: ctx
|
86
88
|
)
|
87
89
|
|
90
|
+
Instrumentation.gateway.push('rack.request.finish', gateway_request)
|
88
91
|
Instrumentation.gateway.push('rack.response', gateway_response)
|
89
92
|
|
90
93
|
nil
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module Instrumentation
|
6
|
+
class Gateway
|
7
|
+
# NOTE: This class extracted as-is and will be deprecated
|
8
|
+
# Instrumentation gateway middleware
|
9
|
+
class Middleware
|
10
|
+
attr_reader :key, :block
|
11
|
+
|
12
|
+
def initialize(key, &block)
|
13
|
+
@key = key
|
14
|
+
@block = block
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(stack, env)
|
18
|
+
@block.call(stack, env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,35 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'gateway/middleware'
|
4
|
+
|
3
5
|
module Datadog
|
4
6
|
module AppSec
|
5
7
|
# Instrumentation for AppSec
|
6
8
|
module Instrumentation
|
7
9
|
# Instrumentation gateway implementation
|
8
10
|
class Gateway
|
9
|
-
# Instrumentation gateway middleware
|
10
|
-
class Middleware
|
11
|
-
attr_reader :key, :block
|
12
|
-
|
13
|
-
def initialize(key, &block)
|
14
|
-
@key = key
|
15
|
-
@block = block
|
16
|
-
end
|
17
|
-
|
18
|
-
def call(stack, env)
|
19
|
-
@block.call(stack, env)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
private_constant :Middleware
|
24
|
-
|
25
11
|
def initialize
|
26
12
|
@middlewares = Hash.new { |h, k| h[k] = [] }
|
13
|
+
@pushed_events = {}
|
27
14
|
end
|
28
15
|
|
16
|
+
# NOTE: Be careful with pushed names because every pushed event name
|
17
|
+
# is recorded in order to provide an ability to any subscriber
|
18
|
+
# to check wether an arbitrary event had happened.
|
19
|
+
#
|
20
|
+
# WARNING: If we start pushing generated names we should consider
|
21
|
+
# limiting the storage of pushed names.
|
29
22
|
def push(name, env, &block)
|
30
|
-
|
23
|
+
@pushed_events[name] = true
|
31
24
|
|
32
|
-
|
25
|
+
block ||= -> {}
|
26
|
+
middlewares_for_name = @middlewares[name]
|
33
27
|
|
34
28
|
return [block.call, nil] if middlewares_for_name.empty?
|
35
29
|
|
@@ -48,14 +42,15 @@ module Datadog
|
|
48
42
|
end
|
49
43
|
|
50
44
|
def watch(name, key, &block)
|
51
|
-
@middlewares[name] << Middleware.new(key, &block) unless middlewares[name].any? { |m| m.key == key }
|
45
|
+
@middlewares[name] << Middleware.new(key, &block) unless @middlewares[name].any? { |m| m.key == key }
|
52
46
|
end
|
53
47
|
|
54
|
-
|
55
|
-
|
56
|
-
|
48
|
+
def pushed?(name)
|
49
|
+
@pushed_events.key?(name)
|
50
|
+
end
|
57
51
|
end
|
58
52
|
|
53
|
+
# NOTE: This left as-is and will be depricated soon.
|
59
54
|
def self.gateway
|
60
55
|
@gateway ||= Gateway.new # TODO: not thread safe
|
61
56
|
end
|
@@ -22,7 +22,7 @@ module Datadog
|
|
22
22
|
# TODO: `processors` and `scanners` are not provided by the caller, consider removing them
|
23
23
|
def merge(
|
24
24
|
telemetry:,
|
25
|
-
rules:, data: [], overrides: [], exclusions: [], custom_rules: [],
|
25
|
+
rules:, actions: [], data: [], overrides: [], exclusions: [], custom_rules: [],
|
26
26
|
processors: nil, scanners: nil
|
27
27
|
)
|
28
28
|
processors ||= begin
|
@@ -54,6 +54,7 @@ module Datadog
|
|
54
54
|
combined_exclusions = combine_exclusions(exclusions) if exclusions.any?
|
55
55
|
combined_custom_rules = combine_custom_rules(custom_rules) if custom_rules.any?
|
56
56
|
|
57
|
+
combined_rules['actions'] = actions if actions.any?
|
57
58
|
combined_rules['rules_data'] = combined_data if combined_data
|
58
59
|
combined_rules['rules_override'] = combined_overrides if combined_overrides
|
59
60
|
combined_rules['exclusions'] = combined_exclusions if combined_exclusions
|
@@ -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
|
|
@@ -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)
|
@@ -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
|
@@ -22,11 +22,11 @@ module Datadog
|
|
22
22
|
transport_options[:agent_settings] = agent_settings if agent_settings
|
23
23
|
|
24
24
|
negotiation = Negotiation.new(settings, agent_settings)
|
25
|
-
transport_v7 = Datadog::Core::Remote::Transport::HTTP.v7(**transport_options
|
25
|
+
transport_v7 = Datadog::Core::Remote::Transport::HTTP.v7(**transport_options) # steep:ignore
|
26
26
|
|
27
27
|
@barrier = Barrier.new(settings.remote.boot_timeout_seconds)
|
28
28
|
|
29
|
-
@client = Client.new(transport_v7, capabilities)
|
29
|
+
@client = Client.new(transport_v7, capabilities, logger: logger)
|
30
30
|
@healthy = false
|
31
31
|
logger.debug { "new remote configuration client: #{@client.id}" }
|
32
32
|
|
@@ -58,7 +58,7 @@ module Datadog
|
|
58
58
|
end
|
59
59
|
|
60
60
|
# client state is unknown, state might be corrupted
|
61
|
-
@client = Client.new(transport_v7, capabilities)
|
61
|
+
@client = Client.new(transport_v7, capabilities, logger: logger)
|
62
62
|
@healthy = false
|
63
63
|
logger.debug { "new remote configuration client: #{@client.id}" }
|
64
64
|
|
@@ -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
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'http/builder'
|
4
|
+
require_relative 'http/adapters/net'
|
5
|
+
require_relative 'http/adapters/unix_socket'
|
6
|
+
require_relative 'http/adapters/test'
|
7
|
+
|
8
|
+
module Datadog
|
9
|
+
module Core
|
10
|
+
module Transport
|
11
|
+
# HTTP transport
|
12
|
+
module HTTP
|
13
|
+
# Add adapters to registry
|
14
|
+
Builder::REGISTRY.set(
|
15
|
+
Transport::HTTP::Adapters::Net,
|
16
|
+
Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
17
|
+
)
|
18
|
+
Builder::REGISTRY.set(
|
19
|
+
Transport::HTTP::Adapters::Test,
|
20
|
+
Transport::Ext::Test::ADAPTER
|
21
|
+
)
|
22
|
+
Builder::REGISTRY.set(
|
23
|
+
Transport::HTTP::Adapters::UnixSocket,
|
24
|
+
Transport::Ext::UnixSocket::ADAPTER
|
25
|
+
)
|
26
|
+
|
27
|
+
module_function
|
28
|
+
|
29
|
+
# Helper function that delegates to Builder.new
|
30
|
+
# but is under HTTP namespace so that client code requires this file
|
31
|
+
# to get the adapters configured, and not the builder directly.
|
32
|
+
def build(api_instance_class:, &block)
|
33
|
+
Builder.new(api_instance_class: api_instance_class, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -21,7 +21,7 @@ module Datadog
|
|
21
21
|
:metrics
|
22
22
|
|
23
23
|
def initialize(options = {})
|
24
|
-
@metrics = options.fetch(:metrics) { Core::Runtime::Metrics.new }
|
24
|
+
@metrics = options.fetch(:metrics) { Core::Runtime::Metrics.new(logger: options[:logger]) }
|
25
25
|
|
26
26
|
# Workers::Async::Thread settings
|
27
27
|
self.fork_policy = options.fetch(:fork_policy, Workers::Async::Thread::FORK_POLICY_STOP)
|
@@ -5,13 +5,10 @@ require 'uri'
|
|
5
5
|
require_relative '../../core/environment/container'
|
6
6
|
require_relative '../../core/environment/ext'
|
7
7
|
require_relative '../../core/transport/ext'
|
8
|
-
require_relative '../../core/transport/http/adapters/net'
|
9
|
-
require_relative '../../core/transport/http/adapters/test'
|
10
|
-
require_relative '../../core/transport/http/adapters/unix_socket'
|
11
8
|
require_relative 'diagnostics'
|
12
9
|
require_relative 'input'
|
13
10
|
require_relative 'http/api'
|
14
|
-
require_relative '../../core/transport/http
|
11
|
+
require_relative '../../core/transport/http'
|
15
12
|
require_relative '../../../datadog/version'
|
16
13
|
|
17
14
|
module Datadog
|
@@ -23,7 +20,7 @@ module Datadog
|
|
23
20
|
|
24
21
|
# Builds a new Transport::HTTP::Client
|
25
22
|
def new(klass, &block)
|
26
|
-
Core::Transport::HTTP
|
23
|
+
Core::Transport::HTTP.build(
|
27
24
|
api_instance_class: API::Instance, &block
|
28
25
|
).to_transport(klass)
|
29
26
|
end
|
@@ -102,17 +99,6 @@ module Datadog
|
|
102
99
|
def default_adapter
|
103
100
|
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
104
101
|
end
|
105
|
-
|
106
|
-
# Add adapters to registry
|
107
|
-
Datadog::Core::Transport::HTTP::Builder::REGISTRY.set(
|
108
|
-
Datadog::Core::Transport::HTTP::Adapters::Net,
|
109
|
-
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
110
|
-
)
|
111
|
-
Datadog::Core::Transport::HTTP::Builder::REGISTRY.set(Datadog::Core::Transport::HTTP::Adapters::Test, Datadog::Core::Transport::Ext::Test::ADAPTER)
|
112
|
-
Datadog::Core::Transport::HTTP::Builder::REGISTRY.set(
|
113
|
-
Datadog::Core::Transport::HTTP::Adapters::UnixSocket,
|
114
|
-
Datadog::Core::Transport::Ext::UnixSocket::ADAPTER
|
115
|
-
)
|
116
102
|
end
|
117
103
|
end
|
118
104
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module Tracing
|
7
|
+
module Metadata
|
8
|
+
# This class is a data structure that is used to store
|
9
|
+
# complex metadata, such as an array of objects.
|
10
|
+
#
|
11
|
+
# It is serialized to MessagePack format when sent to the agent.
|
12
|
+
class Metastruct
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
def_delegators :@metastruct, :[], :[]=, :to_h
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@metastruct = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_msgpack(packer = nil)
|
22
|
+
# JRuby doesn't pass the packer
|
23
|
+
packer ||= MessagePack::Packer.new
|
24
|
+
|
25
|
+
packer.write(@metastruct.transform_values(&:to_msgpack))
|
26
|
+
end
|
27
|
+
|
28
|
+
def pretty_print(q)
|
29
|
+
q.seplist @metastruct.each do |key, value|
|
30
|
+
q.text "#{key} => #{value}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'metastruct'
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module Tracing
|
7
|
+
module Metadata
|
8
|
+
# Adds data storage for the `meta_struct` field.
|
9
|
+
#
|
10
|
+
# This field is used to send more complex data like an array of objects
|
11
|
+
# in MessagePack format to the agent, and has no size limitations.
|
12
|
+
#
|
13
|
+
# The agent fully supports meta_struct from version v7.35.0 (April 2022).
|
14
|
+
#
|
15
|
+
# On versions older than v7.35.0, sending traces containing meta_struct
|
16
|
+
# has no unexpected side-effects; traces are sent to the backend as expected,
|
17
|
+
# while the meta_struct field is stripped.
|
18
|
+
module MetastructTagging
|
19
|
+
# Set the given key / value tag pair on the metastruct.
|
20
|
+
#
|
21
|
+
# A valid example is:
|
22
|
+
#
|
23
|
+
# span.set_metastruct_tag('_dd.stack', [])
|
24
|
+
def set_metastruct_tag(key, value)
|
25
|
+
metastruct[key] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return the metastruct tag value for the given key,
|
29
|
+
# returns nil if the key doesn't exist.
|
30
|
+
def get_metastruct_tag(key)
|
31
|
+
metastruct[key]
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def metastruct
|
37
|
+
@metastruct ||= Metastruct.new
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative 'metadata/analytics'
|
4
4
|
require_relative 'metadata/tagging'
|
5
|
+
require_relative 'metadata/metastruct_tagging'
|
5
6
|
require_relative 'metadata/errors'
|
6
7
|
|
7
8
|
module Datadog
|
@@ -10,6 +11,7 @@ module Datadog
|
|
10
11
|
module Metadata
|
11
12
|
def self.included(base)
|
12
13
|
base.include(Metadata::Tagging)
|
14
|
+
base.include(Metadata::MetastructTagging)
|
13
15
|
base.include(Metadata::Errors)
|
14
16
|
|
15
17
|
# Additional extensions
|
data/lib/datadog/tracing/span.rb
CHANGED
@@ -33,6 +33,9 @@ module Datadog
|
|
33
33
|
:status,
|
34
34
|
:trace_id
|
35
35
|
|
36
|
+
attr_reader \
|
37
|
+
:metastruct
|
38
|
+
|
36
39
|
attr_writer \
|
37
40
|
:duration
|
38
41
|
|
@@ -54,6 +57,7 @@ module Datadog
|
|
54
57
|
id: nil,
|
55
58
|
meta: nil,
|
56
59
|
metrics: nil,
|
60
|
+
metastruct: nil,
|
57
61
|
parent_id: 0,
|
58
62
|
resource: name,
|
59
63
|
service: nil,
|
@@ -76,6 +80,7 @@ module Datadog
|
|
76
80
|
|
77
81
|
@meta = meta || {}
|
78
82
|
@metrics = metrics || {}
|
83
|
+
@metastruct = metastruct || {}
|
79
84
|
@status = status || 0
|
80
85
|
|
81
86
|
# start_time and end_time track wall clock. In Ruby, wall clock
|
@@ -144,6 +149,7 @@ module Datadog
|
|
144
149
|
error: @status,
|
145
150
|
meta: @meta,
|
146
151
|
metrics: @metrics,
|
152
|
+
meta_struct: @metastruct.to_h,
|
147
153
|
name: @name,
|
148
154
|
parent_id: @parent_id,
|
149
155
|
resource: @resource,
|
@@ -185,12 +191,15 @@ module Datadog
|
|
185
191
|
q.text "#{key} => #{value}"
|
186
192
|
end
|
187
193
|
end
|
188
|
-
q.group(2, 'Metrics: [',
|
194
|
+
q.group(2, 'Metrics: [', "]\n") do
|
189
195
|
q.breakable
|
190
196
|
q.seplist @metrics.each do |key, value|
|
191
197
|
q.text "#{key} => #{value}"
|
192
198
|
end
|
193
199
|
end
|
200
|
+
q.group(2, 'Metastruct: [', ']') do
|
201
|
+
metastruct.pretty_print(q)
|
202
|
+
end
|
194
203
|
end
|
195
204
|
end
|
196
205
|
|
@@ -289,6 +289,7 @@ module Datadog
|
|
289
289
|
id: @id,
|
290
290
|
meta: meta,
|
291
291
|
metrics: metrics,
|
292
|
+
metastruct: metastruct,
|
292
293
|
name: @name,
|
293
294
|
parent_id: @parent_id,
|
294
295
|
resource: @resource,
|
@@ -328,12 +329,15 @@ module Datadog
|
|
328
329
|
q.text "#{key} => #{value}"
|
329
330
|
end
|
330
331
|
end
|
331
|
-
q.group(2, 'Metrics: [',
|
332
|
+
q.group(2, 'Metrics: [', "]\n") do
|
332
333
|
q.breakable
|
333
334
|
q.seplist metrics.each do |key, value|
|
334
335
|
q.text "#{key} => #{value}"
|
335
336
|
end
|
336
337
|
end
|
338
|
+
q.group(2, 'Metastruct: [', ']') do
|
339
|
+
metastruct.pretty_print(q)
|
340
|
+
end
|
337
341
|
end
|
338
342
|
end
|
339
343
|
|
@@ -456,6 +460,7 @@ module Datadog
|
|
456
460
|
id: @id,
|
457
461
|
meta: Core::Utils::SafeDup.frozen_or_dup(meta),
|
458
462
|
metrics: Core::Utils::SafeDup.frozen_or_dup(metrics),
|
463
|
+
metastruct: Core::Utils::SafeDup.frozen_or_dup(metastruct),
|
459
464
|
parent_id: @parent_id,
|
460
465
|
resource: @resource,
|
461
466
|
service: @service,
|
@@ -19,7 +19,8 @@ module Datadog
|
|
19
19
|
attr_reader \
|
20
20
|
:logger,
|
21
21
|
:events,
|
22
|
-
:transport
|
22
|
+
:transport,
|
23
|
+
:agent_settings
|
23
24
|
|
24
25
|
# @param [Datadog::Tracing::Transport::Traces::Transport] transport a custom transport instance.
|
25
26
|
# If provided, overrides `transport_options` and `agent_settings`.
|
@@ -28,9 +29,10 @@ module Datadog
|
|
28
29
|
# the default transport instance.
|
29
30
|
def initialize(transport: nil, transport_options: {}, agent_settings: nil, logger: Datadog.logger)
|
30
31
|
@logger = logger
|
32
|
+
@agent_settings = agent_settings
|
31
33
|
|
32
34
|
@transport = transport || begin
|
33
|
-
transport_options
|
35
|
+
transport_options = transport_options.merge(agent_settings: agent_settings) if agent_settings
|
34
36
|
Transport::HTTP.default(**transport_options)
|
35
37
|
end
|
36
38
|
|
@@ -49,6 +49,8 @@ module Datadog
|
|
49
49
|
# @param tags [Hash] default tags added to all spans
|
50
50
|
# @param writer [Datadog::Tracing::Writer] consumes traces returned by the provided +trace_flush+
|
51
51
|
def initialize(
|
52
|
+
# rubocop:disable Style/KeywordParametersOrder
|
53
|
+
# https://github.com/rubocop/rubocop/issues/13933
|
52
54
|
trace_flush: Flush::Finished.new,
|
53
55
|
context_provider: DefaultContextProvider.new,
|
54
56
|
default_service: Core::Environment::Ext::FALLBACK_SERVICE_NAME,
|
@@ -60,7 +62,10 @@ module Datadog
|
|
60
62
|
),
|
61
63
|
span_sampler: Sampling::Span::Sampler.new,
|
62
64
|
tags: {},
|
63
|
-
writer
|
65
|
+
# writer is not defaulted because creating it requires agent_settings,
|
66
|
+
# which we do not have here and otherwise do not need.
|
67
|
+
writer:
|
68
|
+
# rubocop:enable Style/KeywordParametersOrder
|
64
69
|
)
|
65
70
|
@trace_flush = trace_flush
|
66
71
|
@default_service = default_service
|
@@ -1,14 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'uri'
|
4
|
-
|
5
3
|
require_relative '../../core/environment/container'
|
6
4
|
require_relative '../../core/environment/ext'
|
7
5
|
require_relative '../../core/transport/ext'
|
8
|
-
require_relative '../../core/transport/http
|
9
|
-
require_relative '../../core/transport/http/adapters/test'
|
10
|
-
require_relative '../../core/transport/http/adapters/unix_socket'
|
11
|
-
require_relative '../../core/transport/http/builder'
|
6
|
+
require_relative '../../core/transport/http'
|
12
7
|
require_relative 'http/api'
|
13
8
|
require_relative '../../../datadog/version'
|
14
9
|
|
@@ -17,21 +12,11 @@ module Datadog
|
|
17
12
|
module Transport
|
18
13
|
# Namespace for HTTP transport components
|
19
14
|
module HTTP
|
20
|
-
# NOTE: Due to... legacy reasons... This class likes having a default `AgentSettings` instance to fall back to.
|
21
|
-
# Because we generate this instance with an empty instance of `Settings`, the resulting `AgentSettings` below
|
22
|
-
# represents only settings specified via environment variables + the usual defaults.
|
23
|
-
#
|
24
|
-
# DO NOT USE THIS IN NEW CODE, as it ignores any settings specified by users via `Datadog.configure`.
|
25
|
-
DO_NOT_USE_ENVIRONMENT_AGENT_SETTINGS = Datadog::Core::Configuration::AgentSettingsResolver.call(
|
26
|
-
Datadog::Core::Configuration::Settings.new,
|
27
|
-
logger: nil,
|
28
|
-
)
|
29
|
-
|
30
15
|
module_function
|
31
16
|
|
32
17
|
# Builds a new Transport::HTTP::Client
|
33
18
|
def new(klass, &block)
|
34
|
-
Core::Transport::HTTP
|
19
|
+
Core::Transport::HTTP.build(
|
35
20
|
api_instance_class: API::Instance, &block
|
36
21
|
).to_transport(klass)
|
37
22
|
end
|
@@ -39,7 +24,7 @@ module Datadog
|
|
39
24
|
# Builds a new Transport::HTTP::Client with default settings
|
40
25
|
# Pass a block to override any settings.
|
41
26
|
def default(
|
42
|
-
agent_settings
|
27
|
+
agent_settings:,
|
43
28
|
**options
|
44
29
|
)
|
45
30
|
new(Transport::Traces::Transport) do |transport|
|
@@ -86,20 +71,6 @@ module Datadog
|
|
86
71
|
def default_adapter
|
87
72
|
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
88
73
|
end
|
89
|
-
|
90
|
-
# Add adapters to registry
|
91
|
-
Core::Transport::HTTP::Builder::REGISTRY.set(
|
92
|
-
Datadog::Core::Transport::HTTP::Adapters::Net,
|
93
|
-
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
94
|
-
)
|
95
|
-
Core::Transport::HTTP::Builder::REGISTRY.set(
|
96
|
-
Datadog::Core::Transport::HTTP::Adapters::Test,
|
97
|
-
Datadog::Core::Transport::Ext::Test::ADAPTER
|
98
|
-
)
|
99
|
-
Core::Transport::HTTP::Builder::REGISTRY.set(
|
100
|
-
Datadog::Core::Transport::HTTP::Adapters::UnixSocket,
|
101
|
-
Datadog::Core::Transport::Ext::UnixSocket::ADAPTER
|
102
|
-
)
|
103
74
|
end
|
104
75
|
end
|
105
76
|
end
|
@@ -69,7 +69,7 @@ module Datadog
|
|
69
69
|
def to_msgpack(packer = nil)
|
70
70
|
packer ||= MessagePack::Packer.new
|
71
71
|
|
72
|
-
number_of_elements_to_write =
|
72
|
+
number_of_elements_to_write = 12
|
73
73
|
|
74
74
|
number_of_elements_to_write += 1 if span.events.any? && @native_events_supported
|
75
75
|
|
@@ -117,6 +117,8 @@ module Datadog
|
|
117
117
|
packer.write(span.meta)
|
118
118
|
packer.write('metrics')
|
119
119
|
packer.write(span.metrics)
|
120
|
+
packer.write('meta_struct')
|
121
|
+
packer.write(span.metastruct)
|
120
122
|
packer.write('span_links')
|
121
123
|
packer.write(span.links.map(&:to_hash))
|
122
124
|
packer.write('error')
|
@@ -18,7 +18,8 @@ module Datadog
|
|
18
18
|
class TraceWriter < Core::Worker
|
19
19
|
attr_reader \
|
20
20
|
:logger,
|
21
|
-
:transport
|
21
|
+
:transport,
|
22
|
+
:agent_settings
|
22
23
|
|
23
24
|
# rubocop:disable Lint/MissingSuper
|
24
25
|
def initialize(options = {})
|
@@ -26,7 +27,10 @@ module Datadog
|
|
26
27
|
|
27
28
|
transport_options = options.fetch(:transport_options, {})
|
28
29
|
|
29
|
-
|
30
|
+
if options.key?(:agent_settings)
|
31
|
+
@agent_settings = options[:agent_settings]
|
32
|
+
transport_options = transport_options.merge(agent_settings: @agent_settings)
|
33
|
+
end
|
30
34
|
|
31
35
|
@transport = options.fetch(:transport) do
|
32
36
|
Datadog::Tracing::Transport::HTTP.default(**transport_options)
|
@@ -16,7 +16,8 @@ module Datadog
|
|
16
16
|
:logger,
|
17
17
|
:transport,
|
18
18
|
:worker,
|
19
|
-
:events
|
19
|
+
:events,
|
20
|
+
:agent_settings
|
20
21
|
|
21
22
|
def initialize(options = {})
|
22
23
|
@logger = options[:logger] || Datadog.logger
|
@@ -26,7 +27,10 @@ module Datadog
|
|
26
27
|
@flush_interval = options.fetch(:flush_interval, Workers::AsyncTransport::DEFAULT_FLUSH_INTERVAL)
|
27
28
|
transport_options = options.fetch(:transport_options, {})
|
28
29
|
|
29
|
-
|
30
|
+
if options.key?(:agent_settings)
|
31
|
+
@agent_settings = options[:agent_settings]
|
32
|
+
transport_options = transport_options.merge(agent_settings: @agent_settings)
|
33
|
+
end
|
30
34
|
|
31
35
|
# transport and buffers
|
32
36
|
@transport = options.fetch(:transport) do
|
data/lib/datadog/version.rb
CHANGED
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.12.
|
4
|
+
version: 2.12.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -226,6 +226,7 @@ files:
|
|
226
226
|
- lib/datadog/appsec/instrumentation.rb
|
227
227
|
- lib/datadog/appsec/instrumentation/gateway.rb
|
228
228
|
- lib/datadog/appsec/instrumentation/gateway/argument.rb
|
229
|
+
- lib/datadog/appsec/instrumentation/gateway/middleware.rb
|
229
230
|
- lib/datadog/appsec/metrics.rb
|
230
231
|
- lib/datadog/appsec/metrics/collector.rb
|
231
232
|
- lib/datadog/appsec/metrics/exporter.rb
|
@@ -342,6 +343,7 @@ files:
|
|
342
343
|
- lib/datadog/core/telemetry/request.rb
|
343
344
|
- lib/datadog/core/telemetry/worker.rb
|
344
345
|
- lib/datadog/core/transport/ext.rb
|
346
|
+
- lib/datadog/core/transport/http.rb
|
345
347
|
- lib/datadog/core/transport/http/adapters/net.rb
|
346
348
|
- lib/datadog/core/transport/http/adapters/registry.rb
|
347
349
|
- lib/datadog/core/transport/http/adapters/test.rb
|
@@ -875,6 +877,8 @@ files:
|
|
875
877
|
- lib/datadog/tracing/metadata/analytics.rb
|
876
878
|
- lib/datadog/tracing/metadata/errors.rb
|
877
879
|
- lib/datadog/tracing/metadata/ext.rb
|
880
|
+
- lib/datadog/tracing/metadata/metastruct.rb
|
881
|
+
- lib/datadog/tracing/metadata/metastruct_tagging.rb
|
878
882
|
- lib/datadog/tracing/metadata/tagging.rb
|
879
883
|
- lib/datadog/tracing/pipeline.rb
|
880
884
|
- lib/datadog/tracing/pipeline/span_filter.rb
|
@@ -929,8 +933,8 @@ licenses:
|
|
929
933
|
- Apache-2.0
|
930
934
|
metadata:
|
931
935
|
allowed_push_host: https://rubygems.org
|
932
|
-
changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.12.
|
933
|
-
source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.12.
|
936
|
+
changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.12.2/CHANGELOG.md
|
937
|
+
source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.12.2
|
934
938
|
post_install_message:
|
935
939
|
rdoc_options: []
|
936
940
|
require_paths:
|