sqreen 1.20.4-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 +4 -4
- data/CHANGELOG.md +15 -24
- data/lib/sqreen/condition_evaluator.rb +6 -5
- data/lib/sqreen/conditionable.rb +24 -6
- data/lib/sqreen/deliveries/batch.rb +8 -1
- 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/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/client_data.rb +31 -0
- data/lib/sqreen/ecosystem/module_api/tracing/server_data.rb +27 -0
- data/lib/sqreen/ecosystem/module_api/tracing.rb +45 -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_api.rb +30 -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.rb +96 -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/ecosystem_integration.rb +87 -0
- data/lib/sqreen/frameworks/generic.rb +15 -1
- data/lib/sqreen/graft/call.rb +30 -1
- data/lib/sqreen/graft/hook.rb +88 -78
- data/lib/sqreen/graft/hook_point.rb +17 -10
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +7 -1
- data/lib/sqreen/metrics/req_detailed.rb +41 -0
- data/lib/sqreen/metrics.rb +1 -0
- data/lib/sqreen/remote_command.rb +3 -0
- data/lib/sqreen/rules/rule_cb.rb +2 -2
- data/lib/sqreen/runner.rb +44 -15
- data/lib/sqreen/session.rb +2 -0
- data/lib/sqreen/signals/conversions.rb +6 -1
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/budget.rb +3 -14
- data/lib/sqreen/weave/legacy/instrumentation.rb +145 -94
- metadata +41 -5
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'sqreen/ecosystem/loggable'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
# The transaction storage is a mechanism for the modules to share
|
6
|
+
# request-scoped data with each other or to keep request-scoped objects
|
7
|
+
# themselves, although, for this last use case to be effective,
|
8
|
+
# propagation of request start/end events to the modules will likely be
|
9
|
+
# needed. A more generic notification of data availability to modules
|
10
|
+
# also may be needed in the future.
|
11
|
+
#
|
12
|
+
# This is not be used to share data with the Ecosystem client
|
13
|
+
#
|
14
|
+
# This class is not thread safe because it can call the lazy getter
|
15
|
+
# twice if [] is called concurrently.
|
16
|
+
class TransactionStorage
|
17
|
+
include Loggable
|
18
|
+
|
19
|
+
class << self
|
20
|
+
# @return [Sqreen::Ecosystem::TransactionStorage]
|
21
|
+
def create_thread_local
|
22
|
+
Thread.current[:tx_storage] = new
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Sqreen::Ecosystem::TransactionStorage]
|
26
|
+
def fetch_thread_local
|
27
|
+
Thread.current[:tx_storage]
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy_thread_local
|
31
|
+
Thread.current[:tx_storage] = nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@values = {}
|
37
|
+
@values_lazy = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def []=(key, value)
|
41
|
+
@values[key] = value
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_lazy(key, &block)
|
45
|
+
@values_lazy[key] = block
|
46
|
+
end
|
47
|
+
|
48
|
+
def [](key)
|
49
|
+
v = @values[key]
|
50
|
+
return v unless v.nil?
|
51
|
+
|
52
|
+
v = @values_lazy[key]
|
53
|
+
return nil if v.nil?
|
54
|
+
|
55
|
+
begin
|
56
|
+
@values[key] = v.call
|
57
|
+
rescue StandardError => e
|
58
|
+
logger.warn { "Error resolving key #{e} with lazy value: #{e.message}" }
|
59
|
+
raise
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,96 @@
|
|
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_broker'
|
6
|
+
require 'sqreen/ecosystem/tracing_id_setup'
|
7
|
+
require 'sqreen/ecosystem/module_api/message_producer'
|
8
|
+
require 'sqreen/ecosystem/module_api/tracing_id_generation'
|
9
|
+
require 'sqreen/ecosystem/module_api/tracing'
|
10
|
+
|
11
|
+
module Sqreen
|
12
|
+
# The API for the ecosystem client (together with the dispatch table)
|
13
|
+
module Ecosystem
|
14
|
+
class << self
|
15
|
+
def init(opts = {})
|
16
|
+
@registry = ModuleRegistry.new
|
17
|
+
register_modules(opts[:modules])
|
18
|
+
@registry.init_all
|
19
|
+
|
20
|
+
# setup tracing generation
|
21
|
+
tracing_id_mods = @registry.module_subset(ModuleApi::TracingIdGeneration)
|
22
|
+
@tracing_id_setup = TracingIdSetup.new(tracing_id_mods)
|
23
|
+
@tracing_id_setup.setup_modules
|
24
|
+
|
25
|
+
# configure tracing broker with the consumers (tracing modules)
|
26
|
+
tracing_modules = @registry.module_subset(ModuleApi::Tracing)
|
27
|
+
@tracing_broker = TracingBroker.new(tracing_modules)
|
28
|
+
|
29
|
+
# inject tracing broker in message producers
|
30
|
+
@registry.each_module(ModuleApi::MessageProducer) do |mod|
|
31
|
+
mod.tracing_broker = @tracing_broker
|
32
|
+
end
|
33
|
+
rescue ::Exception # rubocop:disable Lint/RescueException
|
34
|
+
# TODO: modules must be disabled at this point
|
35
|
+
raise
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset
|
39
|
+
instance_variables.each do |ia|
|
40
|
+
instance_variable_set(ia, nil)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# To be called by the Ecosystem client when a new transaction
|
45
|
+
# (generally: request) is started
|
46
|
+
# In the future, it's intended that request end/start detection be handled
|
47
|
+
# by the Ecosystem itself, so control will flow in the other direction,
|
48
|
+
# from the ecosystem to its client
|
49
|
+
def start_transaction
|
50
|
+
TransactionStorage.create_thread_local
|
51
|
+
end
|
52
|
+
|
53
|
+
def end_transaction
|
54
|
+
TransactionStorage.destroy_thread_local
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param [String] tracing_id_prefix
|
58
|
+
# @param [Array<Hash{String=>Object}>] sampling_config
|
59
|
+
def configure_sampling(tracing_id_prefix, sampling_config)
|
60
|
+
@tracing_id_setup.tracing_id_prefix = tracing_id_prefix
|
61
|
+
built_samp_cfg = Tracing::SamplingConfiguration.new(sampling_config)
|
62
|
+
@tracing_broker.sampling_configuration = built_samp_cfg
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def register_modules(modules)
|
68
|
+
return register_all_modules unless modules
|
69
|
+
|
70
|
+
modules.each { |mod| register mod }
|
71
|
+
end
|
72
|
+
|
73
|
+
def register_all_modules
|
74
|
+
# replace with something more magical?
|
75
|
+
require_relative 'ecosystem/http/rack_request'
|
76
|
+
register Http::RackRequest.new
|
77
|
+
|
78
|
+
require_relative 'ecosystem/http/net_http'
|
79
|
+
register Http::NetHttp.new
|
80
|
+
|
81
|
+
require_relative 'ecosystem/redis/redis_connection'
|
82
|
+
register Redis::RedisConnection.new
|
83
|
+
|
84
|
+
require_relative 'ecosystem/tracing/modules/client'
|
85
|
+
register Tracing::Modules::Client.new
|
86
|
+
|
87
|
+
require_relative 'ecosystem/tracing/modules/server'
|
88
|
+
register Tracing::Modules::Server.new
|
89
|
+
end
|
90
|
+
|
91
|
+
def register(mod)
|
92
|
+
@registry.register mod
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'sqreen/metrics_store'
|
2
|
+
require 'sqreen/log/loggable'
|
3
|
+
require 'sqreen/events/remote_exception'
|
4
|
+
require 'sqreen/mono_time'
|
5
|
+
require 'sqreen/graft/call'
|
6
|
+
|
7
|
+
module Sqreen
|
8
|
+
class EcosystemIntegration
|
9
|
+
module AroundCallbacks
|
10
|
+
class << self
|
11
|
+
include Log::Loggable::ClassMethods
|
12
|
+
|
13
|
+
# @return [Proc]
|
14
|
+
attr_accessor :create_metric
|
15
|
+
|
16
|
+
# for instrumentation hooks
|
17
|
+
# instrumentation hooks already handle budgets/metrics
|
18
|
+
def wrap_instrumentation_hook(module_name, action, callable)
|
19
|
+
# make tag similar to that of rules
|
20
|
+
# TODO: move to structured tags to avoid silly string manips
|
21
|
+
action_for_metric = if %w[pre post failing finally].include?(action)
|
22
|
+
action
|
23
|
+
else
|
24
|
+
'pre'
|
25
|
+
end
|
26
|
+
metric_name = "sq.ecosystem_#{module_name}.#{action_for_metric}"
|
27
|
+
create_metric.call(metric_name)
|
28
|
+
|
29
|
+
Proc.new do |*args|
|
30
|
+
begin
|
31
|
+
callable.call(*args)
|
32
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
33
|
+
# 2) rescue exceptions
|
34
|
+
logger.warn { "Error in #{module_name}:#{action}: #{e.message}" }
|
35
|
+
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
36
|
+
Sqreen::RemoteException.record(e)
|
37
|
+
end # end begin
|
38
|
+
end # end proc
|
39
|
+
end
|
40
|
+
|
41
|
+
# XXX: not used yet
|
42
|
+
def wrap_generic_callback(module_name, action, callable)
|
43
|
+
timer_name = "ecosystem:#{module_name}@#{action}"
|
44
|
+
perf_notif_name = "ecosystem_#{module_name}"
|
45
|
+
|
46
|
+
# XXX: register metric
|
47
|
+
|
48
|
+
Proc.new do |*args|
|
49
|
+
begin
|
50
|
+
req_storage = Thread.current[:sqreen_http_request]
|
51
|
+
|
52
|
+
timer = Graft::Timer.new(timer_name) do |t|
|
53
|
+
# this is an epilogue to measure()
|
54
|
+
req_storage && req_storage[:timed_hooks] << t
|
55
|
+
end
|
56
|
+
|
57
|
+
req_timer = nil
|
58
|
+
timer.measure do
|
59
|
+
# not in a request, no budget; call cb
|
60
|
+
next callable.call(*args) unless req_storage
|
61
|
+
|
62
|
+
# 1) budget enforcement
|
63
|
+
# skip callback if budget already expended
|
64
|
+
next if req_storage[:time_budget_expended]
|
65
|
+
|
66
|
+
budget = req_storage[:time_budget]
|
67
|
+
if budget
|
68
|
+
req_timer = req_storage[:timer]
|
69
|
+
remaining = budget - req_timer.elapsed
|
70
|
+
unless remaining > 0
|
71
|
+
req_storage[:time_budget_expended] = true
|
72
|
+
next # skip callback
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
callable.call(*args)
|
77
|
+
end
|
78
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
79
|
+
# 2) rescue exceptions
|
80
|
+
logger.warn { "Error in #{module_name}:#{action}: #{e.message}" }
|
81
|
+
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
82
|
+
Sqreen::RemoteException.record(e)
|
83
|
+
ensure
|
84
|
+
# 3) contribute to performance metrics
|
85
|
+
if timer
|
86
|
+
req_timer.include_measurements(timer) if req_timer
|
87
|
+
|
88
|
+
# XXX: PerformanceNotifications is used no more
|
89
|
+
Sqreen::PerformanceNotifications.notify(
|
90
|
+
perf_notif_name, action, *timer.start_and_end
|
91
|
+
)
|
92
|
+
end
|
93
|
+
end # end begin
|
94
|
+
end # end proc
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'sqreen/graft/hook'
|
2
|
+
require 'sqreen/ecosystem_integration/around_callbacks'
|
3
|
+
|
4
|
+
module Sqreen
|
5
|
+
class EcosystemIntegration
|
6
|
+
module InstrumentationService
|
7
|
+
class << self
|
8
|
+
# @param [String] module_name
|
9
|
+
# @param [String] method in form A::B#c or A::B.c
|
10
|
+
# @param [Hash{Symbol=>Proc}] spec
|
11
|
+
def instrument(module_name, method, spec)
|
12
|
+
hook = Sqreen::Graft::Hook[method].add do
|
13
|
+
if spec[:before]
|
14
|
+
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'pre', spec[:before])
|
15
|
+
tag = "weave,rule=ecosystem_#{module_name}"
|
16
|
+
before(tag, flow: true, &cb)
|
17
|
+
end
|
18
|
+
|
19
|
+
if spec[:after]
|
20
|
+
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'post', spec[:after])
|
21
|
+
tag = "weave,rule=ecosystem_#{module_name}"
|
22
|
+
after(tag, flow: true, &cb)
|
23
|
+
end
|
24
|
+
|
25
|
+
if spec[:raised]
|
26
|
+
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'failing', spec[:raised])
|
27
|
+
tag = "weave,rule=ecosystem_#{module_name}"
|
28
|
+
raised(tag, flow: true, &cb)
|
29
|
+
end
|
30
|
+
|
31
|
+
if spec[:ensured]
|
32
|
+
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'finally', spec[:ensured])
|
33
|
+
tag = "weave,rule=ecosystem_#{module_name}"
|
34
|
+
ensured(tag, flow: true, &cb)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
hook.install
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'sqreen/events/remote_exception'
|
2
|
+
require 'sqreen/log/loggable'
|
3
|
+
|
4
|
+
module Sqreen
|
5
|
+
class EcosystemIntegration
|
6
|
+
# This class gets notified of request start/end and
|
7
|
+
# 1) distributes such events to listeners (typically ecosystem modules;
|
8
|
+
# the method add_start_observer is exposed to ecosystem modules through
|
9
|
+
# +Sqreen::Ecosystem::ModuleApi::EventListener+ and the dispatch table).
|
10
|
+
# 2) keeps track of whether a request is active on this thread. This is
|
11
|
+
# so that users of this class can have this information without needing
|
12
|
+
# to subscribe to request start/events and keeping thread local state
|
13
|
+
# themselves.
|
14
|
+
# XXX: Since the Ecosystem is also notified of request start/end, it could
|
15
|
+
# notify its modules of request start without going through the dispatch
|
16
|
+
# table and call add_start_observer. We need to think if we want to keep
|
17
|
+
# the transaction / request distinction or if they should just be
|
18
|
+
# assumed to be the same, though.
|
19
|
+
class RequestLifecycleTracking
|
20
|
+
include Sqreen::Log::Loggable
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@start_observers = []
|
24
|
+
@tl_key = "#{object_id}_req_in_flight"
|
25
|
+
end
|
26
|
+
|
27
|
+
# API for classes needing to know the request state
|
28
|
+
|
29
|
+
# @param cb A callback taking a Rack::Request
|
30
|
+
def add_start_observer(cb)
|
31
|
+
@start_observers << cb
|
32
|
+
end
|
33
|
+
|
34
|
+
def in_request?
|
35
|
+
Thread.current[@tl_key] ? true : false
|
36
|
+
end
|
37
|
+
|
38
|
+
# API for classes notifying this one of request events
|
39
|
+
|
40
|
+
def notify_request_start(rack_req)
|
41
|
+
Thread.current[@tl_key] = true
|
42
|
+
return if @start_observers.empty?
|
43
|
+
@start_observers.each do |cb|
|
44
|
+
begin
|
45
|
+
cb.call(rack_req)
|
46
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
47
|
+
logger.warn { "Error calling #{cb} on request start: #{e.message}" }
|
48
|
+
Sqreen::RemoteException.record(e)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def notify_request_end
|
54
|
+
Thread.current[@tl_key] = false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'sqreen/log/loggable'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
class EcosystemIntegration
|
5
|
+
class SignalConsumption
|
6
|
+
include Sqreen::Log::Loggable
|
7
|
+
|
8
|
+
PAYLOAD_CREATOR_SECTIONS = %w[request response params headers].freeze
|
9
|
+
|
10
|
+
# @param [Sqreen::Frameworks::GenericFramework] framework
|
11
|
+
# @param [Sqreen::EcosystemIntegration::RequestLifecycleTracking]
|
12
|
+
# @param [Sqreen::CappedQueue]
|
13
|
+
def initialize(framework, req_lifecycle, queue)
|
14
|
+
@framework = framework
|
15
|
+
@req_lifecycle = req_lifecycle
|
16
|
+
@queue = queue
|
17
|
+
end
|
18
|
+
|
19
|
+
def consume_signal(signal)
|
20
|
+
# transitional
|
21
|
+
unless Sqreen.features.fetch('use_signals', DEFAULT_USE_SIGNALS)
|
22
|
+
logger.debug { "Discarding signal #{signal} (signals disabled)" }
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
if @req_lifecycle.in_request?
|
27
|
+
# add it to the request record
|
28
|
+
@framework.observe(:signals, signal, PAYLOAD_CREATOR_SECTIONS, true)
|
29
|
+
else
|
30
|
+
@queue.push signal
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'sqreen/log/loggable'
|
2
|
+
require 'sqreen/metrics_store'
|
3
|
+
require 'sqreen/ecosystem'
|
4
|
+
require 'sqreen/ecosystem/dispatch_table'
|
5
|
+
require 'sqreen/ecosystem_integration/around_callbacks'
|
6
|
+
require 'sqreen/ecosystem_integration/instrumentation_service'
|
7
|
+
require 'sqreen/ecosystem_integration/request_lifecycle_tracking'
|
8
|
+
require 'sqreen/ecosystem_integration/signal_consumption'
|
9
|
+
|
10
|
+
module Sqreen
|
11
|
+
# This class is the interface through which the agent interacts
|
12
|
+
# with the ecosystem.
|
13
|
+
#
|
14
|
+
# Other classes in the EcosystemIntegration module implement the
|
15
|
+
# functionality that the ecosystem requires in order to deliver
|
16
|
+
# data to the agent and to be informed by the agent of certain
|
17
|
+
# key events (see Sqreen::Ecosystem::DispatchTable).
|
18
|
+
class EcosystemIntegration
|
19
|
+
include Sqreen::Log::Loggable
|
20
|
+
|
21
|
+
# @param [Sqreen::Framework] framework
|
22
|
+
# @param [Proc] create_binning_metric
|
23
|
+
def initialize(framework, queue, create_binning_metric)
|
24
|
+
@framework = framework
|
25
|
+
@queue = queue
|
26
|
+
# XXX: created metrics are insulated from feature upgrades
|
27
|
+
@create_binning_metric = create_binning_metric
|
28
|
+
@request_lifecycle = RequestLifecycleTracking.new
|
29
|
+
@online = false
|
30
|
+
end
|
31
|
+
|
32
|
+
def init
|
33
|
+
raise 'already initialized' if @online
|
34
|
+
|
35
|
+
setup_dispatch_table
|
36
|
+
AroundCallbacks.create_metric = @create_binning_metric
|
37
|
+
Ecosystem.init
|
38
|
+
logger.info 'Ecosystem successfully initialized'
|
39
|
+
@online = true
|
40
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
41
|
+
logger.warn { "Error initializing Ecosystem: #{e.message}" }
|
42
|
+
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
43
|
+
Sqreen::RemoteException.record(e)
|
44
|
+
end
|
45
|
+
|
46
|
+
def disable
|
47
|
+
raise NotImplementedYet
|
48
|
+
end
|
49
|
+
|
50
|
+
def request_start(rack_request)
|
51
|
+
return unless @online
|
52
|
+
|
53
|
+
Ecosystem.start_transaction
|
54
|
+
@request_lifecycle.notify_request_start(rack_request)
|
55
|
+
end
|
56
|
+
|
57
|
+
def request_end
|
58
|
+
return unless @online
|
59
|
+
|
60
|
+
Ecosystem.end_transaction
|
61
|
+
end
|
62
|
+
|
63
|
+
def handle_tracing_command(trace_id_prefix, scopes_config)
|
64
|
+
return unless @online
|
65
|
+
|
66
|
+
Ecosystem.configure_sampling(trace_id_prefix, scopes_config)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def setup_dispatch_table
|
72
|
+
Ecosystem::DispatchTable.consume_signal =
|
73
|
+
create_signal_consumption.method(:consume_signal)
|
74
|
+
|
75
|
+
Ecosystem::DispatchTable.add_request_start_listener =
|
76
|
+
@request_lifecycle.method(:add_start_observer)
|
77
|
+
|
78
|
+
Ecosystem::DispatchTable.fetch_logger = lambda { logger }
|
79
|
+
|
80
|
+
Ecosystem::DispatchTable.instrument = InstrumentationService.method(:instrument)
|
81
|
+
end
|
82
|
+
|
83
|
+
def create_signal_consumption
|
84
|
+
SignalConsumption.new(@framework, @request_lifecycle, @queue)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -22,8 +22,17 @@ module Sqreen
|
|
22
22
|
include RequestRecorder
|
23
23
|
attr_accessor :sqreen_configuration
|
24
24
|
|
25
|
+
attr_writer :req_start_cb, :req_end_cb
|
26
|
+
|
25
27
|
def initialize
|
26
28
|
clean_request_record
|
29
|
+
|
30
|
+
# for notifying the ecosystem of request boundaries
|
31
|
+
# XXX: this should be refactored. It shouldn't be
|
32
|
+
# the framework doing these notifications to the ecosystem
|
33
|
+
# Probably the rule callback should do it itself
|
34
|
+
@req_start_cb = Proc.new {}
|
35
|
+
@req_end_cb = Proc.new {}
|
27
36
|
end
|
28
37
|
|
29
38
|
# What kind of database is this
|
@@ -260,8 +269,12 @@ module Sqreen
|
|
260
269
|
# Nota: cleanup should be performed at end of request (see clean_request)
|
261
270
|
def store_request(object)
|
262
271
|
return unless ensure_rack_loaded
|
272
|
+
|
273
|
+
rack_req = Rack::Request.new(object)
|
274
|
+
@req_start_cb.call(rack_req)
|
275
|
+
|
263
276
|
self.remaining_perf_budget = Sqreen.performance_budget
|
264
|
-
SharedStorage.set(:request,
|
277
|
+
SharedStorage.set(:request, rack_req)
|
265
278
|
SharedStorage.set(:xss_params, nil)
|
266
279
|
SharedStorage.set(:whitelisted, nil)
|
267
280
|
SharedStorage.set(:request_overtime, nil)
|
@@ -290,6 +303,7 @@ module Sqreen
|
|
290
303
|
SharedStorage.set(:xss_params, nil)
|
291
304
|
SharedStorage.set(:whitelisted, nil)
|
292
305
|
SharedStorage.set(:request_overtime, nil)
|
306
|
+
@req_end_cb.call
|
293
307
|
end
|
294
308
|
|
295
309
|
def remaining_perf_budget
|
data/lib/sqreen/graft/call.rb
CHANGED
@@ -27,6 +27,10 @@ module Sqreen
|
|
27
27
|
def raise(value)
|
28
28
|
Flow.raise(value)
|
29
29
|
end
|
30
|
+
|
31
|
+
def noop
|
32
|
+
Flow.noop
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
class Flow
|
@@ -46,12 +50,17 @@ module Sqreen
|
|
46
50
|
def raise(value)
|
47
51
|
new(:raise, value)
|
48
52
|
end
|
53
|
+
|
54
|
+
def noop
|
55
|
+
new(:noop, nil)
|
56
|
+
end
|
49
57
|
end
|
50
58
|
|
51
59
|
def initialize(action, value, brk = false)
|
52
60
|
@action = action
|
53
61
|
@value = value
|
54
62
|
@break = brk
|
63
|
+
@passed_conditions = false
|
55
64
|
end
|
56
65
|
|
57
66
|
def return?
|
@@ -91,6 +100,16 @@ module Sqreen
|
|
91
100
|
def break?
|
92
101
|
@break ? true : false
|
93
102
|
end
|
103
|
+
|
104
|
+
def passed_conditions!
|
105
|
+
@passed_conditions = true
|
106
|
+
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
def passed_conditions?
|
111
|
+
@passed_conditions
|
112
|
+
end
|
94
113
|
end
|
95
114
|
|
96
115
|
class TimerError < StandardError; end
|
@@ -101,6 +120,7 @@ module Sqreen
|
|
101
120
|
end
|
102
121
|
|
103
122
|
attr_reader :tag, :size
|
123
|
+
attr_accessor :conditions_passed
|
104
124
|
|
105
125
|
def initialize(tag, &block)
|
106
126
|
@tag = tag
|
@@ -195,8 +215,17 @@ module Sqreen
|
|
195
215
|
@size.even?
|
196
216
|
end
|
197
217
|
|
218
|
+
def include_measurements(another_timer)
|
219
|
+
@blips += another_timer.instance_variable_get(:@blips)
|
220
|
+
end
|
221
|
+
|
222
|
+
def start_and_end
|
223
|
+
raise 'Not exactly two measurements recorded' unless size == 2
|
224
|
+
@blips
|
225
|
+
end
|
226
|
+
|
198
227
|
def to_s
|
199
|
-
"#{@tag}: time=%.03fus" % (
|
228
|
+
"#{@tag}: time=%.03fus" % (@tally * 1_000_000)
|
200
229
|
end
|
201
230
|
|
202
231
|
protected
|