sqreen 1.20.1 → 1.21.0.beta1
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/lib/sqreen/attack_detected.html +1 -2
- data/lib/sqreen/deliveries/batch.rb +8 -1
- data/lib/sqreen/ecosystem.rb +80 -0
- data/lib/sqreen/ecosystem/dispatch_table.rb +43 -0
- data/lib/sqreen/ecosystem/http/net_http.rb +51 -0
- data/lib/sqreen/ecosystem/http/rack_request.rb +38 -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/signal_producer.rb +26 -0
- data/lib/sqreen/ecosystem/module_api/tracing_push_down.rb +34 -0
- data/lib/sqreen/ecosystem/module_api/transaction_storage.rb +71 -0
- data/lib/sqreen/ecosystem/module_registry.rb +39 -0
- data/lib/sqreen/ecosystem/redis/redis_connection.rb +35 -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_id_setup.rb +34 -0
- data/lib/sqreen/ecosystem/transaction_storage.rb +64 -0
- data/lib/sqreen/ecosystem_integration.rb +70 -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 +56 -0
- data/lib/sqreen/ecosystem_integration/signal_consumption.rb +35 -0
- data/lib/sqreen/frameworks/generic.rb +15 -1
- data/lib/sqreen/graft/call.rb +9 -0
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +7 -1
- data/lib/sqreen/remote_command.rb +3 -0
- data/lib/sqreen/runner.rb +19 -5
- data/lib/sqreen/session.rb +2 -0
- data/lib/sqreen/signals/conversions.rb +6 -1
- data/lib/sqreen/version.rb +1 -1
- metadata +32 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49a6c95ab34d19ae0f769e475ae67c2c3e4d19b17582ee09d8a6d231ac3d9150
|
4
|
+
data.tar.gz: ad1ea7a80f3582ba90ffc6aa1cef7040459c56f65ea4712a023923b8bc7801e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0da6438f20a00a84914db2bb06c24feab53e164feae1cb7d2af0b53afe24c5d5ea54a0cb68a8872a49aadedae4450de57e63da6a4f4a2ec21ac85eaa84c13acf
|
7
|
+
data.tar.gz: 3e75918e810529674e10d693fd2a62c0eeeeecb18bac06a25fdd686d29c45d55333abb0feea790ec1d89e29ce71097bd1de16c2d31d98a6219e985d806793008
|
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
<!-- Sorry, you’ve been blocked --><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>You've been blocked</title><style>a,body,div,h1,html,span{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}body{background:-webkit-radial-gradient(26% 19%,circle,#fff,#f4f7f9);background:radial-gradient(circle at 26% 19%,#fff,#f4f7f9);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:center;align-content:center;width:100%;min-height:100vh;line-height:1;flex-direction:column}h1,p,svg{display:block}svg{margin:0 auto 4vh}main{text-align:center;flex:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:center;align-content:center;flex-direction:column}h1{font-family:sans-serif;font-weight:600;font-size:34px;color:#1e0936;line-height:1.2}p{font-size:18px;line-height:normal;color:#646464;font-family:sans-serif;font-weight:400}a{color:#4842b7}footer{width:100%;text-align:center}footer p{font-size:16px}</style></head><body><main><svg width="170px" height="193px" viewBox="0 0 170 193" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true"><g id="exports" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g id="Artboard" transform="translate(-186.000000, -189.000000)"><g id="logo-cmyk-indigo" transform="translate(186.000000, 189.000000)"><g id="nest-cmyk-indigo"><ellipse id="sqreen" fill="#B0ACFF" cx="85" cy="96.5" rx="45.7692308" ry="45.7966102"></ellipse><path d="M78.4615385,175.749389 L78.4615385,102.2092 L13.1398162,64.4731256 L13.1398162,129.181112 L36.352167,115.771438 C37.9764468,119.873152 40.1038639,123.720553 42.6582364,127.237412 L18.5723996,141.151695 L78.4615385,175.749389 Z M91.5384615,175.749389 L151.4276,141.151695 L127.341764,127.237412 C129.896136,123.720553 132.023553,119.873152 133.647833,115.771438 L156.860184,129.181112 L156.860184,64.4731256 L91.5384615,102.2092 L91.5384615,175.749389 Z M18.0061522,52.1754237 L85,90.8774777 L151.993848,52.1754237 L91.5384615,17.2506105 L91.5384615,44.565949 C89.3964992,44.2986903 87.2143177,44.1610169 85,44.1610169 C82.7856823,44.1610169 80.6035008,44.2986903 78.4615385,44.565949 L78.4615385,17.2506105 L18.0061522,52.1754237 Z M90.8846156,1.76392358 L164.052491,44.0326866 C167.693904,46.1363149 169.937107,50.0239804 169.937107,54.231237 L169.937107,138.768763 C169.937107,142.97602 167.693904,146.863685 164.052491,148.967313 L90.8846156,191.236076 C87.2432028,193.339705 82.7567972,193.339705 79.1153844,191.236076 L5.94750871,148.967313 C2.30609589,146.863685 0.0628930904,142.97602 0.0628930904,138.768763 L0.0628930904,54.231237 C0.0628930904,50.0239804 2.30609589,46.1363149 5.94750871,44.0326866 L79.1153844,1.76392358 C82.7567972,-0.339704735 87.2432028,-0.339704735 90.8846156,1.76392358 Z" id="app" fill="#4842B7"></path></g></g></g></g></svg><h1>Sorry, you've been blocked</h1><p>Contact the website owner</p></main><footer><p>Security provided by <a href="https://www.sqreen.com/?utm_medium=block_page" target="_blank">Sqreen</a></p></footer></body></html>
|
@@ -13,6 +13,8 @@ require 'sqreen/events/attack'
|
|
13
13
|
require 'sqreen/events/remote_exception'
|
14
14
|
require 'sqreen/mono_time'
|
15
15
|
require 'sqreen/deliveries/simple'
|
16
|
+
require 'sqreen/kit/signals/signal'
|
17
|
+
require 'sqreen/kit/signals/trace'
|
16
18
|
|
17
19
|
module Sqreen
|
18
20
|
module Deliveries
|
@@ -58,7 +60,7 @@ module Sqreen
|
|
58
60
|
def post_batch_needed?(event)
|
59
61
|
now = Sqreen.time
|
60
62
|
# do not use any? {} due to side effects inside block
|
61
|
-
event_keys(event).map do |key|
|
63
|
+
event_keys(event).uniq.map do |key|
|
62
64
|
was = @first_seen[key]
|
63
65
|
@first_seen[key] ||= now
|
64
66
|
was.nil? || current_batch.size > max_batch || now > (was + max_staleness)
|
@@ -86,6 +88,7 @@ module Sqreen
|
|
86
88
|
res += event.observed.fetch(:sdk, []).select { |e|
|
87
89
|
e[0] == :track
|
88
90
|
}.map { |e| "sdk-track".freeze }
|
91
|
+
res += event.observed.fetch(:signals, []).map { "signal".freeze }
|
89
92
|
return res
|
90
93
|
end
|
91
94
|
|
@@ -97,6 +100,10 @@ module Sqreen
|
|
97
100
|
"rex-#{event.klass}"
|
98
101
|
when Sqreen::AggregatedMetric
|
99
102
|
"agg-metric"
|
103
|
+
when Sqreen::Kit::Signals::Signal
|
104
|
+
"signal"
|
105
|
+
when Sqreen::Kit::Signals::Trace
|
106
|
+
"signal"
|
100
107
|
end
|
101
108
|
end
|
102
109
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'sqreen/ecosystem/module_registry'
|
3
|
+
require 'sqreen/ecosystem/tracing/sampling_configuration'
|
4
|
+
require 'sqreen/ecosystem/transaction_storage'
|
5
|
+
require 'sqreen/ecosystem/tracing_id_setup'
|
6
|
+
require 'sqreen/ecosystem/module_api/tracing_push_down'
|
7
|
+
|
8
|
+
module Sqreen
|
9
|
+
# The API for the ecosystem client (together with the dispatch table)
|
10
|
+
module Ecosystem
|
11
|
+
class << self
|
12
|
+
def init(opts = {})
|
13
|
+
@registry = ModuleRegistry.new
|
14
|
+
register_modules(opts[:modules])
|
15
|
+
@registry.init_all
|
16
|
+
|
17
|
+
@tracing_id_setup = TracingIdSetup.new(@registry)
|
18
|
+
@tracing_id_setup.setup_modules
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset
|
22
|
+
instance_variables.each do |ia|
|
23
|
+
instance_variable_set(ia, nil)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# To be called by the Ecosystem client when a new transaction
|
28
|
+
# (generally: request) is started
|
29
|
+
# In the future, it's intended that request end/start detection be handled
|
30
|
+
# by the Ecosystem itself, so control will flow in the other direction,
|
31
|
+
# from the ecosystem to its client
|
32
|
+
def start_transaction
|
33
|
+
TransactionStorage.create_thread_local
|
34
|
+
end
|
35
|
+
|
36
|
+
def end_transaction
|
37
|
+
TransactionStorage.destroy_thread_local
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param [String] tracing_id_prefix
|
41
|
+
# @param [Array<Hash{String=>Object}>] sampling_config
|
42
|
+
def configure_sampling(tracing_id_prefix, sampling_config)
|
43
|
+
@tracing_id_setup.tracing_id_prefix = tracing_id_prefix
|
44
|
+
built_samp_cfg = Tracing::SamplingConfiguration.new(sampling_config)
|
45
|
+
inject_sampling_config(built_samp_cfg)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def register_modules(modules)
|
51
|
+
return register_all_modules unless modules
|
52
|
+
|
53
|
+
modules.each { |mod| register mod }
|
54
|
+
end
|
55
|
+
|
56
|
+
def register_all_modules
|
57
|
+
# replace with something more magical?
|
58
|
+
require_relative 'ecosystem/http/rack_request'
|
59
|
+
register Http::RackRequest.new
|
60
|
+
|
61
|
+
require_relative 'ecosystem/http/net_http'
|
62
|
+
register Http::NetHttp.new
|
63
|
+
|
64
|
+
require_relative 'ecosystem/redis/redis_connection'
|
65
|
+
register Redis::RedisConnection.new
|
66
|
+
end
|
67
|
+
|
68
|
+
def register(mod)
|
69
|
+
@registry.register mod
|
70
|
+
end
|
71
|
+
|
72
|
+
# @param [Sqreen::Ecosystem::SamplingConfiguration] config
|
73
|
+
def inject_sampling_config(config)
|
74
|
+
@registry.each_module(Sqreen::Ecosystem::ModuleApi::TracingPushDown) do |mod|
|
75
|
+
mod.sampling_config = config
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
# Configured by the ecosystem client
|
6
|
+
module DispatchTable
|
7
|
+
class << self
|
8
|
+
# data consumption
|
9
|
+
# argument: +Sqreen::Kit::Signals::Signal+
|
10
|
+
# see +Sqreen::EcosystemIntegration::SignalConsumption#consume_signal+
|
11
|
+
attr_accessor :consume_signal
|
12
|
+
|
13
|
+
# argument: block taking a Rack::Request
|
14
|
+
# see +Sqreen::EcosystemIntegration::RequestLifecycleTracking#add_start_observer+
|
15
|
+
attr_accessor :add_request_start_listener
|
16
|
+
|
17
|
+
attr_accessor :fetch_logger
|
18
|
+
|
19
|
+
# argument: callback taking:
|
20
|
+
# * the method to instrument
|
21
|
+
# * A Hash{Symbol=>Proc} with the advice. The proc takes the
|
22
|
+
# arguments and the ball, so these details of the instrumentation
|
23
|
+
# implementation leak through the abstraction
|
24
|
+
# see +Sqreen::EcosystemIntegration::InstrumentationService+
|
25
|
+
attr_accessor :instrument
|
26
|
+
|
27
|
+
def reset
|
28
|
+
instance_variables.each do |ia|
|
29
|
+
instance_variable_set(ia, nil)
|
30
|
+
end
|
31
|
+
|
32
|
+
# set default logger
|
33
|
+
logger = ::Logger.new(STDERR)
|
34
|
+
logger.level = ::Logger::WARN
|
35
|
+
logger.progname = 'sqreen-ecosystem'
|
36
|
+
self.fetch_logger = proc { logger }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
reset
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'sqreen/ecosystem/module_api'
|
2
|
+
require 'sqreen/ecosystem/module_api/instrumentation'
|
3
|
+
require 'sqreen/ecosystem/module_api/tracing_push_down'
|
4
|
+
require 'sqreen/ecosystem/module_api/signal_producer'
|
5
|
+
require 'sqreen/ecosystem/module_api/transaction_storage'
|
6
|
+
require 'sqreen/ecosystem/tracing/signals/tracing_client'
|
7
|
+
|
8
|
+
module Sqreen
|
9
|
+
module Ecosystem
|
10
|
+
module Http
|
11
|
+
class NetHttp
|
12
|
+
include ModuleApi::Instrumentation
|
13
|
+
include ModuleApi::SignalProducer
|
14
|
+
include ModuleApi::TracingPushDown
|
15
|
+
|
16
|
+
def setup
|
17
|
+
instrument 'Net::HTTP#request', before: method(:before_advice)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# instr. def request(req, body = nil, &block) # :yield: +response+
|
23
|
+
# req is of type +Net::HTTPGenericRequest+
|
24
|
+
def before_advice(call, _ball)
|
25
|
+
return unless should_sample?('client')
|
26
|
+
|
27
|
+
tracing_id = create_tracing_id
|
28
|
+
|
29
|
+
# build & submit signal
|
30
|
+
host = call.instance.address
|
31
|
+
port = call.instance.port
|
32
|
+
|
33
|
+
host += ':' + port.to_s if port != 80 && port != 443
|
34
|
+
|
35
|
+
signal = Tracing::Signals::TracingClient.new
|
36
|
+
signal.payload = Tracing::Signals::TracingClient::Payload.new(
|
37
|
+
transport: 'http',
|
38
|
+
host: host,
|
39
|
+
tracing_identifier: tracing_id
|
40
|
+
)
|
41
|
+
|
42
|
+
submit_signal signal
|
43
|
+
|
44
|
+
# add tracing header, if available
|
45
|
+
req = call.args[0]
|
46
|
+
req[ModuleApi::TRACE_ID_HEADER] = tracing_id
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'sqreen/ecosystem/module_api'
|
2
|
+
require 'sqreen/ecosystem/module_api/event_listener'
|
3
|
+
require 'sqreen/ecosystem/module_api/signal_producer'
|
4
|
+
require 'sqreen/ecosystem/module_api/tracing_push_down'
|
5
|
+
require 'sqreen/ecosystem/tracing/signals/tracing_server'
|
6
|
+
|
7
|
+
module Sqreen
|
8
|
+
module Ecosystem
|
9
|
+
module Http
|
10
|
+
class RackRequest
|
11
|
+
include ModuleApi::EventListener
|
12
|
+
include ModuleApi::TracingPushDown
|
13
|
+
include ModuleApi::SignalProducer
|
14
|
+
|
15
|
+
def setup
|
16
|
+
on_request_start(&method(:handle_request))
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def handle_request(rack_request)
|
22
|
+
return unless should_sample?('server')
|
23
|
+
|
24
|
+
trace_id = rack_request.env[ModuleApi::TRACE_ID_ENV_KEY]
|
25
|
+
|
26
|
+
signal = Tracing::Signals::TracingServer.new
|
27
|
+
signal.payload = Tracing::Signals::TracingServer::Payload.new(
|
28
|
+
transport: 'http',
|
29
|
+
client_ip: rack_request.ip,
|
30
|
+
tracing_identifier: trace_id
|
31
|
+
)
|
32
|
+
|
33
|
+
submit_signal signal
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'sqreen/ecosystem/loggable'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
# The API that the transport/tracing modules are written against
|
6
|
+
module ModuleApi
|
7
|
+
TRACE_ID_HEADER = 'X-Sqreen-Trace-Identifier'.freeze
|
8
|
+
TRACE_ID_ENV_KEY = 'HTTP_X_SQREEN_TRACE_IDENTIFIER'.freeze
|
9
|
+
|
10
|
+
Loggable = Sqreen::Ecosystem::Loggable
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
attr_writer :module_name
|
14
|
+
|
15
|
+
def module_name
|
16
|
+
if instance_variable_defined?(:@module_name)
|
17
|
+
@module_name
|
18
|
+
else
|
19
|
+
# to snake case
|
20
|
+
@module_name = to_s.sub(/.*::/, '').gsub(/([a-z])([A-Z])/, '\1_\2').downcase
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.included(mod)
|
26
|
+
mod.extend(ClassMethods)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'sqreen/ecosystem/dispatch_table'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
module ModuleApi
|
6
|
+
module EventListener
|
7
|
+
private
|
8
|
+
|
9
|
+
# XXX: callbacks need to be wrapped in order ot handle
|
10
|
+
# perfcap, exceptions, and maybe other concerns applying
|
11
|
+
# across the board
|
12
|
+
def on_request_start(&cb)
|
13
|
+
DispatchTable.add_request_start_listener.call(cb)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'sqreen/ecosystem/module_api'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
module ModuleApi
|
6
|
+
module Instrumentation
|
7
|
+
def self.included(mod)
|
8
|
+
mod.send :include, ModuleApi unless mod.ancestors.include?(ModuleApi)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Just forwards the call to the instrumentation service
|
14
|
+
# @param [String] method
|
15
|
+
# @param [Hash{Symbol=>Proc}] advice keys are one of: :before, :after,
|
16
|
+
# :raised,
|
17
|
+
def instrument(method, advice)
|
18
|
+
DispatchTable.instrument.call(self.class.module_name, method, advice)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sqreen/ecosystem/dispatch_table'
|
2
|
+
require 'sqreen/ecosystem/module_api/transaction_storage'
|
3
|
+
|
4
|
+
module Sqreen
|
5
|
+
module Ecosystem
|
6
|
+
module ModuleApi
|
7
|
+
module SignalProducer
|
8
|
+
include TransactionStorage
|
9
|
+
|
10
|
+
# for injection
|
11
|
+
attr_writer :tracing_id_producer
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def create_tracing_id
|
16
|
+
@tracing_id_producer.call
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [Sqreen::Kit::Signals::Signal] signal
|
20
|
+
def submit_signal(signal)
|
21
|
+
DispatchTable.consume_signal.call(signal)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'sqreen/ecosystem/loggable'
|
2
|
+
require 'sqreen/ecosystem/tracing/sampling_configuration'
|
3
|
+
|
4
|
+
module Sqreen
|
5
|
+
module Ecosystem
|
6
|
+
module ModuleApi
|
7
|
+
module TracingPushDown
|
8
|
+
include Loggable
|
9
|
+
|
10
|
+
# method for ecosystem to inject the config
|
11
|
+
# @param [Sqreen::Ecosystem::SamplingConfiguration]
|
12
|
+
attr_writer :sampling_config
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def should_sample?(scope)
|
17
|
+
unless @sampling_config
|
18
|
+
logger.debug { "Scope #{scope} is disabled because tracing hasn't been enabled yet" }
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
result = @sampling_config.should_sample?(scope)
|
23
|
+
if result
|
24
|
+
logger.debug { "Will sample scope #{scope}. Sampling line: #{result}" }
|
25
|
+
else
|
26
|
+
logger.debug { "Will NOT sample scope #{scope}" }
|
27
|
+
end
|
28
|
+
|
29
|
+
result
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'sqreen/ecosystem/transaction_storage'
|
2
|
+
require 'sqreen/ecosystem/loggable'
|
3
|
+
|
4
|
+
module Sqreen
|
5
|
+
module Ecosystem
|
6
|
+
module ModuleApi
|
7
|
+
module TransactionStorage
|
8
|
+
class TxLocalVariables
|
9
|
+
class << self
|
10
|
+
class << self
|
11
|
+
include Sqreen::Ecosystem::Loggable
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def attr_reader(attr, _opts = {})
|
16
|
+
define_method attr do
|
17
|
+
tx_storage = Ecosystem::TransactionStorage.fetch_thread_local
|
18
|
+
return unless tx_storage
|
19
|
+
tx_storage[attr]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def attr_accessor(attr, opts = {})
|
24
|
+
# reader
|
25
|
+
attr_reader attr, opts
|
26
|
+
|
27
|
+
# writer (2 variants)
|
28
|
+
do_assign = proc do |value|
|
29
|
+
tx_storage = Ecosystem::TransactionStorage.fetch_thread_local
|
30
|
+
unless tx_storage
|
31
|
+
logger.debug do
|
32
|
+
"Assignment of tx local attribute #{attr} to #{value} has no effect"
|
33
|
+
end
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
tx_storage[attr] = value
|
38
|
+
end
|
39
|
+
|
40
|
+
if opts.fetch(:allow_overwrite, false)
|
41
|
+
define "#{attr}=", &do_assign
|
42
|
+
else
|
43
|
+
define_method "#{attr}=" do |value|
|
44
|
+
cur = public_send(attr)
|
45
|
+
unless cur.nil?
|
46
|
+
raise "Cannot override value of #{attr} from #{cur} with #{value}"
|
47
|
+
end
|
48
|
+
|
49
|
+
do_assign.call(value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end # TxLocalVariables.singleton_class.singleton_class
|
54
|
+
|
55
|
+
# usage:
|
56
|
+
# attr_reader :xxx
|
57
|
+
|
58
|
+
# in the future, we'll possibly need to expose the full
|
59
|
+
# TransactionStorage to the modules, at least if we don't
|
60
|
+
# opt for a more structured fashion of data exchange between
|
61
|
+
# the modules.
|
62
|
+
end # TxLocalVariables.singleton_class
|
63
|
+
end # TxLocalVariables
|
64
|
+
|
65
|
+
def tx_local_vars
|
66
|
+
TxLocalVariables
|
67
|
+
end
|
68
|
+
end # TransactionStorage module
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|