datadog 2.13.0 → 2.15.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +7 -6
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +3 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +69 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.h +7 -0
- data/ext/datadog_profiling_native_extension/http_transport.c +25 -32
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +22 -21
- data/ext/libdatadog_api/datadog_ruby_common.h +3 -0
- data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
- data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +0 -1344
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
- data/lib/datadog/appsec/assets/waf_rules/strict.json +0 -1344
- data/lib/datadog/appsec/component.rb +19 -17
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- data/lib/datadog/appsec/contrib/active_record/integration.rb +1 -1
- data/lib/datadog/appsec/event.rb +21 -50
- data/lib/datadog/appsec/remote.rb +4 -0
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/environment/agent_info.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +1 -1
- data/lib/datadog/core/remote/client.rb +1 -1
- data/lib/datadog/core/remote/negotiation.rb +1 -1
- data/lib/datadog/core/remote/transport/config.rb +2 -2
- data/lib/datadog/core/remote/transport/http/client.rb +1 -1
- data/lib/datadog/core/remote/transport/http.rb +2 -2
- data/lib/datadog/core/remote/transport/negotiation.rb +2 -2
- data/lib/datadog/core/telemetry/metric.rb +5 -5
- data/lib/datadog/core/telemetry/request.rb +1 -1
- data/lib/datadog/core/transport/http/builder.rb +2 -2
- data/lib/datadog/core/transport/http.rb +1 -1
- data/lib/datadog/di/probe_notification_builder.rb +1 -1
- data/lib/datadog/di/transport/diagnostics.rb +2 -2
- data/lib/datadog/di/transport/http/client.rb +1 -1
- data/lib/datadog/di/transport/http/diagnostics.rb +0 -1
- data/lib/datadog/di/transport/http/input.rb +0 -1
- data/lib/datadog/di/transport/http.rb +0 -6
- data/lib/datadog/di/transport/input.rb +2 -2
- data/lib/datadog/kit/appsec/events.rb +6 -3
- data/lib/datadog/profiling/collectors/info.rb +3 -0
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +2 -3
- data/lib/datadog/profiling/ext.rb +0 -1
- data/lib/datadog/profiling/flush.rb +4 -7
- data/lib/datadog/profiling/http_transport.rb +10 -59
- data/lib/datadog/profiling/stack_recorder.rb +4 -4
- data/lib/datadog/profiling.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
- data/lib/datadog/tracing/contrib/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +46 -0
- data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
- data/lib/datadog/tracing/contrib/karafka.rb +37 -0
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/span_event.rb +1 -1
- data/lib/datadog/tracing/transport/http/client.rb +1 -1
- data/lib/datadog/tracing/transport/http.rb +1 -1
- data/lib/datadog/tracing/transport/traces.rb +11 -6
- data/lib/datadog/version.rb +1 -1
- data/lib/datadog.rb +1 -1
- metadata +17 -6
@@ -12,7 +12,25 @@ module Datadog
|
|
12
12
|
class << self
|
13
13
|
def build_appsec_component(settings, telemetry:)
|
14
14
|
return if !settings.respond_to?(:appsec) || !settings.appsec.enabled
|
15
|
-
|
15
|
+
|
16
|
+
ffi_version = Gem.loaded_specs['ffi'] && Gem.loaded_specs['ffi'].version
|
17
|
+
unless ffi_version
|
18
|
+
Datadog.logger.warn('FFI gem is not loaded, AppSec will be disabled.')
|
19
|
+
telemetry.error('AppSec: Component not loaded, due to missing FFI gem')
|
20
|
+
|
21
|
+
return
|
22
|
+
end
|
23
|
+
|
24
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.3') && ffi_version < Gem::Version.new('1.16.0')
|
25
|
+
Datadog.logger.warn(
|
26
|
+
'AppSec is not supported in Ruby versions above 3.3.0 when using `ffi` versions older than 1.16.0, ' \
|
27
|
+
'and will be forcibly disabled due to a memory leak in `ffi`. ' \
|
28
|
+
'Please upgrade your `ffi` version to 1.16.0 or higher.'
|
29
|
+
)
|
30
|
+
telemetry.error('AppSec: Component not loaded, ffi version is leaky with ruby > 3.3.0')
|
31
|
+
|
32
|
+
return
|
33
|
+
end
|
16
34
|
|
17
35
|
processor = create_processor(settings, telemetry)
|
18
36
|
|
@@ -29,22 +47,6 @@ module Datadog
|
|
29
47
|
|
30
48
|
private
|
31
49
|
|
32
|
-
def incompatible_ffi_version?
|
33
|
-
ffi_version = Gem.loaded_specs['ffi'] && Gem.loaded_specs['ffi'].version
|
34
|
-
return true unless ffi_version
|
35
|
-
|
36
|
-
return false unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.3') &&
|
37
|
-
ffi_version < Gem::Version.new('1.16.0')
|
38
|
-
|
39
|
-
Datadog.logger.warn(
|
40
|
-
'AppSec is not supported in Ruby versions above 3.3.0 when using `ffi` versions older than 1.16.0, ' \
|
41
|
-
'and will be forcibly disabled due to a memory leak in `ffi`. ' \
|
42
|
-
'Please upgrade your `ffi` version to 1.16.0 or higher.'
|
43
|
-
)
|
44
|
-
|
45
|
-
true
|
46
|
-
end
|
47
|
-
|
48
50
|
def create_processor(settings, telemetry)
|
49
51
|
rules = AppSec::Processor::RuleLoader.load_rules(
|
50
52
|
telemetry: telemetry,
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'zlib'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
require_relative '../core/utils/base64'
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module AppSec
|
11
|
+
# Converts derivative schema payloads into JSON and compresses them into a
|
12
|
+
# base64 encoded string if the payload is worth compressing.
|
13
|
+
#
|
14
|
+
# See: https://github.com/DataDog/dd-trace-rb/pull/3177#issuecomment-1747221082
|
15
|
+
module CompressedJson
|
16
|
+
MIN_SIZE_FOR_COMPRESSION = 260
|
17
|
+
|
18
|
+
def self.dump(payload)
|
19
|
+
value = JSON.dump(payload)
|
20
|
+
return value if value.bytesize < MIN_SIZE_FOR_COMPRESSION
|
21
|
+
|
22
|
+
compress_and_encode(value)
|
23
|
+
rescue ArgumentError, Encoding::UndefinedConversionError, JSON::JSONError => e
|
24
|
+
AppSec.telemetry.report(e, description: 'AppSec: Failed to convert value into JSON')
|
25
|
+
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
private_class_method def self.compress_and_encode(payload)
|
30
|
+
Core::Utils::Base64.strict_encode64(
|
31
|
+
Zlib.gzip(payload, level: Zlib::BEST_SPEED, strategy: Zlib::DEFAULT_STRATEGY)
|
32
|
+
)
|
33
|
+
rescue Zlib::Error, TypeError => e
|
34
|
+
AppSec.telemetry.report(e, description: 'AppSec: Failed to compress and encode value')
|
35
|
+
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -13,7 +13,7 @@ module Datadog
|
|
13
13
|
|
14
14
|
MINIMUM_VERSION = Gem::Version.new('4')
|
15
15
|
|
16
|
-
register_as :active_record, auto_patch:
|
16
|
+
register_as :active_record, auto_patch: true
|
17
17
|
|
18
18
|
def self.version
|
19
19
|
Gem.loaded_specs['activerecord'] && Gem.loaded_specs['activerecord'].version
|
data/lib/datadog/appsec/event.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'json'
|
4
|
-
require 'zlib'
|
5
|
-
|
6
4
|
require_relative 'rate_limiter'
|
7
|
-
require_relative '
|
5
|
+
require_relative 'compressed_json'
|
8
6
|
|
9
7
|
module Datadog
|
10
8
|
module AppSec
|
11
9
|
# AppSec event
|
12
10
|
module Event
|
11
|
+
DERIVATIVE_SCHEMA_KEY_PREFIX = '_dd.appsec.s.'
|
12
|
+
DERIVATIVE_SCHEMA_MAX_COMPRESSED_SIZE = 25000
|
13
13
|
ALLOWED_REQUEST_HEADERS = %w[
|
14
14
|
X-Forwarded-For
|
15
15
|
X-Client-IP
|
@@ -38,11 +38,6 @@ module Datadog
|
|
38
38
|
Content-Language
|
39
39
|
].map!(&:downcase).freeze
|
40
40
|
|
41
|
-
MAX_ENCODED_SCHEMA_SIZE = 25000
|
42
|
-
# For more information about this number
|
43
|
-
# please check https://github.com/DataDog/dd-trace-rb/pull/3177#issuecomment-1747221082
|
44
|
-
MIN_SCHEMA_SIZE_FOR_COMPRESSION = 260
|
45
|
-
|
46
41
|
# Record events for a trace
|
47
42
|
#
|
48
43
|
# This is expected to be called only once per trace for the rate limiter
|
@@ -80,7 +75,6 @@ module Datadog
|
|
80
75
|
end
|
81
76
|
end
|
82
77
|
|
83
|
-
# rubocop:disable Metrics/MethodLength
|
84
78
|
def build_service_entry_tags(event_group)
|
85
79
|
waf_events = []
|
86
80
|
entry_tags = event_group.each_with_object({ '_dd.origin' => 'appsec' }) do |event, tags|
|
@@ -106,26 +100,17 @@ module Datadog
|
|
106
100
|
waf_events += waf_result.events
|
107
101
|
|
108
102
|
waf_result.derivatives.each do |key, value|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
else
|
117
|
-
parsed_value
|
118
|
-
end
|
119
|
-
next unless schema_value
|
120
|
-
|
121
|
-
if schema_value.size >= MAX_ENCODED_SCHEMA_SIZE
|
122
|
-
Datadog.logger.debug do
|
123
|
-
"Schema key: #{key} exceeds the max size value. It will not be included as part of the span tags"
|
124
|
-
end
|
103
|
+
next tags[key] = value unless key.start_with?(DERIVATIVE_SCHEMA_KEY_PREFIX)
|
104
|
+
|
105
|
+
value = CompressedJson.dump(value)
|
106
|
+
next if value.nil?
|
107
|
+
|
108
|
+
if value.size >= DERIVATIVE_SCHEMA_MAX_COMPRESSED_SIZE
|
109
|
+
Datadog.logger.debug { "AppSec: Schema key '#{key}' will not be included into span tags due to it's size" }
|
125
110
|
next
|
126
111
|
end
|
127
112
|
|
128
|
-
tags[key] =
|
113
|
+
tags[key] = value
|
129
114
|
end
|
130
115
|
|
131
116
|
tags
|
@@ -135,14 +120,16 @@ module Datadog
|
|
135
120
|
entry_tags['_dd.appsec.json'] = appsec_events if appsec_events
|
136
121
|
entry_tags
|
137
122
|
end
|
138
|
-
# rubocop:enable Metrics/MethodLength
|
139
123
|
|
140
124
|
def tag_and_keep!(context, waf_result)
|
141
125
|
# We want to keep the trace in case of security event
|
142
126
|
context.trace.keep! if context.trace
|
143
127
|
|
144
128
|
if context.span
|
145
|
-
|
129
|
+
if waf_result.actions.key?('block_request') || waf_result.actions.key?('redirect_request')
|
130
|
+
context.span.set_tag('appsec.blocked', 'true')
|
131
|
+
end
|
132
|
+
|
146
133
|
context.span.set_tag('appsec.event', 'true')
|
147
134
|
end
|
148
135
|
|
@@ -151,31 +138,15 @@ module Datadog
|
|
151
138
|
|
152
139
|
private
|
153
140
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
Datadog.logger.debug do
|
158
|
-
"Failed to compress and encode value when populating AppSec::Event. Error: #{e.message}"
|
159
|
-
end
|
160
|
-
nil
|
161
|
-
end
|
162
|
-
|
141
|
+
# NOTE: Handling of Encoding::UndefinedConversionError is added as a quick fix to
|
142
|
+
# the issue between Ruby encoded strings and libddwaf produced events and now
|
143
|
+
# is under investigation.
|
163
144
|
def json_parse(value)
|
164
145
|
JSON.dump(value)
|
165
|
-
rescue ArgumentError => e
|
166
|
-
|
167
|
-
"Failed to parse value to JSON when populating AppSec::Event. Error: #{e.message}"
|
168
|
-
end
|
169
|
-
nil
|
170
|
-
end
|
146
|
+
rescue ArgumentError, Encoding::UndefinedConversionError, JSON::JSONError => e
|
147
|
+
AppSec.telemetry.report(e, description: 'AppSec: Failed to convert value into JSON')
|
171
148
|
|
172
|
-
|
173
|
-
sio = StringIO.new
|
174
|
-
# For an in depth comparison of Zlib options check https://github.com/DataDog/dd-trace-rb/pull/3177#issuecomment-1747215473
|
175
|
-
gz = Zlib::GzipWriter.new(sio, Zlib::BEST_SPEED, Zlib::DEFAULT_STRATEGY)
|
176
|
-
gz.write(value)
|
177
|
-
gz.close
|
178
|
-
sio.string
|
149
|
+
nil
|
179
150
|
end
|
180
151
|
|
181
152
|
# Propagate to downstream services the information that the current distributed trace is
|
@@ -23,6 +23,8 @@ module Datadog
|
|
23
23
|
CAP_ASM_CUSTOM_RULES = 1 << 8 # accept custom rules
|
24
24
|
CAP_ASM_CUSTOM_BLOCKING_RESPONSE = 1 << 9 # supports custom http code or redirect sa blocking response
|
25
25
|
CAP_ASM_TRUSTED_IPS = 1 << 10 # supports trusted ip
|
26
|
+
CAP_ASM_RASP_SSRF = 1 << 23 # support for server-side request forgery exploit prevention rules
|
27
|
+
CAP_ASM_RASP_SQLI = 1 << 21 # support for SQL injection exploit prevention rules
|
26
28
|
|
27
29
|
# TODO: we need to dynamically add CAP_ASM_ACTIVATION once we support it
|
28
30
|
ASM_CAPABILITIES = [
|
@@ -35,6 +37,8 @@ module Datadog
|
|
35
37
|
CAP_ASM_CUSTOM_RULES,
|
36
38
|
CAP_ASM_CUSTOM_BLOCKING_RESPONSE,
|
37
39
|
CAP_ASM_TRUSTED_IPS,
|
40
|
+
CAP_ASM_RASP_SSRF,
|
41
|
+
CAP_ASM_RASP_SQLI,
|
38
42
|
].freeze
|
39
43
|
|
40
44
|
ASM_PRODUCTS = [
|
@@ -53,7 +53,7 @@ module Datadog
|
|
53
53
|
class AgentInfo
|
54
54
|
attr_reader :agent_settings, :logger
|
55
55
|
|
56
|
-
def initialize(agent_settings, logger:)
|
56
|
+
def initialize(agent_settings, logger: Datadog.logger)
|
57
57
|
@agent_settings = agent_settings
|
58
58
|
@logger = logger
|
59
59
|
@client = Remote::Transport::HTTP.root(agent_settings: agent_settings, logger: logger)
|
@@ -15,7 +15,7 @@ module Datadog
|
|
15
15
|
|
16
16
|
attr_reader :transport, :repository, :id, :dispatcher, :logger
|
17
17
|
|
18
|
-
def initialize(transport, capabilities, logger
|
18
|
+
def initialize(transport, capabilities, logger: Datadog.logger, repository: Configuration::Repository.new)
|
19
19
|
@transport = transport
|
20
20
|
@logger = logger
|
21
21
|
|
@@ -9,7 +9,7 @@ module Datadog
|
|
9
9
|
class Negotiation
|
10
10
|
attr_reader :logger
|
11
11
|
|
12
|
-
def initialize(_settings, agent_settings, logger
|
12
|
+
def initialize(_settings, agent_settings, logger: Datadog.logger, suppress_logging: {})
|
13
13
|
@logger = logger
|
14
14
|
@transport_root = Datadog::Core::Remote::Transport::HTTP.root(agent_settings: agent_settings, logger: logger)
|
15
15
|
@logged = suppress_logging
|
@@ -34,11 +34,11 @@ module Datadog
|
|
34
34
|
class Transport
|
35
35
|
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
36
36
|
|
37
|
-
def initialize(apis, default_api, logger)
|
37
|
+
def initialize(apis, default_api, logger: Datadog.logger)
|
38
38
|
@apis = apis
|
39
39
|
@logger = logger
|
40
40
|
|
41
|
-
@client = HTTP::Client.new(current_api, logger)
|
41
|
+
@client = HTTP::Client.new(current_api, logger: logger)
|
42
42
|
end
|
43
43
|
|
44
44
|
##### there is only one transport! it's negotiation!
|
@@ -33,7 +33,7 @@ module Datadog
|
|
33
33
|
# Pass a block to override any settings.
|
34
34
|
def root(
|
35
35
|
agent_settings:,
|
36
|
-
logger
|
36
|
+
logger: Datadog.logger,
|
37
37
|
api_version: nil,
|
38
38
|
headers: nil
|
39
39
|
)
|
@@ -57,7 +57,7 @@ module Datadog
|
|
57
57
|
# Pass a block to override any settings.
|
58
58
|
def v7(
|
59
59
|
agent_settings:,
|
60
|
-
logger
|
60
|
+
logger: Datadog.logger,
|
61
61
|
api_version: nil,
|
62
62
|
headers: nil
|
63
63
|
)
|
@@ -51,11 +51,11 @@ module Datadog
|
|
51
51
|
class Transport
|
52
52
|
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
53
53
|
|
54
|
-
def initialize(apis, default_api, logger)
|
54
|
+
def initialize(apis, default_api, logger: Datadog.logger)
|
55
55
|
@apis = apis
|
56
56
|
@logger = logger
|
57
57
|
|
58
|
-
@client = HTTP::Client.new(current_api, logger)
|
58
|
+
@client = HTTP::Client.new(current_api, logger: logger)
|
59
59
|
end
|
60
60
|
|
61
61
|
def send_info
|
@@ -108,9 +108,9 @@ module Datadog
|
|
108
108
|
value = value.to_i
|
109
109
|
|
110
110
|
if values.empty?
|
111
|
-
values << [Time.now.to_i, value]
|
111
|
+
values << [Core::Utils::Time.now.to_i, value]
|
112
112
|
else
|
113
|
-
values[0][0] = Time.now.to_i
|
113
|
+
values[0][0] = Core::Utils::Time.now.to_i
|
114
114
|
values[0][1] += value
|
115
115
|
end
|
116
116
|
nil
|
@@ -129,9 +129,9 @@ module Datadog
|
|
129
129
|
|
130
130
|
def track(value)
|
131
131
|
if values.empty?
|
132
|
-
values << [Time.now.to_i, value]
|
132
|
+
values << [Core::Utils::Time.now.to_i, value]
|
133
133
|
else
|
134
|
-
values[0][0] = Time.now.to_i
|
134
|
+
values[0][0] = Core::Utils::Time.now.to_i
|
135
135
|
values[0][1] = value
|
136
136
|
end
|
137
137
|
nil
|
@@ -155,7 +155,7 @@ module Datadog
|
|
155
155
|
|
156
156
|
def track(value = 1.0)
|
157
157
|
@value += value
|
158
|
-
@values = [[Time.now.to_i, @value / interval]]
|
158
|
+
@values = [[Core::Utils::Time.now.to_i, @value / interval]]
|
159
159
|
nil
|
160
160
|
end
|
161
161
|
end
|
@@ -21,7 +21,7 @@ module Datadog
|
|
21
21
|
:default_headers,
|
22
22
|
:logger
|
23
23
|
|
24
|
-
def initialize(api_instance_class:, logger:)
|
24
|
+
def initialize(api_instance_class:, logger: Datadog.logger)
|
25
25
|
# Global settings
|
26
26
|
@default_adapter = nil
|
27
27
|
@default_headers = {}
|
@@ -88,7 +88,7 @@ module Datadog
|
|
88
88
|
def to_transport(klass)
|
89
89
|
raise NoDefaultApiError if @default_api.nil?
|
90
90
|
|
91
|
-
klass.new(to_api_instances, @default_api, logger)
|
91
|
+
klass.new(to_api_instances, @default_api, logger: logger)
|
92
92
|
end
|
93
93
|
|
94
94
|
def to_api_instances
|
@@ -29,7 +29,7 @@ module Datadog
|
|
29
29
|
# Helper function that delegates to Builder.new
|
30
30
|
# but is under HTTP namespace so that client code requires this file
|
31
31
|
# to get the adapters configured, and not the builder directly.
|
32
|
-
def build(api_instance_class:, agent_settings:, logger
|
32
|
+
def build(api_instance_class:, agent_settings:, logger: Datadog.logger, api_version: nil, headers: nil, &block)
|
33
33
|
Builder.new(api_instance_class: api_instance_class, logger: logger) do |transport|
|
34
34
|
transport.adapter(agent_settings)
|
35
35
|
transport.headers(default_headers)
|
@@ -17,11 +17,11 @@ module Datadog
|
|
17
17
|
class Transport
|
18
18
|
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
19
19
|
|
20
|
-
def initialize(apis, default_api, logger)
|
20
|
+
def initialize(apis, default_api, logger:)
|
21
21
|
@apis = apis
|
22
22
|
@logger = logger
|
23
23
|
|
24
|
-
@client = HTTP::Client.new(current_api, logger)
|
24
|
+
@client = HTTP::Client.new(current_api, logger: logger)
|
25
25
|
end
|
26
26
|
|
27
27
|
def current_api
|
@@ -1,15 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'uri'
|
4
|
-
|
5
|
-
require_relative '../../core/environment/container'
|
6
|
-
require_relative '../../core/environment/ext'
|
7
|
-
require_relative '../../core/transport/ext'
|
8
3
|
require_relative 'diagnostics'
|
9
4
|
require_relative 'input'
|
10
5
|
require_relative 'http/api'
|
11
6
|
require_relative '../../core/transport/http'
|
12
|
-
require_relative '../../../datadog/version'
|
13
7
|
|
14
8
|
module Datadog
|
15
9
|
module DI
|
@@ -17,11 +17,11 @@ module Datadog
|
|
17
17
|
class Transport
|
18
18
|
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
19
19
|
|
20
|
-
def initialize(apis, default_api, logger)
|
20
|
+
def initialize(apis, default_api, logger:)
|
21
21
|
@apis = apis
|
22
22
|
@logger = logger
|
23
23
|
|
24
|
-
@client = HTTP::Client.new(current_api, logger)
|
24
|
+
@client = HTTP::Client.new(current_api, logger: logger)
|
25
25
|
end
|
26
26
|
|
27
27
|
def current_api
|
@@ -10,6 +10,7 @@ module Datadog
|
|
10
10
|
LOGIN_SUCCESS_EVENT = 'users.login.success'
|
11
11
|
LOGIN_FAILURE_EVENT = 'users.login.failure'
|
12
12
|
SIGNUP_EVENT = 'users.signup'
|
13
|
+
USER_LOGIN_KEYS = ['usr.login', :'usr.login'].freeze
|
13
14
|
|
14
15
|
class << self
|
15
16
|
# Attach login success event information to the trace
|
@@ -30,10 +31,11 @@ module Datadog
|
|
30
31
|
set_trace_and_span_context('track_login_success', trace, span) do |active_trace, active_span|
|
31
32
|
user_options = user.dup
|
32
33
|
user_id = user_options.delete(:id)
|
33
|
-
user_login = user_options[:login] || others[:'usr.login'] || user_id
|
34
|
+
user_login = user_options[:login] || others[:'usr.login'] || others['usr.login'] || user_id
|
34
35
|
|
35
36
|
raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
|
36
37
|
|
38
|
+
others = others.reject { |key, _| USER_LOGIN_KEYS.include?(key) }
|
37
39
|
others[:'usr.login'] = user_login
|
38
40
|
track(LOGIN_SUCCESS_EVENT, active_trace, active_span, **others)
|
39
41
|
|
@@ -58,7 +60,7 @@ module Datadog
|
|
58
60
|
# event information to attach to the trace.
|
59
61
|
def track_login_failure(trace = nil, span = nil, user_exists:, user_id: nil, **others)
|
60
62
|
set_trace_and_span_context('track_login_failure', trace, span) do |active_trace, active_span|
|
61
|
-
others[:'usr.login'] = user_id if user_id && !others.key?(:'usr.login')
|
63
|
+
others[:'usr.login'] = user_id if user_id && !others.key?(:'usr.login') && !others.key?('usr.login')
|
62
64
|
track(LOGIN_FAILURE_EVENT, active_trace, active_span, **others)
|
63
65
|
|
64
66
|
active_span.set_tag('appsec.events.users.login.failure.usr.id', user_id) if user_id
|
@@ -84,10 +86,11 @@ module Datadog
|
|
84
86
|
set_trace_and_span_context('track_signup', trace, span) do |active_trace, active_span|
|
85
87
|
user_options = user.dup
|
86
88
|
user_id = user_options.delete(:id)
|
87
|
-
user_login = user_options[:login] || others[:'usr.login'] || user_id
|
89
|
+
user_login = user_options[:login] || others[:'usr.login'] || others['usr.login'] || user_id
|
88
90
|
|
89
91
|
raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
|
90
92
|
|
93
|
+
others = others.reject { |key, _| USER_LOGIN_KEYS.include?(key) }
|
91
94
|
others[:'usr.login'] = user_login
|
92
95
|
track(SIGNUP_EVENT, active_trace, active_span, **others)
|
93
96
|
|
@@ -31,6 +31,9 @@ module Datadog
|
|
31
31
|
# Instead of trying to figure out real process start time by checking
|
32
32
|
# /proc or some other complex/non-portable way, approximate start time
|
33
33
|
# by time of requirement of this file.
|
34
|
+
#
|
35
|
+
# Note: this does not use Core::Utils::Time.now because this constant
|
36
|
+
# gets initialized before a user has a chance to configure the library.
|
34
37
|
START_TIME = Time.now.utc.freeze
|
35
38
|
|
36
39
|
def collect_platform_info
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Profiling
|
5
|
+
# This class exists to wrap a ddog_prof_EncodedProfile into a Ruby object
|
6
|
+
#
|
7
|
+
# This class is not empty; all of this class is implemented as native code.
|
8
|
+
class EncodedProfile # rubocop:disable Lint/EmptyClass
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -57,7 +57,7 @@ module Datadog
|
|
57
57
|
serialization_result = pprof_recorder.serialize
|
58
58
|
return if serialization_result.nil?
|
59
59
|
|
60
|
-
start, finish,
|
60
|
+
start, finish, encoded_profile, profile_stats = serialization_result
|
61
61
|
@last_flush_finish_at = finish
|
62
62
|
|
63
63
|
if duration_below_threshold?(start, finish)
|
@@ -70,8 +70,7 @@ module Datadog
|
|
70
70
|
Flush.new(
|
71
71
|
start: start,
|
72
72
|
finish: finish,
|
73
|
-
|
74
|
-
pprof_data: compressed_pprof.to_s,
|
73
|
+
encoded_profile: encoded_profile,
|
75
74
|
code_provenance_file_name: Datadog::Profiling::Ext::Transport::HTTP::CODE_PROVENANCE_FILENAME,
|
76
75
|
code_provenance_data: uncompressed_code_provenance,
|
77
76
|
tags_as_array: Datadog::Profiling::TagBuilder.call(settings: Datadog.configuration).to_a,
|
@@ -9,10 +9,9 @@ module Datadog
|
|
9
9
|
attr_reader \
|
10
10
|
:start,
|
11
11
|
:finish,
|
12
|
-
:
|
13
|
-
:pprof_data, # gzipped pprof bytes
|
12
|
+
:encoded_profile,
|
14
13
|
:code_provenance_file_name,
|
15
|
-
:code_provenance_data,
|
14
|
+
:code_provenance_data,
|
16
15
|
:tags_as_array,
|
17
16
|
:internal_metadata_json,
|
18
17
|
:info_json
|
@@ -20,8 +19,7 @@ module Datadog
|
|
20
19
|
def initialize(
|
21
20
|
start:,
|
22
21
|
finish:,
|
23
|
-
|
24
|
-
pprof_data:,
|
22
|
+
encoded_profile:,
|
25
23
|
code_provenance_file_name:,
|
26
24
|
code_provenance_data:,
|
27
25
|
tags_as_array:,
|
@@ -30,8 +28,7 @@ module Datadog
|
|
30
28
|
)
|
31
29
|
@start = start
|
32
30
|
@finish = finish
|
33
|
-
@
|
34
|
-
@pprof_data = pprof_data
|
31
|
+
@encoded_profile = encoded_profile
|
35
32
|
@code_provenance_file_name = code_provenance_file_name
|
36
33
|
@code_provenance_data = code_provenance_data
|
37
34
|
@tags_as_array = tags_as_array
|