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
data/lib/sqreen/null_logger.rb
CHANGED
@@ -9,6 +9,26 @@ module Sqreen
|
|
9
9
|
class NullLogger
|
10
10
|
include Singleton
|
11
11
|
|
12
|
+
def debug?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def info?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def warn?
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def error?
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
def fatal?
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
12
32
|
def debug(_msg = nil); end
|
13
33
|
|
14
34
|
def info(_msg = nil); end
|
@@ -19,6 +39,8 @@ module Sqreen
|
|
19
39
|
|
20
40
|
def fatal(_msg = nil); end
|
21
41
|
|
42
|
+
def unknown(_msg = nil); end
|
43
|
+
|
22
44
|
def add(_severity, _msg = nil); end
|
23
45
|
|
24
46
|
def formatter=(_); end
|
@@ -122,10 +122,16 @@ module Sqreen
|
|
122
122
|
attr_reader :metrics_store
|
123
123
|
attr_reader :period
|
124
124
|
|
125
|
-
def ensure_metric(metric_name)
|
125
|
+
def ensure_metric(metric_name, rule = nil)
|
126
126
|
return if metrics_store.metric?(metric_name)
|
127
127
|
metrics_store.create_metric(
|
128
|
-
|
128
|
+
{
|
129
|
+
'name' => metric_name,
|
130
|
+
'period' => period,
|
131
|
+
'kind' => 'Binning',
|
132
|
+
'options' => @perf_metric_opts,
|
133
|
+
},
|
134
|
+
rule
|
129
135
|
)
|
130
136
|
end
|
131
137
|
|
@@ -18,10 +18,12 @@ module Sqreen
|
|
18
18
|
:features_get => :features,
|
19
19
|
:features_change => :change_features,
|
20
20
|
:force_logout => :shutdown,
|
21
|
+
:force_restart => :restart,
|
21
22
|
:paths_whitelist => :change_whitelisted_paths,
|
22
23
|
:ips_whitelist => :change_whitelisted_ips,
|
23
24
|
:get_bundle => :upload_bundle,
|
24
25
|
:performance_budget => :change_performance_budget,
|
26
|
+
:tracing_enable => :tracing_enable,
|
25
27
|
}.freeze
|
26
28
|
|
27
29
|
attr_reader :uuid
|
@@ -39,6 +41,8 @@ module Sqreen
|
|
39
41
|
begin
|
40
42
|
output = runner.send(KNOWN_COMMANDS[@name], *@params, context_infos)
|
41
43
|
rescue => e
|
44
|
+
Sqreen.log.warn { "Command failed with #{e}" }
|
45
|
+
Sqreen.log.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
42
46
|
Sqreen::RemoteException.record(e)
|
43
47
|
return { :status => false, :reason => "error: #{e.inspect}" }
|
44
48
|
end
|
data/lib/sqreen/rules.rb
CHANGED
@@ -114,15 +114,19 @@ module Sqreen
|
|
114
114
|
Sqreen.log.warn('No JavaScript engine is available. ' \
|
115
115
|
'JavaScript callbacks will be ignored')
|
116
116
|
end
|
117
|
-
Sqreen.log.
|
117
|
+
Sqreen.log.debug("Ignoring JS callback #{rule_name}")
|
118
118
|
return nil
|
119
119
|
end
|
120
120
|
|
121
121
|
cb_class = ExecJSCB if js
|
122
122
|
|
123
|
-
if cbname
|
124
|
-
|
125
|
-
|
123
|
+
if cbname
|
124
|
+
cb_class = if cbname.include?('::')
|
125
|
+
# Only load callbacks from sqreen
|
126
|
+
Rules.walk_const_get(cbname) if cbname.start_with?('::Sqreen::', 'Sqreen::')
|
127
|
+
else
|
128
|
+
Rules.const_get(cbname) if Rules.const_defined?(cbname) # rubocop:disable Style/IfInsideElse
|
129
|
+
end
|
126
130
|
end
|
127
131
|
|
128
132
|
if cb_class.nil?
|
@@ -135,13 +139,15 @@ module Sqreen
|
|
135
139
|
return nil
|
136
140
|
end
|
137
141
|
|
142
|
+
rule_cb = cb_class.new(instr_class, instr_method, hash_rule)
|
143
|
+
|
138
144
|
if metrics_store
|
139
145
|
(hash_rule[Attrs::METRICS] || []).each do |metric|
|
140
|
-
metrics_store.create_metric(metric)
|
146
|
+
metrics_store.create_metric(metric, rule_cb)
|
141
147
|
end
|
142
148
|
end
|
143
149
|
|
144
|
-
|
150
|
+
rule_cb
|
145
151
|
rescue => e
|
146
152
|
rule_name = nil
|
147
153
|
rulespack_id = nil
|
@@ -33,7 +33,7 @@ module Sqreen
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def insert_values(ranges)
|
36
|
-
Sqreen.log.
|
36
|
+
Sqreen.log.debug 'no ips given for IP blacklisting' if ranges.empty?
|
37
37
|
|
38
38
|
ranges.map { |r| Prefix.from_str(r, r) }.each do |prefix|
|
39
39
|
trie_for(prefix).insert prefix
|
@@ -50,7 +50,7 @@ module Sqreen
|
|
50
50
|
begin
|
51
51
|
ipa = IPAddr.new(rip)
|
52
52
|
rescue StandardError
|
53
|
-
Sqreen.log.
|
53
|
+
Sqreen.log.debug "invalid IP address given by framework: #{rip}"
|
54
54
|
return nil
|
55
55
|
end
|
56
56
|
|
@@ -55,12 +55,12 @@ module Sqreen
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def respond_page
|
58
|
-
page
|
58
|
+
@page ||= File.read(File.join(File.dirname(__FILE__), '../attack_detected.html'))
|
59
59
|
headers = {
|
60
60
|
'Content-Type' => 'text/html',
|
61
|
-
'Content-Length' => page.size.to_s,
|
61
|
+
'Content-Length' => @page.size.to_s,
|
62
62
|
}
|
63
|
-
[@status_code, headers, page]
|
63
|
+
[@status_code, headers, [@page]]
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
data/lib/sqreen/rules/rule_cb.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
4
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
5
5
|
|
6
|
+
require 'sqreen/deprecation'
|
6
7
|
require 'sqreen/framework_cb'
|
7
8
|
require 'sqreen/context'
|
8
9
|
require 'sqreen/conditionable'
|
@@ -61,7 +62,9 @@ module Sqreen
|
|
61
62
|
:infos => infos,
|
62
63
|
:rulespack_id => rulespack_id,
|
63
64
|
:rule_name => rule_name,
|
65
|
+
:attack_type => @rule['attack_type'], # for signal
|
64
66
|
:test => test,
|
67
|
+
:block => @rule['block'], # for signal
|
65
68
|
:time => at,
|
66
69
|
}
|
67
70
|
if payload_tpl.include?('context')
|
@@ -87,9 +90,9 @@ module Sqreen
|
|
87
90
|
framework.observe(:sqreen_exceptions, payload)
|
88
91
|
end
|
89
92
|
|
90
|
-
# Recommend taking an action (
|
93
|
+
# Recommend taking an action (optionally adding more data/context)
|
91
94
|
#
|
92
|
-
# This will format the requested action and
|
95
|
+
# This will format the requested action and optionally
|
93
96
|
# override it if it should not be taken (should not block for example)
|
94
97
|
def advise_action(action, additional_data = {})
|
95
98
|
return if action.nil? && additional_data.empty?
|
@@ -107,6 +110,7 @@ module Sqreen
|
|
107
110
|
)
|
108
111
|
true
|
109
112
|
end
|
113
|
+
Sqreen::Deprecation.deprecate(instance_method(:overtime!))
|
110
114
|
end
|
111
115
|
end
|
112
116
|
end
|
data/lib/sqreen/rules/waf_cb.rb
CHANGED
@@ -11,7 +11,7 @@ require 'sqreen/safe_json'
|
|
11
11
|
require 'sqreen/exception'
|
12
12
|
require 'sqreen/util/capper'
|
13
13
|
require 'sqreen/dependency/libsqreen'
|
14
|
-
require 'sqreen/
|
14
|
+
require 'sqreen/kit/string_sanitizer'
|
15
15
|
|
16
16
|
module Sqreen
|
17
17
|
module Rules
|
@@ -60,7 +60,7 @@ module Sqreen
|
|
60
60
|
end
|
61
61
|
|
62
62
|
# 0 for using defaults (PW_RUN_TIMEOUT)
|
63
|
-
@max_run_budget_us = (@data['values'].fetch('
|
63
|
+
@max_run_budget_us = (@data['values'].fetch('max_budget_ms', 0) * 1000).to_i
|
64
64
|
@max_run_budget_us = INFINITE_BUDGET_US if @max_run_budget_us >= INFINITE_BUDGET_US
|
65
65
|
|
66
66
|
Sqreen.log.debug { "Max WAF run budget for #{@waf_rule_name} set to #{@max_run_budget_us} us" }
|
@@ -82,7 +82,7 @@ module Sqreen
|
|
82
82
|
waf_args = binding_accessors.each_with_object({}) do |(e, b), h|
|
83
83
|
h[e] = capper.call(b.resolve(*env))
|
84
84
|
end
|
85
|
-
waf_args = Sqreen::
|
85
|
+
waf_args = Sqreen::Kit::StringSanitizer.sanitize(waf_args)
|
86
86
|
|
87
87
|
if budget
|
88
88
|
rem_budget_s = budget - (Sqreen.time - start)
|
@@ -98,10 +98,10 @@ module Sqreen
|
|
98
98
|
|
99
99
|
case action
|
100
100
|
when :monitor
|
101
|
-
record_event({
|
101
|
+
record_event({ waf_data: data })
|
102
102
|
advise_action(nil)
|
103
103
|
when :block
|
104
|
-
record_event({
|
104
|
+
record_event({ waf_data: data })
|
105
105
|
advise_action(:raise)
|
106
106
|
when :good
|
107
107
|
advise_action(nil)
|
@@ -132,20 +132,23 @@ module Sqreen
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def record_exception(exception, infos = {}, at = Time.now.utc)
|
135
|
-
infos.merge!(
|
135
|
+
infos.merge!(waf_infos(exception)) if exception.is_a?(Sqreen::WAFError)
|
136
136
|
super(exception, infos, at)
|
137
137
|
end
|
138
138
|
|
139
139
|
private
|
140
140
|
|
141
|
-
|
141
|
+
# see https://github.com/sqreen/TechDoc/blob/master/content/specs/spec000016-waf-integration.md#error-management
|
142
|
+
def waf_infos(e)
|
142
143
|
{
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
144
|
+
waf: {
|
145
|
+
waf_rule: e.rule_name,
|
146
|
+
error_code: ERROR_CODES[e.error],
|
147
|
+
}.tap do |r|
|
148
|
+
r[:error_data] = e.data if e.data
|
149
|
+
r[:args] = e.args if e.arg
|
150
|
+
end,
|
151
|
+
}
|
149
152
|
end
|
150
153
|
|
151
154
|
ERROR_CODES = {
|
data/lib/sqreen/runner.rb
CHANGED
@@ -11,18 +11,23 @@ require 'sqreen/events/attack'
|
|
11
11
|
|
12
12
|
require 'sqreen/log'
|
13
13
|
|
14
|
+
require 'sqreen/agent_message'
|
14
15
|
require 'sqreen/rules'
|
15
16
|
require 'sqreen/session'
|
17
|
+
require 'sqreen/version'
|
16
18
|
require 'sqreen/remote_command'
|
17
19
|
require 'sqreen/capped_queue'
|
18
20
|
require 'sqreen/metrics_store'
|
19
21
|
require 'sqreen/deliveries/simple'
|
20
22
|
require 'sqreen/deliveries/batch'
|
23
|
+
require 'sqreen/endpoint_testing'
|
21
24
|
require 'sqreen/performance_notifications/metrics'
|
22
25
|
require 'sqreen/performance_notifications/binned_metrics'
|
23
26
|
require 'sqreen/legacy/instrumentation'
|
24
27
|
require 'sqreen/call_countable'
|
25
28
|
require 'sqreen/weave/legacy/instrumentation'
|
29
|
+
require 'sqreen/kit/configuration'
|
30
|
+
require 'sqreen/ecosystem_integration'
|
26
31
|
|
27
32
|
module Sqreen
|
28
33
|
@features = {}
|
@@ -37,6 +42,8 @@ module Sqreen
|
|
37
42
|
PERF_METRICS_PERIOD = 60 # 1 min
|
38
43
|
DEFAULT_PERF_LEVEL = 0 # disabled
|
39
44
|
|
45
|
+
DEFAULT_USE_SIGNALS = false
|
46
|
+
|
40
47
|
class << self
|
41
48
|
attr_reader :features
|
42
49
|
def update_features(features)
|
@@ -47,10 +54,6 @@ module Sqreen
|
|
47
54
|
@queue ||= CappedQueue.new(MAX_QUEUE_LENGTH)
|
48
55
|
end
|
49
56
|
|
50
|
-
def update_queue(queue)
|
51
|
-
@queue = queue
|
52
|
-
end
|
53
|
-
|
54
57
|
def observations_queue
|
55
58
|
@observations_queue ||= CappedQueue.new(MAX_OBS_QUEUE_LENGTH)
|
56
59
|
end
|
@@ -87,7 +90,9 @@ module Sqreen
|
|
87
90
|
|
88
91
|
attr_accessor :heartbeat_delay
|
89
92
|
attr_accessor :metrics_engine
|
93
|
+
# @return [Sqreen::Deliveries::Simple]
|
90
94
|
attr_reader :deliverer
|
95
|
+
# @return [Sqreen::Session]
|
91
96
|
attr_reader :session
|
92
97
|
attr_reader :instrumenter
|
93
98
|
attr_accessor :running
|
@@ -97,8 +102,8 @@ module Sqreen
|
|
97
102
|
# we may want to do that in a thread in order to prevent delaying app
|
98
103
|
# startup
|
99
104
|
# set_at_exit do not place a global at_exit (used for testing)
|
105
|
+
# @param [Sqreen::Frameworks::GenericFramework] framework
|
100
106
|
def initialize(configuration, framework, set_at_exit = true, session_class = Sqreen::Session)
|
101
|
-
Sqreen.update_queue(CappedQueue.new(MAX_QUEUE_LENGTH))
|
102
107
|
@logged_out_tried = false
|
103
108
|
@configuration = configuration
|
104
109
|
@framework = framework
|
@@ -108,15 +113,25 @@ module Sqreen
|
|
108
113
|
@next_metrics = []
|
109
114
|
@running = true
|
110
115
|
|
116
|
+
@proxy_url = @configuration.get(:proxy_url)
|
117
|
+
chosen_endpoints = determine_endpoints
|
118
|
+
|
111
119
|
@token = @configuration.get(:token)
|
112
120
|
@app_name = @configuration.get(:app_name)
|
113
|
-
@url =
|
121
|
+
@url = chosen_endpoints.control.url
|
122
|
+
@cert_store = chosen_endpoints.control.ca_store
|
123
|
+
|
114
124
|
Sqreen.update_whitelisted_paths([])
|
115
125
|
Sqreen.update_whitelisted_ips({})
|
116
126
|
Sqreen.update_performance_budget(nil)
|
117
|
-
raise(Sqreen::Exception, 'no url found') unless @url
|
118
127
|
raise(Sqreen::TokenNotFoundException, 'no token found') unless @token
|
119
128
|
|
129
|
+
Sqreen::Kit::Configuration.logger = Sqreen.log
|
130
|
+
Sqreen::Kit::Configuration.ingestion_url = chosen_endpoints.ingestion.url
|
131
|
+
Sqreen::Kit::Configuration.certificate_store = chosen_endpoints.ingestion.ca_store
|
132
|
+
Sqreen::Kit::Configuration.proxy_url = @proxy_url
|
133
|
+
Sqreen::Kit::Configuration.default_source = "sqreen:agent:ruby:#{Sqreen::VERSION}"
|
134
|
+
|
120
135
|
register_exit_cb if set_at_exit
|
121
136
|
|
122
137
|
self.metrics_engine = MetricsStore.new
|
@@ -126,13 +141,19 @@ module Sqreen
|
|
126
141
|
end
|
127
142
|
|
128
143
|
if @configuration.get(:weave) || needs_weave.call
|
129
|
-
|
144
|
+
# XXX: don't get updated
|
145
|
+
opts = {
|
146
|
+
perf_req_metrics_max_reqs: Sqreen.features['perf_req_metrics_max_reqs'],
|
147
|
+
perf_req_metrics_period: Sqreen.features['perf_req_metrics_period'],
|
148
|
+
}
|
149
|
+
@instrumenter = Sqreen::Weave::Legacy::Instrumentation.new(metrics_engine, opts)
|
130
150
|
else
|
131
151
|
@instrumenter = Sqreen::Legacy::Instrumentation.new(metrics_engine)
|
132
152
|
end
|
133
153
|
|
134
154
|
Sqreen.log.debug "Using token #{@token}"
|
135
155
|
response = create_session(session_class)
|
156
|
+
post_endpoint_testing_msgs(chosen_endpoints)
|
136
157
|
wanted_features = response.fetch('features', {})
|
137
158
|
conf_initial_features = configuration.get(:initial_features)
|
138
159
|
unless conf_initial_features.nil?
|
@@ -142,15 +163,21 @@ module Sqreen
|
|
142
163
|
Sqreen.log.debug do
|
143
164
|
"Override initial features with #{conf_features.inspect}"
|
144
165
|
end
|
145
|
-
wanted_features = conf_features
|
166
|
+
wanted_features = wanted_features.merge(conf_features)
|
146
167
|
rescue
|
147
168
|
Sqreen.log.warn do
|
148
|
-
"NOT using invalid
|
169
|
+
"NOT using invalid initial features #{conf_initial_features}"
|
149
170
|
end
|
150
171
|
end
|
151
172
|
end
|
152
173
|
self.features = wanted_features
|
153
174
|
|
175
|
+
@ecosystem_integration = EcosystemIntegration.new(framework,
|
176
|
+
Sqreen.queue,
|
177
|
+
create_binning_metric_proc)
|
178
|
+
framework.req_start_cb = @ecosystem_integration.method(:request_start)
|
179
|
+
framework.req_end_cb = @ecosystem_integration.method(:request_end)
|
180
|
+
|
154
181
|
# Ensure a deliverer is there unless features have set it first
|
155
182
|
self.deliverer ||= Deliveries::Simple.new(session)
|
156
183
|
context_infos = {}
|
@@ -161,7 +188,7 @@ module Sqreen
|
|
161
188
|
end
|
162
189
|
|
163
190
|
def create_session(session_class)
|
164
|
-
@session = session_class.new(@url, @token, @app_name)
|
191
|
+
@session = session_class.new(@url, @cert_store, @token, @app_name, @proxy_url)
|
165
192
|
session.login(@framework)
|
166
193
|
end
|
167
194
|
|
@@ -170,8 +197,18 @@ module Sqreen
|
|
170
197
|
@deliverer = new_deliverer
|
171
198
|
end
|
172
199
|
|
173
|
-
def batch_events(batch_size, max_staleness = nil)
|
200
|
+
def batch_events(batch_size, max_staleness = nil, use_signals = false)
|
174
201
|
size = batch_size.to_i
|
202
|
+
|
203
|
+
if size <= 1 && use_signals
|
204
|
+
Sqreen.log.warn do
|
205
|
+
"Using signals with no delivery batching is unsupported. " \
|
206
|
+
"Using instead batching with batch size = 30, max_staleness = 60"
|
207
|
+
end
|
208
|
+
size = 30
|
209
|
+
max_staleness = 60
|
210
|
+
end
|
211
|
+
|
175
212
|
self.deliverer = if size < 1
|
176
213
|
Deliveries::Simple.new(session)
|
177
214
|
else
|
@@ -241,6 +278,10 @@ module Sqreen
|
|
241
278
|
rulespack_id, rules = load_rules(context_infos)
|
242
279
|
@framework.instrument_when_ready!(instrumenter, rules)
|
243
280
|
Sqreen.log.info 'Instrumentation set up'
|
281
|
+
|
282
|
+
# XXX: ecosystem instrumentation should likely be deferred
|
283
|
+
# the same way the rest might be
|
284
|
+
@ecosystem_integration.init unless Sqreen.features['disable_ecosystem']
|
244
285
|
rulespack_id.to_s
|
245
286
|
end
|
246
287
|
|
@@ -301,19 +342,37 @@ module Sqreen
|
|
301
342
|
def do_heartbeat
|
302
343
|
@last_heartbeat_request = Time.now
|
303
344
|
@next_metrics.concat(metrics_engine.publish(false)) if metrics_engine
|
304
|
-
|
345
|
+
metrics_in_hb = use_signals? ? nil : next_metrics
|
346
|
+
|
347
|
+
res = session.heartbeat(next_command_results, metrics_in_hb)
|
305
348
|
next_command_results.clear
|
349
|
+
|
350
|
+
deliver_metrics_as_event if use_signals?
|
306
351
|
next_metrics.clear
|
352
|
+
|
307
353
|
process_commands(res['commands'])
|
308
354
|
end
|
309
355
|
|
356
|
+
def deliver_metrics_as_event
|
357
|
+
# this is disastrous withe simple delivery strategy,
|
358
|
+
# as each aggregated metric would trigger an http request
|
359
|
+
# Sending of metrics is therefore not supported with simple delivery strategy
|
360
|
+
# TODO: Confirm that only batch is used in production
|
361
|
+
next_metrics.each { |x| deliverer.post_event(x) }
|
362
|
+
end
|
363
|
+
|
310
364
|
def features(_context_infos = {})
|
311
365
|
Sqreen.features
|
312
366
|
end
|
313
367
|
|
368
|
+
def use_signals?
|
369
|
+
features.fetch('use_signals', DEFAULT_USE_SIGNALS)
|
370
|
+
end
|
371
|
+
|
314
372
|
def features=(features)
|
315
373
|
Sqreen.update_features(features)
|
316
374
|
session.request_compression = features['request_compression'] if session
|
375
|
+
session.use_signals = use_signals?
|
317
376
|
self.performance_metrics_period = features['performance_metrics_period']
|
318
377
|
|
319
378
|
unless @configuration.get(:weave)
|
@@ -331,7 +390,7 @@ module Sqreen
|
|
331
390
|
hd = features['heartbeat_delay'].to_i
|
332
391
|
self.heartbeat_delay = hd if hd > 0
|
333
392
|
return if features['batch_size'].nil?
|
334
|
-
batch_events(features['batch_size'], features['max_staleness'])
|
393
|
+
batch_events(features['batch_size'], features['max_staleness'], use_signals?)
|
335
394
|
end
|
336
395
|
|
337
396
|
def change_whitelisted_paths(paths, _context_infos = {})
|
@@ -342,11 +401,28 @@ module Sqreen
|
|
342
401
|
|
343
402
|
def change_performance_budget(budget, _context_infos = {})
|
344
403
|
return false unless budget.nil? || budget.to_f > 0
|
345
|
-
|
346
|
-
|
404
|
+
|
405
|
+
if @configuration.get(:weave)
|
406
|
+
prev = Sqreen::Weave::Budget.current
|
407
|
+
prev = prev.to_h if prev
|
408
|
+
|
409
|
+
budget_s = budget.to_f / 1000.0 if budget
|
410
|
+
Sqreen::Weave::Budget.update(threshold: budget_s)
|
411
|
+
else
|
412
|
+
prev = Sqreen.performance_budget
|
413
|
+
Sqreen.update_performance_budget(budget)
|
414
|
+
end
|
415
|
+
|
347
416
|
{ :was => prev }
|
348
417
|
end
|
349
418
|
|
419
|
+
# @param [String] tracing_id_prefix
|
420
|
+
# @param [Array<Hash{String=>Object}>] sampling_config
|
421
|
+
def tracing_enable(tracing_id_prefix, sampling_config, _context_infos = {})
|
422
|
+
@ecosystem_integration.handle_tracing_command(tracing_id_prefix, sampling_config)
|
423
|
+
{ status: true }
|
424
|
+
end
|
425
|
+
|
350
426
|
def upload_bundle(_context_infos = {})
|
351
427
|
t = Time.now
|
352
428
|
session.post_bundle(RuntimeInfos.dependencies_signature, RuntimeInfos.dependencies)
|
@@ -433,6 +509,15 @@ module Sqreen
|
|
433
509
|
logout
|
434
510
|
end
|
435
511
|
|
512
|
+
def restart(_context_infos = {})
|
513
|
+
shutdown
|
514
|
+
heartbeat_delay = @heartbeat_delay
|
515
|
+
Thread.new do
|
516
|
+
sleep(2 * heartbeat_delay)
|
517
|
+
Sqreen::Worker.start(Sqreen.framework)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
436
521
|
def logout(retrying = true)
|
437
522
|
return unless session
|
438
523
|
Sqreen.log.debug("Logging out")
|
@@ -470,6 +555,43 @@ module Sqreen
|
|
470
555
|
|
471
556
|
private
|
472
557
|
|
558
|
+
def create_binning_metric_proc
|
559
|
+
lambda do |metric_name|
|
560
|
+
return if @metrics_engine.metric?(metric_name)
|
561
|
+
metrics_engine.create_metric(
|
562
|
+
'name' => metric_name,
|
563
|
+
'kind' => 'Binning',
|
564
|
+
'period' => Sqreen.features['performance_metrics_period'] || 60,
|
565
|
+
'options' => {
|
566
|
+
'base' => Sqreen.features['perf_base'] || PerformanceNotifications::BinnedMetrics::DEFAULT_PERF_BASE,
|
567
|
+
'factor' => Sqreen.features['perf_unit'] || PerformanceNotifications::BinnedMetrics::DEFAULT_PERF_UNIT,
|
568
|
+
},
|
569
|
+
)
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
def post_endpoint_testing_msgs(chosen_endpoints)
|
574
|
+
chosen_endpoints.messages.each do |msg|
|
575
|
+
session.post_agent_message(@framework, msg)
|
576
|
+
end
|
577
|
+
rescue => e
|
578
|
+
Sqreen.log.warn "Error submitting agent message: #{e}"
|
579
|
+
RemoteException.record(e)
|
580
|
+
end
|
581
|
+
|
582
|
+
def determine_endpoints
|
583
|
+
# there's no sniffing going on; just a misnamed config setting
|
584
|
+
if @configuration.get(:no_sniff_domains)
|
585
|
+
# reproduces behaviour before endpoint testing was introduced
|
586
|
+
EndpointTesting.no_test_endpoints(@configuration.get(:url),
|
587
|
+
@configuration.get(:ingestion_url))
|
588
|
+
else
|
589
|
+
EndpointTesting.test_endpoints(@proxy_url,
|
590
|
+
@configuration.get(:url),
|
591
|
+
@configuration.get(:ingestion_url))
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
473
595
|
def load_actions(hashes)
|
474
596
|
unsupported = Set.new
|
475
597
|
|