sqreen 1.20.0-java → 1.21.1-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 +37 -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/attack_detected.html +1 -2
- data/lib/sqreen/ca.crt +24 -0
- data/lib/sqreen/condition_evaluator.rb +8 -2
- data/lib/sqreen/configuration.rb +5 -3
- data/lib/sqreen/deferred_logger.rb +50 -14
- data/lib/sqreen/deliveries/batch.rb +8 -1
- data/lib/sqreen/dependency/detector.rb +11 -3
- data/lib/sqreen/dependency/new_relic.rb +10 -1
- data/lib/sqreen/deprecation.rb +38 -0
- data/lib/sqreen/ecosystem.rb +123 -0
- data/lib/sqreen/ecosystem/databases/database_connection_data.rb +23 -0
- data/lib/sqreen/ecosystem/databases/mongo.rb +39 -0
- data/lib/sqreen/ecosystem/databases/mysql.rb +54 -0
- data/lib/sqreen/ecosystem/databases/postgres.rb +51 -0
- data/lib/sqreen/ecosystem/databases/redis.rb +36 -0
- data/lib/sqreen/ecosystem/dispatch_table.rb +43 -0
- data/lib/sqreen/ecosystem/exception_reporting.rb +28 -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/messaging/bunny.rb +61 -0
- data/lib/sqreen/ecosystem/messaging/kafka.rb +70 -0
- data/lib/sqreen/ecosystem/messaging/kinesis.rb +66 -0
- data/lib/sqreen/ecosystem/messaging/sqs.rb +68 -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 +57 -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/consumer_data.rb +13 -0
- data/lib/sqreen/ecosystem/module_api/tracing/messaging_data.rb +35 -0
- data/lib/sqreen/ecosystem/module_api/tracing/producer_data.rb +13 -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 +48 -0
- data/lib/sqreen/ecosystem/tracing/modules/client.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/modules/consumer.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/modules/determine_ip.rb +28 -0
- data/lib/sqreen/ecosystem/tracing/modules/producer.rb +35 -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_consumer.rb +56 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_producer.rb +56 -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 +81 -0
- data/lib/sqreen/ecosystem_integration/around_callbacks.rb +89 -0
- data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +38 -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/events/request_record.rb +0 -1
- data/lib/sqreen/frameworks/generic.rb +24 -1
- data/lib/sqreen/frameworks/rails.rb +0 -7
- data/lib/sqreen/frameworks/request_recorder.rb +2 -0
- data/lib/sqreen/graft/call.rb +85 -18
- data/lib/sqreen/graft/callback.rb +1 -1
- data/lib/sqreen/graft/hook.rb +192 -88
- data/lib/sqreen/graft/hook_point.rb +18 -11
- data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +2 -0
- data/lib/sqreen/legacy/instrumentation.rb +22 -10
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +9 -2
- 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_store.rb +11 -0
- data/lib/sqreen/null_logger.rb +22 -0
- data/lib/sqreen/remote_command.rb +4 -0
- data/lib/sqreen/rules.rb +8 -4
- data/lib/sqreen/rules/blacklist_ips_cb.rb +2 -2
- data/lib/sqreen/rules/custom_error_cb.rb +3 -3
- data/lib/sqreen/rules/rule_cb.rb +2 -0
- data/lib/sqreen/rules/waf_cb.rb +3 -3
- data/lib/sqreen/runner.rb +83 -14
- data/lib/sqreen/session.rb +19 -11
- data/lib/sqreen/signals/conversions.rb +6 -1
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/budget.rb +46 -0
- data/lib/sqreen/weave/legacy/instrumentation.rb +194 -103
- data/lib/sqreen/worker.rb +6 -2
- metadata +58 -6
- data/lib/sqreen/encoding_sanitizer.rb +0 -27
|
@@ -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.open(File.join(File.dirname(__FILE__), '../attack_detected.html'), 'rb', &:read)
|
|
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'
|
|
@@ -109,6 +110,7 @@ module Sqreen
|
|
|
109
110
|
)
|
|
110
111
|
true
|
|
111
112
|
end
|
|
113
|
+
Sqreen::Deprecation.deprecate(instance_method(:overtime!))
|
|
112
114
|
end
|
|
113
115
|
end
|
|
114
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)
|
data/lib/sqreen/runner.rb
CHANGED
|
@@ -11,19 +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'
|
|
26
29
|
require 'sqreen/kit/configuration'
|
|
30
|
+
require 'sqreen/ecosystem_integration'
|
|
27
31
|
|
|
28
32
|
module Sqreen
|
|
29
33
|
@features = {}
|
|
@@ -50,10 +54,6 @@ module Sqreen
|
|
|
50
54
|
@queue ||= CappedQueue.new(MAX_QUEUE_LENGTH)
|
|
51
55
|
end
|
|
52
56
|
|
|
53
|
-
def update_queue(queue)
|
|
54
|
-
@queue = queue
|
|
55
|
-
end
|
|
56
|
-
|
|
57
57
|
def observations_queue
|
|
58
58
|
@observations_queue ||= CappedQueue.new(MAX_OBS_QUEUE_LENGTH)
|
|
59
59
|
end
|
|
@@ -102,8 +102,8 @@ module Sqreen
|
|
|
102
102
|
# we may want to do that in a thread in order to prevent delaying app
|
|
103
103
|
# startup
|
|
104
104
|
# set_at_exit do not place a global at_exit (used for testing)
|
|
105
|
+
# @param [Sqreen::Frameworks::GenericFramework] framework
|
|
105
106
|
def initialize(configuration, framework, set_at_exit = true, session_class = Sqreen::Session)
|
|
106
|
-
Sqreen.update_queue(CappedQueue.new(MAX_QUEUE_LENGTH))
|
|
107
107
|
@logged_out_tried = false
|
|
108
108
|
@configuration = configuration
|
|
109
109
|
@framework = framework
|
|
@@ -113,19 +113,24 @@ module Sqreen
|
|
|
113
113
|
@next_metrics = []
|
|
114
114
|
@running = true
|
|
115
115
|
|
|
116
|
+
@proxy_url = @configuration.get(:proxy_url)
|
|
117
|
+
chosen_endpoints = determine_endpoints
|
|
118
|
+
|
|
116
119
|
@token = @configuration.get(:token)
|
|
117
120
|
@app_name = @configuration.get(:app_name)
|
|
118
|
-
@url =
|
|
119
|
-
@
|
|
121
|
+
@url = chosen_endpoints.control.url
|
|
122
|
+
@cert_store = chosen_endpoints.control.ca_store
|
|
123
|
+
|
|
120
124
|
Sqreen.update_whitelisted_paths([])
|
|
121
125
|
Sqreen.update_whitelisted_ips({})
|
|
122
126
|
Sqreen.update_performance_budget(nil)
|
|
123
|
-
raise(Sqreen::Exception, 'no url found') unless @url
|
|
124
127
|
raise(Sqreen::TokenNotFoundException, 'no token found') unless @token
|
|
125
128
|
|
|
126
129
|
Sqreen::Kit::Configuration.logger = Sqreen.log
|
|
127
|
-
Sqreen::Kit::Configuration.ingestion_url =
|
|
128
|
-
Sqreen::Kit::Configuration.
|
|
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}"
|
|
129
134
|
|
|
130
135
|
register_exit_cb if set_at_exit
|
|
131
136
|
|
|
@@ -143,6 +148,7 @@ module Sqreen
|
|
|
143
148
|
|
|
144
149
|
Sqreen.log.debug "Using token #{@token}"
|
|
145
150
|
response = create_session(session_class)
|
|
151
|
+
post_endpoint_testing_msgs(chosen_endpoints)
|
|
146
152
|
wanted_features = response.fetch('features', {})
|
|
147
153
|
conf_initial_features = configuration.get(:initial_features)
|
|
148
154
|
unless conf_initial_features.nil?
|
|
@@ -155,12 +161,16 @@ module Sqreen
|
|
|
155
161
|
wanted_features = wanted_features.merge(conf_features)
|
|
156
162
|
rescue
|
|
157
163
|
Sqreen.log.warn do
|
|
158
|
-
"NOT using invalid
|
|
164
|
+
"NOT using invalid initial features #{conf_initial_features}"
|
|
159
165
|
end
|
|
160
166
|
end
|
|
161
167
|
end
|
|
162
168
|
self.features = wanted_features
|
|
163
169
|
|
|
170
|
+
@ecosystem_integration = EcosystemIntegration.new(framework, Sqreen.queue)
|
|
171
|
+
framework.req_start_cb = @ecosystem_integration.method(:request_start)
|
|
172
|
+
framework.req_end_cb = @ecosystem_integration.method(:request_end)
|
|
173
|
+
|
|
164
174
|
# Ensure a deliverer is there unless features have set it first
|
|
165
175
|
self.deliverer ||= Deliveries::Simple.new(session)
|
|
166
176
|
context_infos = {}
|
|
@@ -171,7 +181,7 @@ module Sqreen
|
|
|
171
181
|
end
|
|
172
182
|
|
|
173
183
|
def create_session(session_class)
|
|
174
|
-
@session = session_class.new(@url, @token, @app_name, @proxy_url)
|
|
184
|
+
@session = session_class.new(@url, @cert_store, @token, @app_name, @proxy_url)
|
|
175
185
|
session.login(@framework)
|
|
176
186
|
end
|
|
177
187
|
|
|
@@ -261,6 +271,10 @@ module Sqreen
|
|
|
261
271
|
rulespack_id, rules = load_rules(context_infos)
|
|
262
272
|
@framework.instrument_when_ready!(instrumenter, rules)
|
|
263
273
|
Sqreen.log.info 'Instrumentation set up'
|
|
274
|
+
|
|
275
|
+
# XXX: ecosystem instrumentation should likely be deferred
|
|
276
|
+
# the same way the rest might be
|
|
277
|
+
@ecosystem_integration.init
|
|
264
278
|
rulespack_id.to_s
|
|
265
279
|
end
|
|
266
280
|
|
|
@@ -380,11 +394,35 @@ module Sqreen
|
|
|
380
394
|
|
|
381
395
|
def change_performance_budget(budget, _context_infos = {})
|
|
382
396
|
return false unless budget.nil? || budget.to_f > 0
|
|
383
|
-
|
|
384
|
-
|
|
397
|
+
|
|
398
|
+
if @configuration.get(:weave)
|
|
399
|
+
prev = Sqreen::Weave::Budget.current
|
|
400
|
+
prev = prev.to_h if prev
|
|
401
|
+
|
|
402
|
+
budget_s = budget.to_f / 1000 if budget
|
|
403
|
+
|
|
404
|
+
feature = features['performance_budget']
|
|
405
|
+
if feature
|
|
406
|
+
budget_s = feature['threshold'] if feature.key?('threshold')
|
|
407
|
+
ratio = feature['ratio'] if feature.key?('ratio')
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
Sqreen::Weave::Budget.update(threshold: budget_s, ratio: ratio)
|
|
411
|
+
else
|
|
412
|
+
prev = Sqreen.performance_budget
|
|
413
|
+
Sqreen.update_performance_budget(budget)
|
|
414
|
+
end
|
|
415
|
+
|
|
385
416
|
{ :was => prev }
|
|
386
417
|
end
|
|
387
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
|
+
|
|
388
426
|
def upload_bundle(_context_infos = {})
|
|
389
427
|
t = Time.now
|
|
390
428
|
session.post_bundle(RuntimeInfos.dependencies_signature, RuntimeInfos.dependencies)
|
|
@@ -471,6 +509,15 @@ module Sqreen
|
|
|
471
509
|
logout
|
|
472
510
|
end
|
|
473
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
|
+
|
|
474
521
|
def logout(retrying = true)
|
|
475
522
|
return unless session
|
|
476
523
|
Sqreen.log.debug("Logging out")
|
|
@@ -508,6 +555,28 @@ module Sqreen
|
|
|
508
555
|
|
|
509
556
|
private
|
|
510
557
|
|
|
558
|
+
def post_endpoint_testing_msgs(chosen_endpoints)
|
|
559
|
+
chosen_endpoints.messages.each do |msg|
|
|
560
|
+
session.post_agent_message(@framework, msg)
|
|
561
|
+
end
|
|
562
|
+
rescue => e
|
|
563
|
+
Sqreen.log.warn "Error submitting agent message: #{e}"
|
|
564
|
+
RemoteException.record(e)
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
def determine_endpoints
|
|
568
|
+
# there's no sniffing going on; just a misnamed config setting
|
|
569
|
+
if @configuration.get(:no_sniff_domains)
|
|
570
|
+
# reproduces behaviour before endpoint testing was introduced
|
|
571
|
+
EndpointTesting.no_test_endpoints(@configuration.get(:url),
|
|
572
|
+
@configuration.get(:ingestion_url))
|
|
573
|
+
else
|
|
574
|
+
EndpointTesting.test_endpoints(@proxy_url,
|
|
575
|
+
@configuration.get(:url),
|
|
576
|
+
@configuration.get(:ingestion_url))
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
511
580
|
def load_actions(hashes)
|
|
512
581
|
unsupported = Set.new
|
|
513
582
|
|
data/lib/sqreen/session.rb
CHANGED
|
@@ -50,7 +50,7 @@ module Sqreen
|
|
|
50
50
|
|
|
51
51
|
attr_accessor :request_compression
|
|
52
52
|
|
|
53
|
-
def initialize(server_url, token, app_name = nil, proxy_url = nil)
|
|
53
|
+
def initialize(server_url, cert_store, token, app_name = nil, proxy_url = nil)
|
|
54
54
|
@token = token
|
|
55
55
|
@app_name = app_name
|
|
56
56
|
@session_id = nil
|
|
@@ -73,12 +73,7 @@ module Sqreen
|
|
|
73
73
|
@http = Net::HTTP.new(uri.host, uri.port, *proxy_params)
|
|
74
74
|
@http.use_ssl = use_ssl
|
|
75
75
|
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE if ENV['SQREEN_SSL_NO_VERIFY'] # for testing
|
|
76
|
-
if use_ssl
|
|
77
|
-
cert_file = File.join(File.dirname(__FILE__), 'ca.crt')
|
|
78
|
-
cert_store = OpenSSL::X509::Store.new
|
|
79
|
-
cert_store.add_file cert_file
|
|
80
|
-
@http.cert_store = cert_store
|
|
81
|
-
end
|
|
76
|
+
@http.cert_store = cert_store if use_ssl
|
|
82
77
|
self.use_signals = false
|
|
83
78
|
end
|
|
84
79
|
|
|
@@ -240,10 +235,7 @@ module Sqreen
|
|
|
240
235
|
end
|
|
241
236
|
|
|
242
237
|
def login(framework)
|
|
243
|
-
headers =
|
|
244
|
-
'x-api-key' => @token,
|
|
245
|
-
'x-app-name' => @app_name || framework.application_name,
|
|
246
|
-
}.reject { |k, v| v == nil }
|
|
238
|
+
headers = prelogin_auth_headers(framework)
|
|
247
239
|
|
|
248
240
|
Sqreen.log.warn "Using app name: #{headers['x-app-name']}"
|
|
249
241
|
|
|
@@ -257,8 +249,10 @@ module Sqreen
|
|
|
257
249
|
end
|
|
258
250
|
Sqreen.log.info 'Login success.'
|
|
259
251
|
@session_id = res['session_id']
|
|
252
|
+
|
|
260
253
|
Kit::Configuration.session_key = @session_id
|
|
261
254
|
Kit.reset
|
|
255
|
+
|
|
262
256
|
Sqreen.log.debug { "received session_id #{@session_id}" }
|
|
263
257
|
Sqreen.logged_in = true
|
|
264
258
|
res
|
|
@@ -312,6 +306,11 @@ module Sqreen
|
|
|
312
306
|
@evt_sub_strategy.post_batch(events)
|
|
313
307
|
end
|
|
314
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)
|
|
312
|
+
end
|
|
313
|
+
|
|
315
314
|
# Perform agent logout
|
|
316
315
|
# @param retrying [Boolean] whether to try again on error
|
|
317
316
|
def logout(retrying = true)
|
|
@@ -325,5 +324,14 @@ module Sqreen
|
|
|
325
324
|
Sqreen.logged_in = false
|
|
326
325
|
disconnect
|
|
327
326
|
end
|
|
327
|
+
|
|
328
|
+
private
|
|
329
|
+
|
|
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 }
|
|
335
|
+
end
|
|
328
336
|
end
|
|
329
337
|
end
|
|
@@ -118,6 +118,7 @@ module Sqreen
|
|
|
118
118
|
signals += req_rec.processed_sdk_calls
|
|
119
119
|
.select { |h| h[:name] == :track }
|
|
120
120
|
.map { |h| convert_track(h) }
|
|
121
|
+
signals += (observed[:signals] || [])
|
|
121
122
|
|
|
122
123
|
trace = Kit::Signals::Specialized::HttpTrace.new(
|
|
123
124
|
actor: Kit::Signals::Actor.new(
|
|
@@ -137,7 +138,7 @@ module Sqreen
|
|
|
137
138
|
trace
|
|
138
139
|
end
|
|
139
140
|
|
|
140
|
-
# @
|
|
141
|
+
# @return [Array<Sqreen::Kit::Signals::Signal|Sqreen::Kit::Signals::Trace>]
|
|
141
142
|
def convert_batch(batch)
|
|
142
143
|
batch.map do |evt|
|
|
143
144
|
case evt
|
|
@@ -147,6 +148,10 @@ module Sqreen
|
|
|
147
148
|
convert_metric_sample(evt)
|
|
148
149
|
when RequestRecord
|
|
149
150
|
convert_req_record(evt)
|
|
151
|
+
when Sqreen::Kit::Signals::Signal
|
|
152
|
+
evt
|
|
153
|
+
when Sqreen::Kit::Signals::Trace
|
|
154
|
+
evt
|
|
150
155
|
else
|
|
151
156
|
raise NotImplementedError, "Unknown type of event in batch: #{evt}"
|
|
152
157
|
end
|
data/lib/sqreen/version.rb
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
require 'sqreen/log/loggable'
|
|
7
|
+
require 'sqreen/weave'
|
|
8
|
+
|
|
9
|
+
class Sqreen::Weave::Budget
|
|
10
|
+
include Sqreen::Log::Loggable
|
|
11
|
+
|
|
12
|
+
def initialize(threshold, ratio = nil)
|
|
13
|
+
@threshold = threshold
|
|
14
|
+
@ratio = ratio
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def static?
|
|
18
|
+
threshold && !ratio
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def dynamic?
|
|
22
|
+
threshold && ratio
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
attr_reader :threshold
|
|
26
|
+
attr_reader :ratio
|
|
27
|
+
|
|
28
|
+
def to_h
|
|
29
|
+
{ threshold: threshold, ratio: ratio }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class << self
|
|
33
|
+
attr_reader :current
|
|
34
|
+
|
|
35
|
+
def update(opts = nil)
|
|
36
|
+
Sqreen::Weave.logger.info("budget update:#{opts.inspect}")
|
|
37
|
+
|
|
38
|
+
return @current = nil if opts.nil? || opts.empty?
|
|
39
|
+
|
|
40
|
+
threshold = opts[:threshold]
|
|
41
|
+
ratio = opts[:ratio]
|
|
42
|
+
|
|
43
|
+
@current = new(threshold, ratio)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
5
|
|
|
6
6
|
require 'sqreen/weave/legacy'
|
|
7
|
+
require 'sqreen/weave/budget'
|
|
8
|
+
require 'sqreen/graft/hook'
|
|
7
9
|
require 'sqreen/graft/hook_point'
|
|
8
10
|
require 'sqreen/call_countable'
|
|
9
11
|
require 'sqreen/rules'
|
|
10
12
|
require 'sqreen/rules/record_request_context'
|
|
13
|
+
require 'sqreen/sqreen_signed_verifier'
|
|
11
14
|
|
|
12
15
|
class Sqreen::Weave::Legacy::Instrumentation
|
|
13
16
|
attr_accessor :metrics_engine
|
|
@@ -60,6 +63,27 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
60
63
|
'options' => opts[:perf_metric_percent] || { 'base' => 1.3, 'factor' => 1.0 },
|
|
61
64
|
)
|
|
62
65
|
|
|
66
|
+
metrics_engine.create_metric(
|
|
67
|
+
'name' => 'req.sq.hook.overhead',
|
|
68
|
+
'period' => 60,
|
|
69
|
+
'kind' => 'Binning',
|
|
70
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
metrics_engine.create_metric(
|
|
74
|
+
'name' => 'sq.hook.overhead',
|
|
75
|
+
'period' => 60,
|
|
76
|
+
'kind' => 'Binning',
|
|
77
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
metrics_engine.create_metric(
|
|
81
|
+
'name' => 'sq.shrinkwrap',
|
|
82
|
+
'period' => 60,
|
|
83
|
+
'kind' => 'Binning',
|
|
84
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
85
|
+
)
|
|
86
|
+
|
|
63
87
|
Sqreen.thread_cpu_time? && metrics_engine.create_metric(
|
|
64
88
|
'name' => 'sq_thread_cpu_pct',
|
|
65
89
|
'period' => opts[:period] || 60,
|
|
@@ -84,6 +108,15 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
84
108
|
|
|
85
109
|
### set up rule signature verifier
|
|
86
110
|
verifier = nil
|
|
111
|
+
if Sqreen.features['rules_signature'] &&
|
|
112
|
+
Sqreen.config_get(:rules_verify_signature) == true &&
|
|
113
|
+
!defined?(::JRUBY_VERSION)
|
|
114
|
+
verifier = Sqreen::SqreenSignedVerifier.new
|
|
115
|
+
Sqreen::Weave.logger.debug('Rules signature enabled')
|
|
116
|
+
else
|
|
117
|
+
Sqreen::Weave.logger.debug('Rules signature disabled')
|
|
118
|
+
end
|
|
119
|
+
|
|
87
120
|
### force clean instrumentation callback list
|
|
88
121
|
@hooks = []
|
|
89
122
|
### for each rule description
|
|
@@ -94,6 +127,25 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
94
127
|
next unless rule_callback
|
|
95
128
|
### attach framework to callback
|
|
96
129
|
rule_callback.framework = framework
|
|
130
|
+
## create metric
|
|
131
|
+
Sqreen::Weave.logger.debug { "Adding rule metric: #{rule_callback}" }
|
|
132
|
+
[:pre, :post, :failing].each do |whence|
|
|
133
|
+
next unless rule_callback.send(:"#{whence}?")
|
|
134
|
+
metric_name = "sq.#{rule['name']}.#{whence}"
|
|
135
|
+
metrics_engine.create_metric(
|
|
136
|
+
'name' => metric_name,
|
|
137
|
+
'period' => 60,
|
|
138
|
+
'kind' => 'Binning',
|
|
139
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
140
|
+
)
|
|
141
|
+
metric_name = "req.sq.#{rule['name']}.#{whence}"
|
|
142
|
+
metrics_engine.create_metric(
|
|
143
|
+
'name' => metric_name,
|
|
144
|
+
'period' => 60,
|
|
145
|
+
'kind' => 'Binning',
|
|
146
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
147
|
+
)
|
|
148
|
+
end
|
|
97
149
|
### install callback, observing priority
|
|
98
150
|
Sqreen::Weave.logger.debug { "Adding rule callback: #{rule_callback}" }
|
|
99
151
|
@hooks << add_callback("weave,rule=#{rule['name']}", rule_callback, strategy)
|
|
@@ -107,30 +159,43 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
107
159
|
end
|
|
108
160
|
|
|
109
161
|
metrics_engine = self.metrics_engine
|
|
162
|
+
|
|
110
163
|
request_hook = Sqreen::Graft::Hook['Sqreen::ShrinkWrap#call', strategy]
|
|
111
164
|
@hooks << request_hook
|
|
112
165
|
request_hook.add do
|
|
113
166
|
before('wave,meta,request', rank: -100000, mandatory: true) do |_call|
|
|
114
167
|
next unless Sqreen.instrumentation_ready
|
|
115
168
|
|
|
116
|
-
|
|
117
|
-
|
|
169
|
+
# shrinkwrap_timer = Sqreen::Graft::Timer.new('weave,shrinkwrap')
|
|
170
|
+
# shrinkwrap_timer.start
|
|
171
|
+
|
|
172
|
+
request_timer = Sqreen::Graft::Timer.new("request")
|
|
173
|
+
request_timer.start
|
|
174
|
+
sqreen_timer = Sqreen::Graft::Timer.new("sqreen")
|
|
175
|
+
budget = Sqreen::Weave::Budget.current
|
|
176
|
+
request_budget_threshold = budget.threshold if budget
|
|
177
|
+
request_budget_ratio = budget.ratio if budget
|
|
178
|
+
request_budget_is_dynamic = !request_budget_ratio.nil?
|
|
179
|
+
request_budget = !request_budget_threshold.nil?
|
|
180
|
+
timed_level = (Sqreen.features['perf_level'] || 1).to_i
|
|
181
|
+
Sqreen::Weave.logger.debug { "request budget: #{budget.to_h} timed.level: #{timed_level}" } if Sqreen::Weave.logger.debug?
|
|
182
|
+
|
|
118
183
|
Thread.current[:sqreen_http_request] = {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
time_budget: Sqreen.performance_budget,
|
|
184
|
+
request_timer: request_timer,
|
|
185
|
+
sqreen_timer: sqreen_timer,
|
|
122
186
|
time_budget_expended: false,
|
|
123
|
-
|
|
187
|
+
time_budget_threshold: request_budget_threshold,
|
|
188
|
+
time_budget_dynamic: request_budget_is_dynamic,
|
|
189
|
+
time_budget_ratio: request_budget_ratio,
|
|
190
|
+
time_budget: request_budget,
|
|
124
191
|
timed_callbacks: [],
|
|
125
192
|
timed_hooks: [],
|
|
126
|
-
|
|
127
|
-
timed_hooks_after: [],
|
|
128
|
-
timed_hooks_raised: [],
|
|
129
|
-
timed_hooks_ensured: [],
|
|
193
|
+
timed_level: timed_level,
|
|
130
194
|
skipped_callbacks: [],
|
|
195
|
+
# timed_shrinkwrap: shrinkwrap_timer,
|
|
131
196
|
}
|
|
132
197
|
|
|
133
|
-
|
|
198
|
+
# shrinkwrap_timer.stop
|
|
134
199
|
end
|
|
135
200
|
|
|
136
201
|
ensured('weave,meta,request', rank: 100000, mandatory: true) do |_call|
|
|
@@ -138,105 +203,118 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
138
203
|
|
|
139
204
|
next if request.nil?
|
|
140
205
|
|
|
206
|
+
# shrinkwrap_timer = request[:timed_shrinkwrap]
|
|
207
|
+
# shrinkwrap_timer.start
|
|
208
|
+
|
|
141
209
|
Thread.current[:sqreen_http_request] = nil
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
request[:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
metrics_engine.
|
|
161
|
-
|
|
162
|
-
'period' => 60,
|
|
163
|
-
'kind' => 'Binning',
|
|
164
|
-
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
165
|
-
)
|
|
210
|
+
request_timer = request[:request_timer]
|
|
211
|
+
now = request_timer.stop
|
|
212
|
+
|
|
213
|
+
if request[:timed_level] >= 1
|
|
214
|
+
request[:timed_callbacks].each do |timer|
|
|
215
|
+
duration = timer.duration
|
|
216
|
+
|
|
217
|
+
timer.tag =~ /weave,rule=(.*)$/ && rule = $1
|
|
218
|
+
next unless rule
|
|
219
|
+
|
|
220
|
+
whence = case timer.tag
|
|
221
|
+
when /@before/ then 'pre'
|
|
222
|
+
when /@after/ then 'post'
|
|
223
|
+
when /@raised/ then 'failing'
|
|
224
|
+
end
|
|
225
|
+
next unless whence
|
|
226
|
+
|
|
227
|
+
metric_name = "sq.#{rule}.#{whence}"
|
|
228
|
+
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
|
229
|
+
# Sqreen.observations_queue.push([metric_name, nil, duration * 1000, utc_now])
|
|
166
230
|
end
|
|
167
|
-
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
|
168
|
-
end
|
|
169
231
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
'period' => 60,
|
|
176
|
-
'kind' => 'Binning',
|
|
177
|
-
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
178
|
-
)
|
|
179
|
-
end
|
|
180
|
-
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
|
181
|
-
|
|
182
|
-
metric_name = 'sq.hooks_post.post'
|
|
183
|
-
duration = request[:timed_hooks_after].sum(&:duration)
|
|
184
|
-
unless metrics_engine.metric?(metric_name)
|
|
185
|
-
metrics_engine.create_metric(
|
|
186
|
-
'name' => metric_name,
|
|
187
|
-
'period' => 60,
|
|
188
|
-
'kind' => 'Binning',
|
|
189
|
-
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
190
|
-
)
|
|
191
|
-
end
|
|
192
|
-
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
|
193
|
-
|
|
194
|
-
metric_name = 'sq.hooks_failing.failing'
|
|
195
|
-
duration = request[:timed_hooks_raised].sum(&:duration)
|
|
196
|
-
unless metrics_engine.metric?(metric_name)
|
|
197
|
-
metrics_engine.create_metric(
|
|
198
|
-
'name' => metric_name,
|
|
199
|
-
'period' => 60,
|
|
200
|
-
'kind' => 'Binning',
|
|
201
|
-
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
|
202
|
-
)
|
|
232
|
+
request[:timed_hooks].each do |timer|
|
|
233
|
+
duration = timer.duration
|
|
234
|
+
metrics_engine.update('sq.hook.overhead', now, nil, duration * 1000)
|
|
235
|
+
# Sqreen.observations_queue.push(['sq.hook.overhead', nil, duration * 1000, utc_now])
|
|
236
|
+
end
|
|
203
237
|
end
|
|
204
|
-
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
|
205
238
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
total =
|
|
210
|
-
Sqreen::Weave.logger.debug { "request
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
239
|
+
sqreen_timer = request[:sqreen_timer]
|
|
240
|
+
total = sqreen_timer.duration
|
|
241
|
+
Sqreen::Weave.logger.debug { "request sqreen_timer.total: #{'%.03fus' % (total * 1_000_000)}" } if Sqreen::Weave.logger.debug?
|
|
242
|
+
total = request_timer.duration
|
|
243
|
+
Sqreen::Weave.logger.debug { "request request_timer.total: #{'%.03fus' % (total * 1_000_000)}" } if Sqreen::Weave.logger.debug?
|
|
244
|
+
|
|
245
|
+
if request[:timed_level] >= 2
|
|
246
|
+
skipped = request[:skipped_callbacks].map(&:name)
|
|
247
|
+
Sqreen::Weave.logger.debug { "request callback.skipped.count: #{skipped.count}" } if Sqreen::Weave.logger.debug?
|
|
248
|
+
timings = request[:timed_callbacks].map(&:to_s)
|
|
249
|
+
total = request[:timed_callbacks].sum(&:duration)
|
|
250
|
+
Sqreen::Weave.logger.debug { "request callback.total: #{'%.03fus' % (total * 1_000_000)} callback.count: #{timings.count}" } if Sqreen::Weave.logger.debug?
|
|
251
|
+
timings = request[:timed_hooks].map(&:to_s)
|
|
252
|
+
total = request[:timed_hooks].sum(&:duration)
|
|
253
|
+
Sqreen::Weave.logger.debug { "request hook.total: #{'%.03fus' % (total * 1_000_000)} hook.count: #{timings.count}" } if Sqreen::Weave.logger.debug?
|
|
254
|
+
end
|
|
217
255
|
|
|
218
256
|
skipped = request[:skipped_callbacks].map(&:name)
|
|
219
257
|
skipped_rule_name = skipped.first && skipped.first =~ /weave,rule=(.*)$/ && $1
|
|
220
|
-
|
|
258
|
+
metrics_engine.update('request_overtime', now, skipped_rule_name, 1) if skipped_rule_name
|
|
259
|
+
# Sqreen.observations_queue.push(['request_overtime', skipped_rule_name, 1, utc_now]) if skipped_rule_name
|
|
221
260
|
|
|
222
|
-
sqreen_request_duration =
|
|
223
|
-
|
|
261
|
+
sqreen_request_duration = sqreen_timer.duration
|
|
262
|
+
metrics_engine.update('sq', now, nil, sqreen_request_duration * 1000)
|
|
263
|
+
# Sqreen.observations_queue.push(['sq', nil, sqreen_request_duration * 1000, utc_now])
|
|
224
264
|
|
|
225
|
-
request_duration =
|
|
226
|
-
|
|
265
|
+
request_duration = request_timer.duration
|
|
266
|
+
metrics_engine.update('req', now, nil, request_duration * 1000)
|
|
267
|
+
# Sqreen.observations_queue.push(['req', nil, request_duration * 1000, utc_now])
|
|
227
268
|
|
|
228
269
|
sqreen_request_ratio = (sqreen_request_duration * 100.0) / (request_duration - sqreen_request_duration)
|
|
229
|
-
|
|
270
|
+
metrics_engine.update('pct', now, nil, sqreen_request_ratio)
|
|
271
|
+
# Sqreen.observations_queue.push(['pct', nil, sqreen_request_ratio, utc_now])
|
|
272
|
+
Sqreen::Weave.logger.debug { "request sqreen_timer.ratio: #{'%.03f' % (sqreen_request_ratio / 100.0)}" } if Sqreen::Weave.logger.debug?
|
|
273
|
+
|
|
274
|
+
if request[:timed_level] >= 2
|
|
275
|
+
tallies = Hash.new(0.0)
|
|
276
|
+
request[:timed_callbacks].each do |timer|
|
|
277
|
+
duration = timer.duration
|
|
278
|
+
|
|
279
|
+
timer.tag =~ /weave,rule=(.*)$/ && rule = $1
|
|
280
|
+
next unless rule
|
|
281
|
+
|
|
282
|
+
whence = case timer.tag
|
|
283
|
+
when /@before/ then 'pre'
|
|
284
|
+
when /@after/ then 'post'
|
|
285
|
+
when /@raised/ then 'failing'
|
|
286
|
+
end
|
|
287
|
+
next unless whence
|
|
288
|
+
|
|
289
|
+
metric_name = "req.sq.#{rule}.#{whence}"
|
|
290
|
+
tallies[metric_name] += duration
|
|
291
|
+
end
|
|
292
|
+
tallies.each do |metric_name, duration|
|
|
293
|
+
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
|
294
|
+
# Sqreen.observations_queue.push([metric_name, nil, duration * 1000, utc_now])
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
duration = request[:timed_hooks].sum(&:duration)
|
|
298
|
+
metrics_engine.update('req.sq.hook.overhead', now, nil, duration * 1000)
|
|
299
|
+
# Sqreen.observations_queue.push(['req.sq.hook.overhead', nil, duration * 1000, utc_now])
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# shrinkwrap_timer.stop
|
|
303
|
+
|
|
304
|
+
# duration = shrinkwrap_timer.duration
|
|
305
|
+
# metrics_engine.update('sq.shrinkwrap', now, nil, duration * 1000)
|
|
230
306
|
end
|
|
231
307
|
end.install
|
|
232
308
|
|
|
233
309
|
### globally declare instrumentation ready
|
|
234
310
|
Sqreen.instrumentation_ready = true
|
|
311
|
+
Sqreen::Weave.logger.info { "Instrumentation activated" }
|
|
235
312
|
end
|
|
236
313
|
|
|
237
314
|
# needed by Sqreen::Runner
|
|
238
315
|
def remove_all_callbacks
|
|
239
316
|
Sqreen.instrumentation_ready = false
|
|
317
|
+
Sqreen::Weave.logger.info { "Instrumentation deactivated" }
|
|
240
318
|
|
|
241
319
|
loop do
|
|
242
320
|
hook = @hooks.pop
|
|
@@ -253,6 +331,15 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
253
331
|
klass = callback.klass
|
|
254
332
|
method = callback.method
|
|
255
333
|
|
|
334
|
+
if (call_count = ENV['SQREEN_DEBUG_CALL_COUNT'])
|
|
335
|
+
call_count = JSON.parse(call_count)
|
|
336
|
+
if callback.respond_to?(:rule_name) && call_count.key?(callback.rule_name)
|
|
337
|
+
count = call_count[callback.rule_name]
|
|
338
|
+
Sqreen::Weave.logger.debug { "override rule: #{callback.rule_name} call_count: #{count.inspect}" }
|
|
339
|
+
callback.instance_eval { @call_count_interval = call_count[callback.rule_name] }
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
256
343
|
if Sqreen::Graft::HookPoint.new("#{klass}.#{method}").exist?
|
|
257
344
|
hook_point = "#{klass}.#{method}"
|
|
258
345
|
elsif Sqreen::Graft::HookPoint.new("#{klass}##{method}").exist?
|
|
@@ -275,7 +362,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
275
362
|
a = call.args
|
|
276
363
|
r = call.remaining
|
|
277
364
|
|
|
278
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i}" }
|
|
279
365
|
begin
|
|
280
366
|
ret = callback.pre(i, a, r)
|
|
281
367
|
rescue StandardError => e
|
|
@@ -286,17 +372,26 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
286
372
|
Sqreen::RemoteException.record(e)
|
|
287
373
|
end
|
|
288
374
|
end
|
|
289
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i} => return=#{ret.inspect}" }
|
|
290
375
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
376
|
+
next if ret.nil? || !ret.is_a?(Hash)
|
|
377
|
+
|
|
378
|
+
throw_val =
|
|
379
|
+
case ret[:status]
|
|
380
|
+
when :skip, 'skip'
|
|
381
|
+
b.return(ret[:new_return_value]).break! if ret.key?(:new_return_value)
|
|
382
|
+
when :modify_args, 'modify_args'
|
|
383
|
+
b.args(ret[:args])
|
|
384
|
+
when :raise, 'raise'
|
|
385
|
+
if ret.key?(:exception)
|
|
386
|
+
b.raise(ret[:exception])
|
|
387
|
+
else
|
|
388
|
+
b.raise(Sqreen::AttackBlocked.new("Sqreen blocked a security threat (type: #{callback.rule_name}). No action is required."))
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
next unless throw_val
|
|
393
|
+
throw_val.break! if ret[:skip_rem_cbs]
|
|
394
|
+
throw(b, throw_val)
|
|
300
395
|
end
|
|
301
396
|
end
|
|
302
397
|
|
|
@@ -309,7 +404,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
309
404
|
a = call.args
|
|
310
405
|
r = call.remaining
|
|
311
406
|
|
|
312
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i}" }
|
|
313
407
|
begin
|
|
314
408
|
ret = callback.post(v, i, a, r)
|
|
315
409
|
rescue StandardError => e
|
|
@@ -320,7 +414,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
320
414
|
Sqreen::RemoteException.record(e)
|
|
321
415
|
end
|
|
322
416
|
end
|
|
323
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i} => return=#{ret.inspect}" }
|
|
324
417
|
|
|
325
418
|
case ret[:status]
|
|
326
419
|
when :override, 'override'
|
|
@@ -341,7 +434,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
341
434
|
a = call.args
|
|
342
435
|
r = call.remaining
|
|
343
436
|
|
|
344
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i}" }
|
|
345
437
|
begin
|
|
346
438
|
ret = callback.failing(e, i, a, r)
|
|
347
439
|
rescue StandardError => e
|
|
@@ -352,7 +444,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
|
352
444
|
Sqreen::RemoteException.record(e)
|
|
353
445
|
end
|
|
354
446
|
end
|
|
355
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i} => return=#{ret.inspect}" }
|
|
356
447
|
|
|
357
448
|
throw(b, b.raise(e)) if ret.nil? || !ret.is_a?(Hash)
|
|
358
449
|
|