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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49a6c95ab34d19ae0f769e475ae67c2c3e4d19b17582ee09d8a6d231ac3d9150
4
- data.tar.gz: ad1ea7a80f3582ba90ffc6aa1cef7040459c56f65ea4712a023923b8bc7801e3
3
+ metadata.gz: e5b3d6fc37fd5d2431e622d302fd3f58d35dd64a3fc7abca741a84b213688025
4
+ data.tar.gz: a3443a3f1c95841af9deb7eb5f4a5ab8c47aabf6c6f42eeb902d828edd3ad91d
5
5
  SHA512:
6
- metadata.gz: 0da6438f20a00a84914db2bb06c24feab53e164feae1cb7d2af0b53afe24c5d5ea54a0cb68a8872a49aadedae4450de57e63da6a4f4a2ec21ac85eaa84c13acf
7
- data.tar.gz: 3e75918e810529674e10d693fd2a62c0eeeeecb18bac06a25fdd686d29c45d55333abb0feea790ec1d89e29ce71097bd1de16c2d31d98a6219e985d806793008
6
+ metadata.gz: 487d63ea8f4bc8c5d3da55dced0c8d458c6a6c7f218689027925d8f6ca2808fc4eda478e57ca67764edb8a049fb8fae60b552974ffa39dfaa0dcd15d31f34071
7
+ data.tar.gz: 23cf04763b76e95d421a36593c2b96d91aad0f40bc206fe8608606fad803a464d03518ac92b40e4c1bb667dbd163ba79c6380f605b1133270f65d66fb8314173
@@ -1,3 +1,11 @@
1
+ ## 1.21.0.beta2
2
+
3
+ * Improve transport and tracing internals
4
+
5
+ ## 1.21.0.beta1
6
+
7
+ * Add transport and tracing internals
8
+
1
9
  ## 1.20.1
2
10
 
3
11
  * Add fallback mechanisms when connecting to new Sqreen backend API domains
@@ -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/tracing_push_down'
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
- @tracing_id_setup = TracingIdSetup.new(@registry)
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
- inject_sampling_config(built_samp_cfg)
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/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'
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::SignalProducer
14
- include ModuleApi::TracingPushDown
16
+ include ModuleApi::MessageProducer
17
+ include ModuleApi::TracingIdGeneration
15
18
 
16
19
  def setup
17
- instrument 'Net::HTTP#request', before: method(:before_advice)
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
- signal = Tracing::Signals::TracingClient.new
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/signal_producer'
4
- require 'sqreen/ecosystem/module_api/tracing_push_down'
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::TracingPushDown
13
- include ModuleApi::SignalProducer
15
+ include ModuleApi::MessageProducer
14
16
 
15
17
  def setup
16
- on_request_start(&method(:handle_request))
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
- signal = Tracing::Signals::TracingServer.new
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
@@ -0,0 +1,16 @@
1
+ module Sqreen
2
+ module Ecosystem
3
+ module ModuleApi
4
+ module TracingIdGeneration
5
+ # for injection
6
+ attr_writer :tracing_id_producer
7
+
8
+ private
9
+
10
+ def create_tracing_id
11
+ @tracing_id_producer.call
12
+ end
13
+ end
14
+ end
15
+ end
16
+ 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/tracing/signals/tracing_client'
2
- require 'sqreen/ecosystem/module_api/signal_producer'
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
- include ModuleApi::SignalProducer
9
- include ModuleApi::TracingPushDown
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: method(:before_advice)
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
- signal = Sqreen::Kit::Signals::Specialized::TracingClient.new
26
- signal.payload = Sqreen::Kit::Signals::Specialized::TracingClient::Payload.new(
33
+ RedisConnectionData.new(
27
34
  transport: 'redis',
28
- host: host, port: port
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::ModuleRegistry] registry
9
- def initialize(registry)
10
- @registry = registry
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
- @registry.each_module(Sqreen::Ecosystem::ModuleApi::SignalProducer) do |mod|
23
+ @modules.each do |mod|
24
24
  mod.tracing_id_producer = method(:generate_tracing_id)
25
25
  end
26
26
  end
@@ -0,0 +1,13 @@
1
+ module Sqreen
2
+ module Ecosystem
3
+ module Util
4
+ module CallWritersFromInit
5
+ def initialize(values = {})
6
+ values.each do |attr, val|
7
+ public_send("#{attr}=", val)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ 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
@@ -4,5 +4,5 @@
4
4
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
5
5
 
6
6
  module Sqreen
7
- VERSION = '1.21.0.beta1'.freeze
7
+ VERSION = '1.21.0.beta2'.freeze
8
8
  end
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.beta1
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-06-29 00:00:00.000000000 Z
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/tracing_push_down.rb
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