sqreen 1.19.1-java → 1.21.0.beta3-java
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 +5 -5
- data/CHANGELOG.md +34 -0
- data/lib/sqreen/actions/block_user.rb +1 -1
- data/lib/sqreen/actions/redirect_ip.rb +1 -1
- data/lib/sqreen/actions/redirect_user.rb +1 -1
- data/lib/sqreen/agent_message.rb +20 -0
- data/lib/sqreen/aggregated_metric.rb +25 -0
- data/lib/sqreen/attack_detected.html +1 -2
- data/lib/sqreen/ca.crt +24 -0
- data/lib/sqreen/condition_evaluator.rb +9 -2
- data/lib/sqreen/conditionable.rb +24 -6
- data/lib/sqreen/configuration.rb +11 -5
- data/lib/sqreen/deferred_logger.rb +50 -14
- data/lib/sqreen/deliveries/batch.rb +12 -2
- data/lib/sqreen/deliveries/simple.rb +4 -0
- data/lib/sqreen/deprecation.rb +38 -0
- data/lib/sqreen/ecosystem.rb +96 -0
- data/lib/sqreen/ecosystem/dispatch_table.rb +43 -0
- data/lib/sqreen/ecosystem/exception_reporting.rb +26 -0
- data/lib/sqreen/ecosystem/http/net_http.rb +50 -0
- data/lib/sqreen/ecosystem/http/rack_request.rb +39 -0
- data/lib/sqreen/ecosystem/loggable.rb +13 -0
- data/lib/sqreen/ecosystem/module_api.rb +30 -0
- data/lib/sqreen/ecosystem/module_api/event_listener.rb +18 -0
- data/lib/sqreen/ecosystem/module_api/instrumentation.rb +23 -0
- data/lib/sqreen/ecosystem/module_api/message_producer.rb +51 -0
- data/lib/sqreen/ecosystem/module_api/signal_producer.rb +24 -0
- data/lib/sqreen/ecosystem/module_api/tracing.rb +45 -0
- data/lib/sqreen/ecosystem/module_api/tracing/client_data.rb +31 -0
- data/lib/sqreen/ecosystem/module_api/tracing/server_data.rb +27 -0
- data/lib/sqreen/ecosystem/module_api/tracing_id_generation.rb +16 -0
- data/lib/sqreen/ecosystem/module_api/transaction_storage.rb +71 -0
- data/lib/sqreen/ecosystem/module_registry.rb +44 -0
- data/lib/sqreen/ecosystem/redis/redis_connection.rb +43 -0
- data/lib/sqreen/ecosystem/tracing/modules/client.rb +31 -0
- data/lib/sqreen/ecosystem/tracing/modules/server.rb +30 -0
- data/lib/sqreen/ecosystem/tracing/sampler.rb +160 -0
- data/lib/sqreen/ecosystem/tracing/sampling_configuration.rb +150 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_client.rb +53 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_server.rb +53 -0
- data/lib/sqreen/ecosystem/tracing_broker.rb +101 -0
- data/lib/sqreen/ecosystem/tracing_id_setup.rb +34 -0
- data/lib/sqreen/ecosystem/transaction_storage.rb +64 -0
- data/lib/sqreen/ecosystem/util/call_writers_from_init.rb +13 -0
- data/lib/sqreen/ecosystem_integration.rb +87 -0
- data/lib/sqreen/ecosystem_integration/around_callbacks.rb +99 -0
- data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +42 -0
- data/lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb +58 -0
- data/lib/sqreen/ecosystem_integration/signal_consumption.rb +35 -0
- data/lib/sqreen/endpoint_testing.rb +184 -0
- data/lib/sqreen/event.rb +7 -5
- data/lib/sqreen/events/attack.rb +23 -18
- data/lib/sqreen/events/remote_exception.rb +0 -22
- data/lib/sqreen/events/request_record.rb +15 -71
- data/lib/sqreen/frameworks/generic.rb +24 -1
- data/lib/sqreen/frameworks/rails.rb +0 -7
- data/lib/sqreen/frameworks/request_recorder.rb +15 -2
- data/lib/sqreen/graft/call.rb +106 -19
- data/lib/sqreen/graft/callback.rb +1 -1
- data/lib/sqreen/graft/hook.rb +212 -100
- data/lib/sqreen/graft/hook_point.rb +18 -11
- data/lib/sqreen/kit/signals/specialized/aggregated_metric.rb +72 -0
- data/lib/sqreen/kit/signals/specialized/attack.rb +57 -0
- data/lib/sqreen/kit/signals/specialized/binning_metric.rb +76 -0
- data/lib/sqreen/kit/signals/specialized/http_trace.rb +26 -0
- data/lib/sqreen/kit/signals/specialized/sdk_track_call.rb +50 -0
- data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +57 -0
- data/lib/sqreen/legacy/instrumentation.rb +22 -10
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +228 -0
- data/lib/sqreen/legacy/waf_redactions.rb +49 -0
- data/lib/sqreen/log.rb +3 -2
- data/lib/sqreen/log/loggable.rb +2 -1
- data/lib/sqreen/logger.rb +24 -0
- data/lib/sqreen/metrics.rb +1 -0
- data/lib/sqreen/metrics/base.rb +3 -0
- data/lib/sqreen/metrics/req_detailed.rb +41 -0
- data/lib/sqreen/metrics_store.rb +33 -12
- data/lib/sqreen/null_logger.rb +22 -0
- data/lib/sqreen/performance_notifications/binned_metrics.rb +8 -2
- data/lib/sqreen/remote_command.rb +4 -0
- data/lib/sqreen/rules.rb +12 -6
- data/lib/sqreen/rules/blacklist_ips_cb.rb +2 -2
- data/lib/sqreen/rules/custom_error_cb.rb +3 -3
- data/lib/sqreen/rules/not_found_cb.rb +2 -0
- data/lib/sqreen/rules/rule_cb.rb +6 -2
- data/lib/sqreen/rules/waf_cb.rb +16 -13
- data/lib/sqreen/runner.rb +138 -16
- data/lib/sqreen/sensitive_data_redactor.rb +19 -31
- data/lib/sqreen/session.rb +53 -43
- data/lib/sqreen/signals/conversions.rb +288 -0
- data/lib/sqreen/signals/http_trace_redaction.rb +111 -0
- data/lib/sqreen/signals/signals_submission_strategy.rb +78 -0
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/budget.rb +35 -0
- data/lib/sqreen/weave/legacy/instrumentation.rb +277 -135
- data/lib/sqreen/worker.rb +6 -2
- metadata +86 -10
- data/lib/sqreen/backport.rb +0 -9
- data/lib/sqreen/backport/clock_gettime.rb +0 -74
- data/lib/sqreen/backport/original_name.rb +0 -88
- data/lib/sqreen/encoding_sanitizer.rb +0 -27
@@ -61,7 +61,7 @@ module Sqreen
|
|
61
61
|
obj.each do |k, v|
|
62
62
|
ck = k.is_a?(String) ? k.downcase : k
|
63
63
|
if @keys.include?(ck)
|
64
|
-
redacted
|
64
|
+
redacted += SensitiveDataRedactor.all_strings(v)
|
65
65
|
v = MASK
|
66
66
|
else
|
67
67
|
v, r = redact(v)
|
@@ -74,39 +74,27 @@ module Sqreen
|
|
74
74
|
[result, redacted]
|
75
75
|
end
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
next(e) unless e[:infos]
|
84
|
-
next(e) unless e[:infos][:waf_data]
|
85
|
-
|
86
|
-
parsed = JSON.parse(e[:infos][:waf_data])
|
87
|
-
redacted = parsed.each do |w|
|
88
|
-
next unless (filters = w['filter'])
|
89
|
-
|
90
|
-
filters.each do |f|
|
91
|
-
next unless (v = f['resolved_value'])
|
92
|
-
next unless values.include?(v.downcase)
|
77
|
+
class << self
|
78
|
+
def all_strings(v)
|
79
|
+
accum = []
|
80
|
+
all_strings_impl(v, accum)
|
81
|
+
accum
|
82
|
+
end
|
93
83
|
|
94
|
-
|
95
|
-
|
84
|
+
private
|
85
|
+
|
86
|
+
def all_strings_impl(obj, accum)
|
87
|
+
case obj
|
88
|
+
when String
|
89
|
+
accum << obj
|
90
|
+
when Array
|
91
|
+
obj.each { |el| all_strings_impl(el, accum) }
|
92
|
+
when Hash
|
93
|
+
obj.each do |k, v|
|
94
|
+
all_strings_impl(k, accum)
|
95
|
+
all_strings_impl(v, accum)
|
96
96
|
end
|
97
97
|
end
|
98
|
-
e[:infos][:waf_data] = JSON.dump(redacted)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def redact_exceptions!(exceptions, values)
|
103
|
-
return exceptions if values.empty?
|
104
|
-
|
105
|
-
exceptions.each do |e|
|
106
|
-
next(e) unless e[:infos]
|
107
|
-
next(e) unless e[:infos][:waf]
|
108
|
-
|
109
|
-
e[:infos][:waf].delete(:args)
|
110
98
|
end
|
111
99
|
end
|
112
100
|
end
|
data/lib/sqreen/session.rb
CHANGED
@@ -11,6 +11,10 @@ require 'sqreen/events/attack'
|
|
11
11
|
require 'sqreen/events/request_record'
|
12
12
|
require 'sqreen/exception'
|
13
13
|
require 'sqreen/safe_json'
|
14
|
+
require 'sqreen/kit'
|
15
|
+
require 'sqreen/kit/configuration'
|
16
|
+
require 'sqreen/signals/signals_submission_strategy'
|
17
|
+
require 'sqreen/legacy/old_event_submission_strategy'
|
14
18
|
|
15
19
|
require 'net/https'
|
16
20
|
require 'uri'
|
@@ -41,13 +45,12 @@ module Sqreen
|
|
41
45
|
RETRY_MANY = 301
|
42
46
|
|
43
47
|
MUTEX = Mutex.new
|
44
|
-
METRICS_KEY = 'metrics'.freeze
|
45
48
|
|
46
49
|
@@path_prefix = '/sqreen/v0/'
|
47
50
|
|
48
51
|
attr_accessor :request_compression
|
49
52
|
|
50
|
-
def initialize(server_url, token, app_name = nil)
|
53
|
+
def initialize(server_url, cert_store, token, app_name = nil, proxy_url = nil)
|
51
54
|
@token = token
|
52
55
|
@app_name = app_name
|
53
56
|
@session_id = nil
|
@@ -59,15 +62,29 @@ module Sqreen
|
|
59
62
|
uri = parse_uri(server_url)
|
60
63
|
use_ssl = (uri.scheme == 'https')
|
61
64
|
|
65
|
+
proxy_params = []
|
66
|
+
if proxy_url
|
67
|
+
proxy_uri = parse_uri(proxy_url)
|
68
|
+
proxy_params = [proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password]
|
69
|
+
end
|
70
|
+
|
62
71
|
@req_nb = 0
|
63
72
|
|
64
|
-
@http = Net::HTTP.new(uri.host, uri.port)
|
73
|
+
@http = Net::HTTP.new(uri.host, uri.port, *proxy_params)
|
65
74
|
@http.use_ssl = use_ssl
|
66
|
-
if
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
75
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE if ENV['SQREEN_SSL_NO_VERIFY'] # for testing
|
76
|
+
@http.cert_store = cert_store if use_ssl
|
77
|
+
self.use_signals = false
|
78
|
+
end
|
79
|
+
|
80
|
+
def use_signals=(do_use)
|
81
|
+
return if do_use == @use_signals
|
82
|
+
|
83
|
+
@use_signals = do_use
|
84
|
+
if do_use
|
85
|
+
@evt_sub_strategy = Sqreen::Signals::SignalsSubmissionStrategy.new
|
86
|
+
else
|
87
|
+
@evt_sub_strategy = Sqreen::Legacy::OldEventSubmissionStrategy.new(method(:post))
|
71
88
|
end
|
72
89
|
end
|
73
90
|
|
@@ -218,10 +235,7 @@ module Sqreen
|
|
218
235
|
end
|
219
236
|
|
220
237
|
def login(framework)
|
221
|
-
headers =
|
222
|
-
'x-api-key' => @token,
|
223
|
-
'x-app-name' => @app_name || framework.application_name,
|
224
|
-
}.reject { |k, v| v == nil }
|
238
|
+
headers = prelogin_auth_headers(framework)
|
225
239
|
|
226
240
|
Sqreen.log.warn "Using app name: #{headers['x-app-name']}"
|
227
241
|
|
@@ -235,6 +249,10 @@ module Sqreen
|
|
235
249
|
end
|
236
250
|
Sqreen.log.info 'Login success.'
|
237
251
|
@session_id = res['session_id']
|
252
|
+
|
253
|
+
Kit::Configuration.session_key = @session_id
|
254
|
+
Kit.reset
|
255
|
+
|
238
256
|
Sqreen.log.debug { "received session_id #{@session_id}" }
|
239
257
|
Sqreen.logged_in = true
|
240
258
|
res
|
@@ -246,20 +264,24 @@ module Sqreen
|
|
246
264
|
|
247
265
|
def heartbeat(cmd_res = {}, metrics = [])
|
248
266
|
payload = {}
|
249
|
-
|
267
|
+
unless metrics.nil? || metrics.empty?
|
268
|
+
# never reached with signals
|
269
|
+
payload['metrics'] = metrics.map do |m|
|
270
|
+
Sqreen::Legacy::EventToHash.convert_agg_metric(m)
|
271
|
+
end
|
272
|
+
end
|
250
273
|
payload['command_results'] = cmd_res unless cmd_res.nil? || cmd_res.empty?
|
251
274
|
|
252
275
|
post('app-beat', payload.empty? ? nil : payload, {}, RETRY_MANY)
|
253
276
|
end
|
254
277
|
|
255
278
|
def post_metrics(metrics)
|
256
|
-
|
257
|
-
payload = { METRICS_KEY => metrics }
|
258
|
-
post(METRICS_KEY, payload, {}, RETRY_MANY)
|
279
|
+
@evt_sub_strategy.post_metrics(metrics)
|
259
280
|
end
|
260
281
|
|
282
|
+
# XXX never called
|
261
283
|
def post_attack(attack)
|
262
|
-
|
284
|
+
@evt_sub_strategy.post_attack(attack)
|
263
285
|
end
|
264
286
|
|
265
287
|
def post_bundle(bundle_sig, dependencies)
|
@@ -271,33 +293,22 @@ module Sqreen
|
|
271
293
|
end
|
272
294
|
|
273
295
|
def post_request_record(request_record)
|
274
|
-
|
296
|
+
@evt_sub_strategy.post_request_record(request_record)
|
275
297
|
end
|
276
298
|
|
277
299
|
# Post an exception to Sqreen for analysis
|
278
300
|
# @param exception [RemoteException] Exception and context to be sent over
|
279
301
|
def post_sqreen_exception(exception)
|
280
|
-
|
281
|
-
rescue StandardError => e
|
282
|
-
Sqreen.log.warn(format('Could not post exception (network down? %s) %s',
|
283
|
-
e.inspect,
|
284
|
-
exception.to_hash.inspect))
|
285
|
-
nil
|
302
|
+
@evt_sub_strategy.post_sqreen_exception(exception)
|
286
303
|
end
|
287
304
|
|
288
|
-
BATCH_KEY = 'batch'.freeze
|
289
|
-
EVENT_TYPE_KEY = 'event_type'.freeze
|
290
305
|
def post_batch(events)
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
tally = Hash[events.group_by(&:class).map{ |k,v| [k, v.count] }]
|
298
|
-
"Doing batch with the following tally of event types: #{tally}"
|
299
|
-
end
|
300
|
-
post(BATCH_KEY, { BATCH_KEY => batch }, {}, RETRY_MANY)
|
306
|
+
@evt_sub_strategy.post_batch(events)
|
307
|
+
end
|
308
|
+
|
309
|
+
def post_agent_message(framework, agent_message)
|
310
|
+
headers = prelogin_auth_headers(framework)
|
311
|
+
post('app_agent_message', agent_message.to_h, headers, 0)
|
301
312
|
end
|
302
313
|
|
303
314
|
# Perform agent logout
|
@@ -314,14 +325,13 @@ module Sqreen
|
|
314
325
|
disconnect
|
315
326
|
end
|
316
327
|
|
317
|
-
|
328
|
+
private
|
318
329
|
|
319
|
-
def
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
end
|
330
|
+
def prelogin_auth_headers(framework)
|
331
|
+
{
|
332
|
+
'x-api-key' => @token,
|
333
|
+
'x-app-name' => @app_name || framework.application_name,
|
334
|
+
}.reject { |_k, v| v == nil }
|
325
335
|
end
|
326
336
|
end
|
327
337
|
end
|
@@ -0,0 +1,288 @@
|
|
1
|
+
require 'sqreen/version'
|
2
|
+
require 'sqreen/rules/rule_cb'
|
3
|
+
require 'sqreen/metrics/base'
|
4
|
+
require 'sqreen/metrics/binning'
|
5
|
+
require 'sqreen/signals/http_trace_redaction'
|
6
|
+
require 'sqreen/kit/signals/signal_attributes'
|
7
|
+
require 'sqreen/kit/signals/specialized/aggregated_metric'
|
8
|
+
require 'sqreen/kit/signals/specialized/attack'
|
9
|
+
require 'sqreen/kit/signals/specialized/binning_metric'
|
10
|
+
require 'sqreen/kit/signals/specialized/sqreen_exception'
|
11
|
+
require 'sqreen/kit/signals/specialized/http_trace'
|
12
|
+
require 'sqreen/kit/signals/specialized/sdk_track_call'
|
13
|
+
|
14
|
+
module Sqreen
|
15
|
+
module Signals
|
16
|
+
module Conversions # rubocop:disable Metrics/ModuleLength
|
17
|
+
class << self
|
18
|
+
# @param [Sqreen::AggregatedMetric] agg
|
19
|
+
# @return [Sqreen::Kit::Signals::Metric]
|
20
|
+
def convert_metric_sample(agg)
|
21
|
+
attrs = {
|
22
|
+
signal_name: "sq.agent.metric.#{agg.name}",
|
23
|
+
source: if agg.rule
|
24
|
+
"sqreen:rules:#{agg.rule.rulespack_id}:#{agg.rule.rule_name}"
|
25
|
+
else
|
26
|
+
agent_gen_source
|
27
|
+
end,
|
28
|
+
time: agg.finish,
|
29
|
+
}
|
30
|
+
|
31
|
+
if agg.metric.is_a?(Sqreen::Metric::Binning)
|
32
|
+
conv_binning_metric(agg, attrs)
|
33
|
+
else
|
34
|
+
conv_generic_metric(agg, attrs)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param [Sqreen::Attack] attack
|
39
|
+
# XXX: not used because we don't use Sqreen::Attack
|
40
|
+
def convert_attack(attack)
|
41
|
+
# no need to set actor/context as we only include them in request records/traces
|
42
|
+
Kit::Signals::Specialized::Attack.new(
|
43
|
+
signal_name: "sq.agent.attack.#{attack.attack_type}",
|
44
|
+
source: "sqreen:rule:#{attack.rulespack_id}:#{attack.rule_name}",
|
45
|
+
time: attack.time,
|
46
|
+
location: Kit::Signals::Location.new(stack_trace: attack.backtrace),
|
47
|
+
payload: Kit::Signals::Specialized::Attack::Payload.new(
|
48
|
+
test: attack.test?,
|
49
|
+
block: attack.block?,
|
50
|
+
infos: attack.infos
|
51
|
+
)
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
# see Sqreen::Rules::RuleCB.record_event
|
56
|
+
def convert_unstructured_attack(payload)
|
57
|
+
Kit::Signals::Specialized::Attack.new(
|
58
|
+
signal_name: "sq.agent.attack.#{payload[:attack_type]}",
|
59
|
+
source: "sqreen:rule:#{payload[:rulespack_id]}:#{payload[:rule_name]}",
|
60
|
+
time: payload[:time],
|
61
|
+
location: (Kit::Signals::Location.new(stack_trace: payload[:backtrace]) if payload[:backtrace]),
|
62
|
+
payload: Kit::Signals::Specialized::Attack::Payload.new(
|
63
|
+
test: payload[:test],
|
64
|
+
block: payload[:block],
|
65
|
+
infos: payload[:infos]
|
66
|
+
)
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param [Sqreen::RemoteException] exception
|
71
|
+
# @return [Sqreen::Kit::Signals::Specialized::SqreenException]
|
72
|
+
def convert_exception(exception)
|
73
|
+
payload = exception.payload
|
74
|
+
|
75
|
+
infos = payload['client_ip'] ? { client_ip: payload['client_ip'] } : {}
|
76
|
+
infos.merge!(payload['infos'] || {})
|
77
|
+
|
78
|
+
Kit::Signals::Specialized::SqreenException.new(
|
79
|
+
source: if payload['rule_name']
|
80
|
+
"sqreen:rule:#{payload['rulespack_id']}:#{payload['rule_name']}"
|
81
|
+
else
|
82
|
+
agent_gen_source
|
83
|
+
end,
|
84
|
+
time: exception.time,
|
85
|
+
ruby_exception: payload['exception'],
|
86
|
+
infos: infos
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
# see Sqreen::Rules::RuleCB.record_exception
|
91
|
+
# @param [Hash] payload
|
92
|
+
# @return [Sqreen::Kit::Signals::Specialized::SqreenException]
|
93
|
+
def convert_unstructured_exception(payload)
|
94
|
+
Kit::Signals::Specialized::SqreenException.new(
|
95
|
+
source: "sqreen:rule:#{payload[:rulespack_id]}:#{payload[:rule_name]}",
|
96
|
+
time: payload[:time],
|
97
|
+
ruby_exception: payload[:exception],
|
98
|
+
infos: payload[:infos]
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @param [Sqreen::RequestRecord] req_rec
|
103
|
+
# @return [Sqreen::Kit::Signals::Specialized::HttpTrace]
|
104
|
+
def convert_req_record(req_rec)
|
105
|
+
payload = req_rec.payload
|
106
|
+
|
107
|
+
request_p = payload['request']
|
108
|
+
id_args = req_rec.last_identify_args
|
109
|
+
identifiers = id_args[0] if id_args
|
110
|
+
traits = id_args[1] if id_args
|
111
|
+
|
112
|
+
observed = payload[:observed] || {}
|
113
|
+
signals = []
|
114
|
+
signals += (observed[:attacks] || [])
|
115
|
+
.map { |att| convert_unstructured_attack(att) }
|
116
|
+
signals += (observed[:sqreen_exceptions] || [])
|
117
|
+
.map { |sq_exc| convert_unstructured_exception(sq_exc) }
|
118
|
+
signals += req_rec.processed_sdk_calls
|
119
|
+
.select { |h| h[:name] == :track }
|
120
|
+
.map { |h| convert_track(h) }
|
121
|
+
signals += (observed[:signals] || [])
|
122
|
+
|
123
|
+
trace = Kit::Signals::Specialized::HttpTrace.new(
|
124
|
+
actor: Kit::Signals::Actor.new(
|
125
|
+
ip_addresses: [request_p[:client_ip]].compact,
|
126
|
+
user_agent: request_p[:user_agent],
|
127
|
+
identifiers: identifiers,
|
128
|
+
traits: traits,
|
129
|
+
),
|
130
|
+
location_infra: location_infra,
|
131
|
+
context: convert_request(request_p,
|
132
|
+
payload['response'],
|
133
|
+
payload['headers'],
|
134
|
+
payload['params']),
|
135
|
+
data: signals
|
136
|
+
)
|
137
|
+
HttpTraceRedaction.redact_trace!(trace, req_rec.redactor)
|
138
|
+
trace
|
139
|
+
end
|
140
|
+
|
141
|
+
# @return [Array<Sqreen::Kit::Signals::Signal|Sqreen::Kit::Signals::Trace>]
|
142
|
+
def convert_batch(batch)
|
143
|
+
batch.map do |evt|
|
144
|
+
case evt
|
145
|
+
when RemoteException
|
146
|
+
convert_exception(evt)
|
147
|
+
when AggregatedMetric
|
148
|
+
convert_metric_sample(evt)
|
149
|
+
when RequestRecord
|
150
|
+
convert_req_record(evt)
|
151
|
+
when Sqreen::Kit::Signals::Signal
|
152
|
+
evt
|
153
|
+
when Sqreen::Kit::Signals::Trace
|
154
|
+
evt
|
155
|
+
else
|
156
|
+
raise NotImplementedError, "Unknown type of event in batch: #{evt}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def agent_gen_source
|
164
|
+
"sqreen:agent:ruby:#{Sqreen::VERSION}"
|
165
|
+
end
|
166
|
+
|
167
|
+
def location_infra
|
168
|
+
@location_infra ||= begin
|
169
|
+
Kit::Signals::LocationInfra.new(
|
170
|
+
agent_version: Sqreen::VERSION,
|
171
|
+
os_type: RuntimeInfos.os[:os_type],
|
172
|
+
hostname: RuntimeInfos.hostname,
|
173
|
+
runtime_type: RuntimeInfos.runtime[:runtime_type],
|
174
|
+
runtime_version: RuntimeInfos.runtime[:runtime_version],
|
175
|
+
libsqreen_version: RuntimeInfos.libsqreen_version,
|
176
|
+
)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# see Sqreen::RequestRecord.processed_sdk_calls
|
181
|
+
def convert_track(call_info)
|
182
|
+
options = call_info[:args][1] || {}
|
183
|
+
Kit::Signals::Specialized::SdkTrackCall.new(
|
184
|
+
signal_name: "sq.sdk.#{call_info[:args][0]}",
|
185
|
+
time: call_info[:time],
|
186
|
+
payload: Kit::Signals::Specialized::SdkTrackCall::Payload.new(
|
187
|
+
properties: options[:properties],
|
188
|
+
user_identifiers: options[:user_identifiers]
|
189
|
+
)
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
# @param [Hash] req_payload
|
194
|
+
# @param [Hash] headers_payload
|
195
|
+
# @param [Hash] params_payload
|
196
|
+
# see the PayloadCreator abomination for reference
|
197
|
+
# TODO: do not convert from the old payload to the new payload
|
198
|
+
# Have an intermediate object that gets the data from the framework.
|
199
|
+
# (Or convert directly from the framework, but this needs to be
|
200
|
+
# done during the request, not just before event is transmitted)
|
201
|
+
def convert_request(req_payload, resp_payload, headers_payload, params_payload)
|
202
|
+
req_payload ||= {}
|
203
|
+
headers_payload ||= {}
|
204
|
+
resp_payload ||= {}
|
205
|
+
params_payload ||= {}
|
206
|
+
|
207
|
+
other = params_payload['other']
|
208
|
+
other = merge_hash_append(other, params_payload['rack'])
|
209
|
+
other = merge_hash_append(other, params_payload['grape_params'])
|
210
|
+
other = merge_hash_append(other, params_payload['rack_routing'])
|
211
|
+
|
212
|
+
Sqreen::Kit::Signals::Context::HttpContext.new(
|
213
|
+
{
|
214
|
+
rid: req_payload[:rid],
|
215
|
+
headers: headers_payload,
|
216
|
+
user_agent: req_payload[:user_agent],
|
217
|
+
scheme: req_payload[:scheme],
|
218
|
+
verb: req_payload[:verb],
|
219
|
+
host: req_payload[:host],
|
220
|
+
port: req_payload[:port],
|
221
|
+
remote_ip: req_payload[:remote_ip],
|
222
|
+
remote_port: req_payload[:remote_port] || 0,
|
223
|
+
path: req_payload[:path],
|
224
|
+
referer: req_payload[:referer],
|
225
|
+
params_query: params_payload['query'],
|
226
|
+
params_form: params_payload['form'],
|
227
|
+
params_other: other,
|
228
|
+
# endpoint, is_reveal_replayed not set
|
229
|
+
status: resp_payload[:status],
|
230
|
+
content_length: resp_payload[:content_length],
|
231
|
+
content_type: resp_payload[:content_type],
|
232
|
+
}
|
233
|
+
)
|
234
|
+
end
|
235
|
+
|
236
|
+
def merge_hash_append(hash1, hash2)
|
237
|
+
return nil if hash1.nil? && hash2.nil?
|
238
|
+
return hash1 if hash2.nil? || hash2.empty?
|
239
|
+
return hash2 if hash1.nil? || hash1.empty?
|
240
|
+
|
241
|
+
pairs = (hash1.keys + hash2.keys).map do |key|
|
242
|
+
values1 = hash1[key]
|
243
|
+
values2 = hash2[key]
|
244
|
+
values = [values1, values2].compact
|
245
|
+
values = values.first if values.size == 1
|
246
|
+
[key, values]
|
247
|
+
end
|
248
|
+
Hash[pairs]
|
249
|
+
end
|
250
|
+
|
251
|
+
# @param [Sqreen::AggregatedMetric] agg
|
252
|
+
# @param [Hash] attrs
|
253
|
+
def conv_generic_metric(agg, attrs)
|
254
|
+
attrs[:payload] = Kit::Signals::Specialized::AggregatedMetric::Payload.new(
|
255
|
+
kind: metric_kind(agg.metric),
|
256
|
+
capture_interval_s: agg.metric.period,
|
257
|
+
date_started: agg.start,
|
258
|
+
date_ended: agg.finish,
|
259
|
+
values: agg.data
|
260
|
+
)
|
261
|
+
|
262
|
+
Kit::Signals::Specialized::AggregatedMetric.new(attrs)
|
263
|
+
end
|
264
|
+
|
265
|
+
# @param [Sqreen::AggregatedMetric] agg
|
266
|
+
# @param [Hash] attrs
|
267
|
+
def conv_binning_metric(agg, attrs)
|
268
|
+
attrs[:payload] = Kit::Signals::Specialized::BinningMetric::Payload.new(
|
269
|
+
capture_interval_s: agg.metric.period,
|
270
|
+
date_started: agg.start,
|
271
|
+
date_ended: agg.finish,
|
272
|
+
base: agg.data['b'],
|
273
|
+
unit: agg.data['u'],
|
274
|
+
max: agg.data['v']['max'],
|
275
|
+
bins: agg.data['v'].reject { |k, _v| k == 'max' }
|
276
|
+
)
|
277
|
+
|
278
|
+
Kit::Signals::Specialized::BinningMetric.new(attrs)
|
279
|
+
end
|
280
|
+
|
281
|
+
# @param [Sqreen::Metric::Base] metric
|
282
|
+
def metric_kind(metric)
|
283
|
+
metric.class.name.sub(/.*::/, '').sub(/Metric$/, '')
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|