sqreen 1.21.0.beta1 → 1.21.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/sqreen/ecosystem.rb +26 -10
- data/lib/sqreen/ecosystem/exception_reporting.rb +26 -0
- data/lib/sqreen/ecosystem/http/net_http.rb +16 -17
- data/lib/sqreen/ecosystem/http/rack_request.rb +13 -12
- data/lib/sqreen/ecosystem/module_api/message_producer.rb +51 -0
- data/lib/sqreen/ecosystem/module_api/signal_producer.rb +1 -3
- 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_registry.rb +5 -0
- data/lib/sqreen/ecosystem/redis/redis_connection.rb +19 -11
- 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_broker.rb +101 -0
- data/lib/sqreen/ecosystem/tracing_id_setup.rb +4 -4
- data/lib/sqreen/ecosystem/util/call_writers_from_init.rb +13 -0
- data/lib/sqreen/ecosystem_integration.rb +11 -0
- data/lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb +2 -0
- data/lib/sqreen/version.rb +1 -1
- metadata +12 -3
- data/lib/sqreen/ecosystem/module_api/tracing_push_down.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5b3d6fc37fd5d2431e622d302fd3f58d35dd64a3fc7abca741a84b213688025
|
4
|
+
data.tar.gz: a3443a3f1c95841af9deb7eb5f4a5ab8c47aabf6c6f42eeb902d828edd3ad91d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 487d63ea8f4bc8c5d3da55dced0c8d458c6a6c7f218689027925d8f6ca2808fc4eda478e57ca67764edb8a049fb8fae60b552974ffa39dfaa0dcd15d31f34071
|
7
|
+
data.tar.gz: 23cf04763b76e95d421a36593c2b96d91aad0f40bc206fe8608606fad803a464d03518ac92b40e4c1bb667dbd163ba79c6380f605b1133270f65d66fb8314173
|
data/CHANGELOG.md
CHANGED
data/lib/sqreen/ecosystem.rb
CHANGED
@@ -2,8 +2,11 @@ require 'securerandom'
|
|
2
2
|
require 'sqreen/ecosystem/module_registry'
|
3
3
|
require 'sqreen/ecosystem/tracing/sampling_configuration'
|
4
4
|
require 'sqreen/ecosystem/transaction_storage'
|
5
|
+
require 'sqreen/ecosystem/tracing_broker'
|
5
6
|
require 'sqreen/ecosystem/tracing_id_setup'
|
6
|
-
require 'sqreen/ecosystem/module_api/
|
7
|
+
require 'sqreen/ecosystem/module_api/message_producer'
|
8
|
+
require 'sqreen/ecosystem/module_api/tracing_id_generation'
|
9
|
+
require 'sqreen/ecosystem/module_api/tracing'
|
7
10
|
|
8
11
|
module Sqreen
|
9
12
|
# The API for the ecosystem client (together with the dispatch table)
|
@@ -14,8 +17,22 @@ module Sqreen
|
|
14
17
|
register_modules(opts[:modules])
|
15
18
|
@registry.init_all
|
16
19
|
|
17
|
-
|
20
|
+
# setup tracing generation
|
21
|
+
tracing_id_mods = @registry.module_subset(ModuleApi::TracingIdGeneration)
|
22
|
+
@tracing_id_setup = TracingIdSetup.new(tracing_id_mods)
|
18
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
|
19
36
|
end
|
20
37
|
|
21
38
|
def reset
|
@@ -42,7 +59,7 @@ module Sqreen
|
|
42
59
|
def configure_sampling(tracing_id_prefix, sampling_config)
|
43
60
|
@tracing_id_setup.tracing_id_prefix = tracing_id_prefix
|
44
61
|
built_samp_cfg = Tracing::SamplingConfiguration.new(sampling_config)
|
45
|
-
|
62
|
+
@tracing_broker.sampling_configuration = built_samp_cfg
|
46
63
|
end
|
47
64
|
|
48
65
|
private
|
@@ -63,18 +80,17 @@ module Sqreen
|
|
63
80
|
|
64
81
|
require_relative 'ecosystem/redis/redis_connection'
|
65
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
|
66
89
|
end
|
67
90
|
|
68
91
|
def register(mod)
|
69
92
|
@registry.register mod
|
70
93
|
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
94
|
end
|
79
95
|
end
|
80
96
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sqreen/ecosystem/dispatch_table'
|
2
|
+
require 'sqreen/ecosystem/loggable'
|
3
|
+
require 'sqreen/kit/signals/specialized/sqreen_exception'
|
4
|
+
|
5
|
+
module Sqreen
|
6
|
+
module Ecosystem
|
7
|
+
module ExceptionReporting
|
8
|
+
include Loggable
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# @param [String] message
|
13
|
+
# @param [Exception] e
|
14
|
+
def report_exception(message, e)
|
15
|
+
logger.warn { "#{message}: #{e.message}" }
|
16
|
+
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
17
|
+
|
18
|
+
signal = Sqreen::Kit::Signals::Specialized::SqreenException.new(
|
19
|
+
ruby_exception: e
|
20
|
+
)
|
21
|
+
|
22
|
+
DispatchTable.consume_signal signal
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,20 +1,24 @@
|
|
1
1
|
require 'sqreen/ecosystem/module_api'
|
2
2
|
require 'sqreen/ecosystem/module_api/instrumentation'
|
3
|
-
require 'sqreen/ecosystem/module_api/
|
4
|
-
require 'sqreen/ecosystem/module_api/
|
5
|
-
require 'sqreen/ecosystem/module_api/
|
6
|
-
require 'sqreen/ecosystem/tracing/signals/tracing_client'
|
3
|
+
require 'sqreen/ecosystem/module_api/message_producer'
|
4
|
+
require 'sqreen/ecosystem/module_api/tracing_id_generation'
|
5
|
+
require 'sqreen/ecosystem/module_api/tracing/client_data'
|
7
6
|
|
8
7
|
module Sqreen
|
9
8
|
module Ecosystem
|
10
9
|
module Http
|
11
10
|
class NetHttp
|
11
|
+
class HttpConnectionData
|
12
|
+
include ModuleApi::Tracing::ClientData
|
13
|
+
end
|
14
|
+
|
12
15
|
include ModuleApi::Instrumentation
|
13
|
-
include ModuleApi::
|
14
|
-
include ModuleApi::
|
16
|
+
include ModuleApi::MessageProducer
|
17
|
+
include ModuleApi::TracingIdGeneration
|
15
18
|
|
16
19
|
def setup
|
17
|
-
|
20
|
+
advice = wrap_for_interest(HttpConnectionData, &method(:before_advice))
|
21
|
+
instrument 'Net::HTTP#request', before: advice
|
18
22
|
end
|
19
23
|
|
20
24
|
private
|
@@ -22,28 +26,23 @@ module Sqreen
|
|
22
26
|
# instr. def request(req, body = nil, &block) # :yield: +response+
|
23
27
|
# req is of type +Net::HTTPGenericRequest+
|
24
28
|
def before_advice(call, _ball)
|
25
|
-
return unless should_sample?('client')
|
26
|
-
|
27
29
|
tracing_id = create_tracing_id
|
28
30
|
|
29
31
|
# build & submit signal
|
30
32
|
host = call.instance.address
|
31
33
|
port = call.instance.port
|
32
34
|
|
35
|
+
# add tracing header
|
36
|
+
req = call.args[0]
|
37
|
+
req[ModuleApi::TRACE_ID_HEADER] = tracing_id
|
38
|
+
|
33
39
|
host += ':' + port.to_s if port != 80 && port != 443
|
34
40
|
|
35
|
-
|
36
|
-
signal.payload = Tracing::Signals::TracingClient::Payload.new(
|
41
|
+
HttpConnectionData.new(
|
37
42
|
transport: 'http',
|
38
43
|
host: host,
|
39
44
|
tracing_identifier: tracing_id
|
40
45
|
)
|
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
46
|
end
|
48
47
|
end
|
49
48
|
end
|
@@ -1,36 +1,37 @@
|
|
1
1
|
require 'sqreen/ecosystem/module_api'
|
2
2
|
require 'sqreen/ecosystem/module_api/event_listener'
|
3
|
-
require 'sqreen/ecosystem/module_api/
|
4
|
-
require 'sqreen/ecosystem/module_api/
|
5
|
-
require 'sqreen/ecosystem/tracing/signals/tracing_server'
|
3
|
+
require 'sqreen/ecosystem/module_api/message_producer'
|
4
|
+
require 'sqreen/ecosystem/module_api/tracing/server_data'
|
6
5
|
|
7
6
|
module Sqreen
|
8
7
|
module Ecosystem
|
9
8
|
module Http
|
10
9
|
class RackRequest
|
10
|
+
class HttpServerData
|
11
|
+
include ModuleApi::Tracing::ServerData
|
12
|
+
end
|
13
|
+
|
11
14
|
include ModuleApi::EventListener
|
12
|
-
include ModuleApi::
|
13
|
-
include ModuleApi::SignalProducer
|
15
|
+
include ModuleApi::MessageProducer
|
14
16
|
|
15
17
|
def setup
|
16
|
-
|
18
|
+
advice = wrap_for_interest(
|
19
|
+
ModuleApi::Tracing::ServerData,
|
20
|
+
&method(:handle_request)
|
21
|
+
)
|
22
|
+
on_request_start(&advice)
|
17
23
|
end
|
18
24
|
|
19
25
|
private
|
20
26
|
|
21
27
|
def handle_request(rack_request)
|
22
|
-
return unless should_sample?('server')
|
23
|
-
|
24
28
|
trace_id = rack_request.env[ModuleApi::TRACE_ID_ENV_KEY]
|
25
29
|
|
26
|
-
|
27
|
-
signal.payload = Tracing::Signals::TracingServer::Payload.new(
|
30
|
+
HttpServerData.new(
|
28
31
|
transport: 'http',
|
29
32
|
client_ip: rack_request.ip,
|
30
33
|
tracing_identifier: trace_id
|
31
34
|
)
|
32
|
-
|
33
|
-
submit_signal signal
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'sqreen/ecosystem/loggable'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
module ModuleApi
|
6
|
+
module MessageProducer
|
7
|
+
include Loggable
|
8
|
+
|
9
|
+
# method for ecosystem to inject the config
|
10
|
+
# @param [Sqreen::Ecosystem::TracingBroker]
|
11
|
+
attr_writer :tracing_broker
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def determine_interest(type, hints = {})
|
16
|
+
@tracing_broker.interested_consumers(type, hints)
|
17
|
+
end
|
18
|
+
|
19
|
+
def publish(data, interested)
|
20
|
+
@tracing_broker.publish(data, interested)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Convenience wrapper.
|
24
|
+
# Wraps a callback, skipping it if there is no interest in the type
|
25
|
+
# produced and submitting the return value as a message to the
|
26
|
+
# tracing broker
|
27
|
+
def wrap_for_interest(type, gen_hints = nil, &block)
|
28
|
+
raise ArgumentError, 'no block passed' if block.nil?
|
29
|
+
|
30
|
+
proc do |*args|
|
31
|
+
hints = gen_hints[*args] if gen_hints
|
32
|
+
interested = determine_interest(type, hints || {})
|
33
|
+
|
34
|
+
unless interested
|
35
|
+
logger.debug { "No interested consumers in #{type}" }
|
36
|
+
next
|
37
|
+
end
|
38
|
+
|
39
|
+
res = block[*args]
|
40
|
+
|
41
|
+
next if res.nil?
|
42
|
+
|
43
|
+
raise 'unexpected return type' unless res.is_a?(type)
|
44
|
+
|
45
|
+
@tracing_broker.publish(res, interested)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'sqreen/ecosystem/dispatch_table'
|
2
|
-
require 'sqreen/ecosystem/module_api/transaction_storage'
|
3
2
|
|
4
3
|
module Sqreen
|
5
4
|
module Ecosystem
|
6
5
|
module ModuleApi
|
7
6
|
module SignalProducer
|
8
|
-
include TransactionStorage
|
9
|
-
|
10
7
|
# for injection
|
8
|
+
# callable taking no arguments and generating a tracing id
|
11
9
|
attr_writer :tracing_id_producer
|
12
10
|
|
13
11
|
private
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'sqreen/ecosystem/module_api/signal_producer'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
module ModuleApi
|
6
|
+
module Tracing
|
7
|
+
include SignalProducer
|
8
|
+
|
9
|
+
def self.included(mod)
|
10
|
+
mod.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
private
|
15
|
+
|
16
|
+
# @param [Module] type The type the including module is interested in
|
17
|
+
def consumes(type)
|
18
|
+
@consumes = type
|
19
|
+
end
|
20
|
+
|
21
|
+
# A fixed (non-virtual) scope for this tracing module
|
22
|
+
# @param [String] scope
|
23
|
+
def fixed_scope(scope)
|
24
|
+
@fixed_scope = scope
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def consumed_type
|
29
|
+
self.class.instance_variable_get(:@consumes) \
|
30
|
+
|| raise('@consumes not specified')
|
31
|
+
end
|
32
|
+
|
33
|
+
def scope(_hints = {})
|
34
|
+
self.class.instance_variable_get(:@fixed_scope) \
|
35
|
+
|| raise('@fixed_scope not set')
|
36
|
+
end
|
37
|
+
|
38
|
+
# including class must implement it
|
39
|
+
def receive(_data)
|
40
|
+
raise NotImplementedError
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'sqreen/ecosystem/util/call_writers_from_init'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
module ModuleApi
|
6
|
+
module Tracing
|
7
|
+
# The data the tracing module needs in order to populate
|
8
|
+
# +Sqreen::Ecosystem::Tracing::Signals::TracingClient::Payload+
|
9
|
+
#
|
10
|
+
# Signals are not produced by the data producers (transport)
|
11
|
+
# because of superior orders, as the only current use of this
|
12
|
+
# data is to generate signals.
|
13
|
+
module ClientData
|
14
|
+
include Util::CallWritersFromInit
|
15
|
+
|
16
|
+
# @return [Symbol]
|
17
|
+
attr_accessor :transport
|
18
|
+
|
19
|
+
# @return [String]
|
20
|
+
attr_accessor :host
|
21
|
+
|
22
|
+
# @return [String]
|
23
|
+
attr_accessor :ip
|
24
|
+
|
25
|
+
# @return [String]
|
26
|
+
attr_accessor :tracing_identifier
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'sqreen/ecosystem/util/call_writers_from_init'
|
2
|
+
|
3
|
+
module Sqreen
|
4
|
+
module Ecosystem
|
5
|
+
module ModuleApi
|
6
|
+
module Tracing
|
7
|
+
# The data the tracing module needs in order to populate
|
8
|
+
# +Sqreen::Ecosystem::Tracing::Signals::TracingServer::Payload+
|
9
|
+
module ServerData
|
10
|
+
include Util::CallWritersFromInit
|
11
|
+
|
12
|
+
# @return [Symbol]
|
13
|
+
attr_accessor :transport
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
attr_accessor :client_ip
|
17
|
+
|
18
|
+
# @return [Array<String>]
|
19
|
+
attr_accessor :previous_hops
|
20
|
+
|
21
|
+
# @return [String]
|
22
|
+
attr_accessor :tracing_identifier
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -16,6 +16,7 @@ module Sqreen
|
|
16
16
|
def init_all
|
17
17
|
logger.info { "Initializing #{@mods.size} ecosystem modules" }
|
18
18
|
each_module do |mod|
|
19
|
+
next unless mod.respond_to? :setup
|
19
20
|
logger.debug { "Initializing module with type #{mod.class}" }
|
20
21
|
mod.setup
|
21
22
|
end
|
@@ -34,6 +35,10 @@ module Sqreen
|
|
34
35
|
selected_mods.each
|
35
36
|
end
|
36
37
|
end
|
38
|
+
|
39
|
+
def module_subset(type)
|
40
|
+
each_module(type).to_a
|
41
|
+
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
@@ -1,33 +1,41 @@
|
|
1
|
-
require 'sqreen/ecosystem/
|
2
|
-
require 'sqreen/ecosystem/module_api/
|
1
|
+
require 'sqreen/ecosystem/module_api'
|
2
|
+
require 'sqreen/ecosystem/module_api/instrumentation'
|
3
|
+
require 'sqreen/ecosystem/module_api/message_producer'
|
4
|
+
require 'sqreen/ecosystem/module_api/tracing_id_generation'
|
5
|
+
require 'sqreen/ecosystem/module_api/tracing/client_data'
|
3
6
|
|
4
7
|
module Sqreen
|
5
8
|
module Ecosystem
|
6
9
|
module Redis
|
7
10
|
class RedisConnection
|
8
|
-
|
9
|
-
|
11
|
+
class RedisConnectionData
|
12
|
+
include ModuleApi::Tracing::ClientData
|
13
|
+
|
14
|
+
attr_accessor :port
|
15
|
+
end
|
16
|
+
|
10
17
|
include ModuleApi::Instrumentation
|
18
|
+
include ModuleApi::MessageProducer
|
19
|
+
include ModuleApi::TracingIdGeneration
|
11
20
|
|
12
21
|
def setup
|
22
|
+
advice = wrap_for_interest(ModuleApi::Tracing::ClientData, &method(:before_advice))
|
13
23
|
instrument 'Redis::Connection::TCPSocket#connect',
|
14
|
-
before:
|
24
|
+
before: advice
|
15
25
|
end
|
16
26
|
|
17
27
|
private
|
18
28
|
|
19
29
|
def before_advice
|
20
|
-
return unless should_sample?('client')
|
21
|
-
|
22
30
|
host = call.args[0]
|
23
31
|
port = call.args[1]
|
24
32
|
|
25
|
-
|
26
|
-
signal.payload = Sqreen::Kit::Signals::Specialized::TracingClient::Payload.new(
|
33
|
+
RedisConnectionData.new(
|
27
34
|
transport: 'redis',
|
28
|
-
host: host,
|
35
|
+
host: host,
|
36
|
+
port: port,
|
37
|
+
tracing_identifier: create_tracing_id
|
29
38
|
)
|
30
|
-
submit_signal signal
|
31
39
|
end
|
32
40
|
end
|
33
41
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'sqreen/ecosystem/tracing/signals/tracing_client'
|
2
|
+
require 'sqreen/ecosystem/module_api/tracing'
|
3
|
+
require 'sqreen/ecosystem/module_api/tracing/client_data'
|
4
|
+
|
5
|
+
module Sqreen
|
6
|
+
module Ecosystem
|
7
|
+
module Tracing
|
8
|
+
module Modules
|
9
|
+
class Client
|
10
|
+
include ModuleApi::Tracing
|
11
|
+
|
12
|
+
consumes ModuleApi::Tracing::ClientData
|
13
|
+
fixed_scope 'client'
|
14
|
+
|
15
|
+
# @param [Sqreen::Ecosystem::ModuleApi::Tracing::ClientData] data
|
16
|
+
def receive(data)
|
17
|
+
signal = Tracing::Signals::TracingClient.new
|
18
|
+
signal.payload = Tracing::Signals::TracingClient::Payload.new(
|
19
|
+
transport: data.transport,
|
20
|
+
host: data.host,
|
21
|
+
ip: data.ip,
|
22
|
+
tracing_identifier: data.tracing_identifier
|
23
|
+
)
|
24
|
+
|
25
|
+
submit_signal signal
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'sqreen/ecosystem/tracing/signals/tracing_server'
|
2
|
+
require 'sqreen/ecosystem/module_api/tracing'
|
3
|
+
require 'sqreen/ecosystem/module_api/tracing/server_data'
|
4
|
+
|
5
|
+
module Sqreen
|
6
|
+
module Ecosystem
|
7
|
+
module Tracing
|
8
|
+
module Modules
|
9
|
+
class Server
|
10
|
+
include ModuleApi::Tracing
|
11
|
+
|
12
|
+
consumes ModuleApi::Tracing::ServerData
|
13
|
+
fixed_scope 'server'
|
14
|
+
|
15
|
+
# @param [Sqreen::Ecosystem::ModuleApi::Tracing::ServerData] data
|
16
|
+
def receive(data)
|
17
|
+
signal = Tracing::Signals::TracingServer.new
|
18
|
+
signal.payload = Tracing::Signals::TracingServer::Payload.new(
|
19
|
+
transport: data.transport,
|
20
|
+
client_ip: data.client_ip,
|
21
|
+
tracing_identifier: data.tracing_identifier
|
22
|
+
)
|
23
|
+
|
24
|
+
submit_signal signal
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'sqreen/ecosystem/loggable'
|
2
|
+
require 'sqreen/ecosystem/exception_reporting'
|
3
|
+
|
4
|
+
module Sqreen
|
5
|
+
module Ecosystem
|
6
|
+
class TracingBroker
|
7
|
+
include Loggable
|
8
|
+
include ExceptionReporting
|
9
|
+
|
10
|
+
# Stores a lookup resolution so that lookup (incl. sampling) is done
|
11
|
+
# only once, not in the beginning of the producer code (when it asks
|
12
|
+
# whether it should proceed) and again once it delivers the data
|
13
|
+
ObserverLookup = Struct.new(:modules)
|
14
|
+
|
15
|
+
# @return [Sqreen::Ecosystem::Tracing::SamplingConfiguration]
|
16
|
+
attr_writer :sampling_configuration
|
17
|
+
|
18
|
+
# @param [Array<Sqreen::Ecosystem::ModuleApi::Tracing>] tracing_modules
|
19
|
+
def initialize(tracing_modules)
|
20
|
+
@sampling_configuration = nil
|
21
|
+
@type_to_subscribers = {}
|
22
|
+
tracing_modules.each do |mod|
|
23
|
+
consumed_type = mod.consumed_type
|
24
|
+
@type_to_subscribers[consumed_type] ||= []
|
25
|
+
@type_to_subscribers[consumed_type] << mod
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param [Object] data
|
30
|
+
# @param [Sqreen::Ecosystem::TracingBroker::ObserverLookup] prev_lookup
|
31
|
+
def publish(data, prev_lookup)
|
32
|
+
prev_lookup.modules.each do |mod|
|
33
|
+
mod_process_data mod, data
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [Module] data_type
|
38
|
+
# @param [Hash] _hints reserved for future use, e.g. virtual scopes
|
39
|
+
# @return [Sqreen::Ecosystem::TracingBroker::ObserverLookup]
|
40
|
+
def interested_consumers(data_type, _hints = {})
|
41
|
+
unless @sampling_configuration
|
42
|
+
logger.debug do
|
43
|
+
"Declaring no one is interested in #{data_type} " \
|
44
|
+
"because tracing hasn't been enabled yet"
|
45
|
+
end
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
# if we have several modules with the same scope, we
|
50
|
+
# should ask whether we should sample only once
|
51
|
+
scope_to_should_sample = Hash.new do |hash, scope|
|
52
|
+
result = @sampling_configuration.should_sample?(scope)
|
53
|
+
if result
|
54
|
+
logger.debug { "Will sample scope #{scope}. Sampling line: #{result}" }
|
55
|
+
else
|
56
|
+
logger.debug { "Will NOT sample scope #{scope}" }
|
57
|
+
end
|
58
|
+
|
59
|
+
hash[scope] = result
|
60
|
+
end
|
61
|
+
|
62
|
+
res = subscribers(data_type).select do |mod|
|
63
|
+
scope_to_should_sample[mod.scope]
|
64
|
+
end
|
65
|
+
|
66
|
+
res.empty? ? false : ObserverLookup.new(res)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# @param [Sqreen::Ecosystem::ModuleApi::Tracing] mod
|
72
|
+
def mod_process_data(mod, data)
|
73
|
+
mod.receive(data)
|
74
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
75
|
+
report_exception("Error invoking tracing module #{mod}", e)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @param [Module] data_type
|
79
|
+
# @return Array<Sqreen::Ecosystem::ModuleApi::Tracing>
|
80
|
+
def subscribers(data_type)
|
81
|
+
subscribers = @type_to_subscribers[data_type]
|
82
|
+
|
83
|
+
# None of the modules subscribes to data_type directly,
|
84
|
+
# but maybe they subscribe to one of the ancestors
|
85
|
+
# Cache this lookup
|
86
|
+
unless subscribers
|
87
|
+
subscribers = parents(data_type).inject([]) do |accum, type|
|
88
|
+
accum + (@type_to_subscribers[type] || [])
|
89
|
+
end
|
90
|
+
@type_to_subscribers[data_type] = subscribers
|
91
|
+
end
|
92
|
+
|
93
|
+
subscribers
|
94
|
+
end
|
95
|
+
|
96
|
+
def parents(type)
|
97
|
+
type.ancestors - Object.ancestors - [type]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -5,9 +5,9 @@ require 'sqreen/ecosystem/module_api/signal_producer'
|
|
5
5
|
module Sqreen
|
6
6
|
module Ecosystem
|
7
7
|
class TracingIdSetup
|
8
|
-
# @param [Sqreen::Ecosystem::
|
9
|
-
def initialize(
|
10
|
-
@
|
8
|
+
# @param [Array<Sqreen::Ecosystem::ModuleApi::SignalProducer>] signal_producer_modules
|
9
|
+
def initialize(signal_producer_modules)
|
10
|
+
@modules = signal_producer_modules
|
11
11
|
@tracing_id_prefix = nil
|
12
12
|
end
|
13
13
|
|
@@ -20,7 +20,7 @@ module Sqreen
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def inject_out_of_tx_tracing_id_gen
|
23
|
-
@
|
23
|
+
@modules.each do |mod|
|
24
24
|
mod.tracing_id_producer = method(:generate_tracing_id)
|
25
25
|
end
|
26
26
|
end
|
@@ -21,15 +21,20 @@ module Sqreen
|
|
21
21
|
@framework = framework
|
22
22
|
@queue = queue
|
23
23
|
@request_lifecycle = RequestLifecycleTracking.new
|
24
|
+
@online = false
|
24
25
|
end
|
25
26
|
|
26
27
|
def init
|
28
|
+
raise 'already initialized' if @online
|
29
|
+
|
27
30
|
setup_dispatch_table
|
28
31
|
Ecosystem.init
|
29
32
|
logger.info 'Ecosystem successfully initialized'
|
33
|
+
@online = true
|
30
34
|
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
31
35
|
logger.warn { "Error initializing Ecosystem: #{e.message}" }
|
32
36
|
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
37
|
+
Sqreen::RemoteException.record(e)
|
33
38
|
end
|
34
39
|
|
35
40
|
def disable
|
@@ -37,15 +42,21 @@ module Sqreen
|
|
37
42
|
end
|
38
43
|
|
39
44
|
def request_start(rack_request)
|
45
|
+
return unless @online
|
46
|
+
|
40
47
|
Ecosystem.start_transaction
|
41
48
|
@request_lifecycle.notify_request_start(rack_request)
|
42
49
|
end
|
43
50
|
|
44
51
|
def request_end
|
52
|
+
return unless @online
|
53
|
+
|
45
54
|
Ecosystem.end_transaction
|
46
55
|
end
|
47
56
|
|
48
57
|
def handle_tracing_command(trace_id_prefix, scopes_config)
|
58
|
+
return unless @online
|
59
|
+
|
49
60
|
Ecosystem.configure_sampling(trace_id_prefix, scopes_config)
|
50
61
|
end
|
51
62
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'sqreen/events/remote_exception'
|
1
2
|
require 'sqreen/log/loggable'
|
2
3
|
|
3
4
|
module Sqreen
|
@@ -44,6 +45,7 @@ module Sqreen
|
|
44
45
|
cb.call(rack_req)
|
45
46
|
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
46
47
|
logger.warn { "Error calling #{cb} on request start: #{e.message}" }
|
48
|
+
Sqreen::RemoteException.record(e)
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
data/lib/sqreen/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqreen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.21.0.
|
4
|
+
version: 1.21.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sqreen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqreen-backport
|
@@ -124,23 +124,32 @@ files:
|
|
124
124
|
- lib/sqreen/dependency/sinatra.rb
|
125
125
|
- lib/sqreen/ecosystem.rb
|
126
126
|
- lib/sqreen/ecosystem/dispatch_table.rb
|
127
|
+
- lib/sqreen/ecosystem/exception_reporting.rb
|
127
128
|
- lib/sqreen/ecosystem/http/net_http.rb
|
128
129
|
- lib/sqreen/ecosystem/http/rack_request.rb
|
129
130
|
- lib/sqreen/ecosystem/loggable.rb
|
130
131
|
- lib/sqreen/ecosystem/module_api.rb
|
131
132
|
- lib/sqreen/ecosystem/module_api/event_listener.rb
|
132
133
|
- lib/sqreen/ecosystem/module_api/instrumentation.rb
|
134
|
+
- lib/sqreen/ecosystem/module_api/message_producer.rb
|
133
135
|
- lib/sqreen/ecosystem/module_api/signal_producer.rb
|
134
|
-
- lib/sqreen/ecosystem/module_api/
|
136
|
+
- lib/sqreen/ecosystem/module_api/tracing.rb
|
137
|
+
- lib/sqreen/ecosystem/module_api/tracing/client_data.rb
|
138
|
+
- lib/sqreen/ecosystem/module_api/tracing/server_data.rb
|
139
|
+
- lib/sqreen/ecosystem/module_api/tracing_id_generation.rb
|
135
140
|
- lib/sqreen/ecosystem/module_api/transaction_storage.rb
|
136
141
|
- lib/sqreen/ecosystem/module_registry.rb
|
137
142
|
- lib/sqreen/ecosystem/redis/redis_connection.rb
|
143
|
+
- lib/sqreen/ecosystem/tracing/modules/client.rb
|
144
|
+
- lib/sqreen/ecosystem/tracing/modules/server.rb
|
138
145
|
- lib/sqreen/ecosystem/tracing/sampler.rb
|
139
146
|
- lib/sqreen/ecosystem/tracing/sampling_configuration.rb
|
140
147
|
- lib/sqreen/ecosystem/tracing/signals/tracing_client.rb
|
141
148
|
- lib/sqreen/ecosystem/tracing/signals/tracing_server.rb
|
149
|
+
- lib/sqreen/ecosystem/tracing_broker.rb
|
142
150
|
- lib/sqreen/ecosystem/tracing_id_setup.rb
|
143
151
|
- lib/sqreen/ecosystem/transaction_storage.rb
|
152
|
+
- lib/sqreen/ecosystem/util/call_writers_from_init.rb
|
144
153
|
- lib/sqreen/ecosystem_integration.rb
|
145
154
|
- lib/sqreen/ecosystem_integration/around_callbacks.rb
|
146
155
|
- lib/sqreen/ecosystem_integration/instrumentation_service.rb
|
@@ -1,34 +0,0 @@
|
|
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
|