sqreen 1.21.0.beta1 → 1.21.0.beta2
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 +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
|