sqreen 1.21.0.beta3-java → 1.21.0-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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -15
  3. data/lib/sqreen/condition_evaluator.rb +5 -6
  4. data/lib/sqreen/conditionable.rb +6 -24
  5. data/lib/sqreen/ecosystem.rb +29 -2
  6. data/lib/sqreen/ecosystem/databases/database_connection_data.rb +23 -0
  7. data/lib/sqreen/ecosystem/databases/mongo.rb +39 -0
  8. data/lib/sqreen/ecosystem/databases/mysql.rb +54 -0
  9. data/lib/sqreen/ecosystem/databases/postgres.rb +51 -0
  10. data/lib/sqreen/ecosystem/databases/redis.rb +36 -0
  11. data/lib/sqreen/ecosystem/exception_reporting.rb +4 -2
  12. data/lib/sqreen/ecosystem/messaging/bunny.rb +61 -0
  13. data/lib/sqreen/ecosystem/messaging/kafka.rb +70 -0
  14. data/lib/sqreen/ecosystem/messaging/kinesis.rb +66 -0
  15. data/lib/sqreen/ecosystem/messaging/sqs.rb +68 -0
  16. data/lib/sqreen/ecosystem/module_api/message_producer.rb +9 -3
  17. data/lib/sqreen/ecosystem/module_api/tracing/consumer_data.rb +13 -0
  18. data/lib/sqreen/ecosystem/module_api/tracing/messaging_data.rb +35 -0
  19. data/lib/sqreen/ecosystem/module_api/tracing/producer_data.rb +13 -0
  20. data/lib/sqreen/ecosystem/module_registry.rb +5 -1
  21. data/lib/sqreen/ecosystem/tracing/modules/client.rb +7 -3
  22. data/lib/sqreen/ecosystem/tracing/modules/consumer.rb +35 -0
  23. data/lib/sqreen/ecosystem/tracing/modules/determine_ip.rb +28 -0
  24. data/lib/sqreen/ecosystem/tracing/modules/producer.rb +35 -0
  25. data/lib/sqreen/ecosystem/tracing/signals/tracing_consumer.rb +56 -0
  26. data/lib/sqreen/ecosystem/tracing/signals/tracing_producer.rb +56 -0
  27. data/lib/sqreen/ecosystem_integration.rb +1 -7
  28. data/lib/sqreen/ecosystem_integration/around_callbacks.rb +10 -20
  29. data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +4 -8
  30. data/lib/sqreen/graft/call.rb +1 -21
  31. data/lib/sqreen/graft/hook.rb +75 -83
  32. data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +2 -0
  33. data/lib/sqreen/metrics.rb +0 -1
  34. data/lib/sqreen/rules/custom_error_cb.rb +1 -1
  35. data/lib/sqreen/rules/rule_cb.rb +2 -2
  36. data/lib/sqreen/runner.rb +12 -27
  37. data/lib/sqreen/version.rb +1 -1
  38. data/lib/sqreen/weave/budget.rb +14 -3
  39. data/lib/sqreen/weave/legacy/instrumentation.rb +94 -145
  40. metadata +22 -9
  41. data/lib/sqreen/ecosystem/redis/redis_connection.rb +0 -43
  42. data/lib/sqreen/metrics/req_detailed.rb +0 -41
@@ -0,0 +1,70 @@
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/consumer_data'
5
+ require 'sqreen/ecosystem/module_api/tracing/producer_data'
6
+
7
+ module Sqreen
8
+ module Ecosystem
9
+ module Messaging
10
+ class Kafka
11
+ include ModuleApi::Loggable
12
+ include ModuleApi::Instrumentation
13
+ include ModuleApi::MessageProducer
14
+
15
+ def setup
16
+ advice_send = wrap_for_interest(ModuleApi::Tracing::ProducerData, &method(:after_send))
17
+ advice_receive = wrap_for_interest(ModuleApi::Tracing::ConsumerData, &method(:after_receive))
18
+ instrument 'Kafka::Broker#produce', after: advice_send
19
+ instrument 'Kafka::Broker#fetch_messages', after: advice_receive
20
+ end
21
+
22
+ private
23
+
24
+ # @param [Sqreen::Graft::CallbackCall] call
25
+ def after_send(call, _ball)
26
+ return if call.raised
27
+ if call.args.length != 1
28
+ logger.info "Expected 1 arguments to Kafka::Broker#produce"
29
+ return
30
+ end
31
+ options = call.args.first
32
+ topics = options[:messages_for_topics].keys
33
+
34
+ create_signal_data(ModuleApi::Tracing::ProducerData,
35
+ call.instance,
36
+ topics)
37
+ end
38
+
39
+ # @param [Sqreen::Graft::CallbackCall] call
40
+ def after_receive(call, _ball)
41
+ return if call.raised
42
+ if call.args.length != 1
43
+ logger.info "Expected 1 arguments to Kafka::Broker#fetch_messages"
44
+ return
45
+ end
46
+ options = call.args.first
47
+ topics = options[:topics].keys
48
+
49
+ create_signal_data(ModuleApi::Tracing::ConsumerData,
50
+ call.instance,
51
+ topics)
52
+ end
53
+
54
+ # @param [Class] clazz
55
+ # @param [Kafka::Broker] broker
56
+ # @param [Array<String>] topics
57
+ def create_signal_data(clazz, broker, topics)
58
+ host = broker.instance_variable_get :@host
59
+ topics.map do |top|
60
+ clazz.new(
61
+ message_type: :kafka,
62
+ host: host,
63
+ topic: top,
64
+ )
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,66 @@
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/consumer_data'
5
+ require 'sqreen/ecosystem/module_api/tracing/producer_data'
6
+
7
+ # see https://aws.amazon.com/blogs/developer/announcing-amazon-kinesis-subscribetoshard-api-support-in-the-aws-sdk-for-ruby/
8
+ module Sqreen
9
+ module Ecosystem
10
+ module Messaging
11
+ class Kinesis
12
+ include ModuleApi::Loggable
13
+ include ModuleApi::Instrumentation
14
+ include ModuleApi::MessageProducer
15
+
16
+ def setup
17
+ advice_send = wrap_for_interest(ModuleApi::Tracing::ProducerData, &method(:after_send_advice))
18
+ advice_receive = wrap_for_interest(ModuleApi::Tracing::ConsumerData, &method(:after_receive_advice))
19
+ instrument 'Aws::Kinesis::Client#put_record', after: advice_send
20
+ instrument 'Aws::Kinesis::Client#put_records', after: advice_send
21
+ # more sophisticated usages (register_stream_consumer, possibly with AsyncClient)
22
+ # are not supported. They are more difficult to test, as kinesalite doesn't support them
23
+ instrument 'Aws::Kinesis::Client#get_shard_iterator', after: advice_receive
24
+ end
25
+
26
+ private
27
+
28
+ # @param [Sqreen::Graft::CallbackCall] call
29
+ def after_send_advice(call, _ball)
30
+ return if call.raised
31
+ unless call.args.length > 0 && call.args[0].is_a?(Hash)
32
+ logger.info "Unexpected arguments to put_record(s)"
33
+ return
34
+ end
35
+
36
+ create_signal(call.instance, call.args, ModuleApi::Tracing::ProducerData)
37
+ end
38
+
39
+ # @param [Sqreen::Graft::CallbackCall] call
40
+ def after_receive_advice(call, _ball)
41
+ return if call.raised
42
+ unless call.args.length > 0 && call.args[0].is_a?(Hash)
43
+ logger.info "Unexpected arguments to get_shared_iterator"
44
+ return
45
+ end
46
+
47
+ create_signal(call.instance, call.args, ModuleApi::Tracing::ConsumerData)
48
+ end
49
+
50
+ def create_signal(client, args, clazz)
51
+ hash = args[0]
52
+ stream_name = hash[:stream_name] || hash['stream_name']
53
+ return unless stream_name
54
+
55
+ endpoint = client.instance_variable_get(:@config).endpoint
56
+
57
+ clazz.new(
58
+ message_type: :'aws-kinesis',
59
+ host: endpoint.host,
60
+ topic: stream_name,
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,68 @@
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/consumer_data'
5
+ require 'sqreen/ecosystem/module_api/tracing/producer_data'
6
+
7
+ module Sqreen
8
+ module Ecosystem
9
+ module Messaging
10
+ class Sqs
11
+ include ModuleApi::Loggable
12
+ include ModuleApi::Instrumentation
13
+ include ModuleApi::MessageProducer
14
+
15
+ def setup
16
+ advice_send = wrap_for_interest(ModuleApi::Tracing::ProducerData, &method(:after_send_advice))
17
+ advice_receive = wrap_for_interest(ModuleApi::Tracing::ConsumerData, &method(:after_receive_advice))
18
+ instrument 'Aws::SQS::Client#send_message', after: advice_send
19
+ instrument 'Aws::SQS::Client#send_message_batch', after: advice_send
20
+ instrument 'Aws::SQS::Client#receive_message', after: advice_receive
21
+ end
22
+
23
+ private
24
+
25
+ # @param [Sqreen::Graft::CallbackCall] call
26
+ def after_send_advice(call, _ball)
27
+ return if call.raised
28
+ unless call.args.length > 0 && call.args[0].is_a?(Hash)
29
+ logger.info "Unexpected arguments to send_message(_batch)"
30
+ return
31
+ end
32
+
33
+ create_signal(call.args, ModuleApi::Tracing::ProducerData)
34
+ end
35
+
36
+ # @param [Sqreen::Graft::CallbackCall] call
37
+ def after_receive_advice(call, _ball)
38
+ return if call.raised
39
+ unless call.args.length > 0 && call.args[0].is_a?(Hash)
40
+ logger.info "Unexpected arguments to receive_message"
41
+ return
42
+ end
43
+
44
+ create_signal(call.args, ModuleApi::Tracing::ConsumerData)
45
+ end
46
+
47
+ def create_signal(args, clazz)
48
+ hash = args[0]
49
+ queue_url = hash[:queue_url] || hash['queue_url']
50
+ return unless queue_url
51
+
52
+ begin
53
+ uri = URI.parse(queue_url)
54
+ rescue URI::InvalidURIError
55
+ logger.info { "Invalid URI: #{uri}" }
56
+ return
57
+ end
58
+
59
+ clazz.new(
60
+ message_type: :'aws-sqs',
61
+ host: uri.host,
62
+ topic: ($1 if uri.path =~ /\A\/queue\/(?:[^\/]+\/)?([^\/]+)\z/),
63
+ )
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -40,9 +40,15 @@ module Sqreen
40
40
 
41
41
  next if res.nil?
42
42
 
43
- raise 'unexpected return type' unless res.is_a?(type)
44
-
45
- @tracing_broker.publish(res, interested)
43
+ if res.is_a?(Array)
44
+ res.each do |d|
45
+ raise "unexpected return type: #{d.class}" unless d.is_a?(type)
46
+ @tracing_broker.publish(d, interested)
47
+ end
48
+ else
49
+ raise "unexpected return type: #{res.class}" unless res.is_a?(type)
50
+ @tracing_broker.publish(res, interested)
51
+ end
46
52
  end
47
53
  end
48
54
  end
@@ -0,0 +1,13 @@
1
+ require 'sqreen/ecosystem/module_api/tracing/messaging_data'
2
+
3
+ module Sqreen
4
+ module Ecosystem
5
+ module ModuleApi
6
+ module Tracing
7
+ class ConsumerData
8
+ include MessagingData
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
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::TracingConsumer::Payload+ and
9
+ # +Sqreen::Ecosystem::Tracing::Signals::TracingProducer::Payload+.
10
+ #
11
+ # Signals are not produced by the data producers (transport)
12
+ # because of superior orders, as the only current use of this
13
+ # data is to generate signals.
14
+ module MessagingData
15
+ include Util::CallWritersFromInit
16
+
17
+ # @return [Symbol]
18
+ attr_accessor :message_type
19
+
20
+ # @return [String]
21
+ attr_accessor :host
22
+
23
+ # @return [String]
24
+ attr_accessor :ip
25
+
26
+ # @return [String]
27
+ attr_accessor :topic
28
+
29
+ # @return [String]
30
+ attr_accessor :tracing_identifier
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ require 'sqreen/ecosystem/module_api/tracing/messaging_data'
2
+
3
+ module Sqreen
4
+ module Ecosystem
5
+ module ModuleApi
6
+ module Tracing
7
+ class ProducerData
8
+ include MessagingData
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -16,7 +16,11 @@ 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
+ unless mod.respond_to? :setup
20
+ logger.debug { "Module with type #{mod.class} requires no initialization" }
21
+ next
22
+ end
23
+
20
24
  logger.debug { "Initializing module with type #{mod.class}" }
21
25
  mod.setup
22
26
  end
@@ -1,4 +1,7 @@
1
+ require 'sqreen/ecosystem/tracing/modules/determine_ip'
1
2
  require 'sqreen/ecosystem/tracing/signals/tracing_client'
3
+ require 'sqreen/ecosystem/loggable'
4
+ require 'sqreen/ecosystem/module_api'
2
5
  require 'sqreen/ecosystem/module_api/tracing'
3
6
  require 'sqreen/ecosystem/module_api/tracing/client_data'
4
7
 
@@ -8,18 +11,19 @@ module Sqreen
8
11
  module Modules
9
12
  class Client
10
13
  include ModuleApi::Tracing
14
+ include ModuleApi::TracingIdGeneration
15
+ include ModuleApi::Loggable
11
16
 
12
17
  consumes ModuleApi::Tracing::ClientData
13
18
  fixed_scope 'client'
14
19
 
15
- # @param [Sqreen::Ecosystem::ModuleApi::Tracing::ClientData] data
16
20
  def receive(data)
17
21
  signal = Tracing::Signals::TracingClient.new
18
22
  signal.payload = Tracing::Signals::TracingClient::Payload.new(
19
23
  transport: data.transport,
20
- host: data.host,
24
+ host: data.host || '',
21
25
  ip: data.ip,
22
- tracing_identifier: data.tracing_identifier
26
+ tracing_identifier: data.tracing_identifier || create_tracing_id
23
27
  )
24
28
 
25
29
  submit_signal signal
@@ -0,0 +1,35 @@
1
+ require 'sqreen/ecosystem/tracing/modules/determine_ip'
2
+ require 'sqreen/ecosystem/tracing/signals/tracing_consumer'
3
+ require 'sqreen/ecosystem/module_api'
4
+ require 'sqreen/ecosystem/module_api/tracing/consumer_data'
5
+
6
+ module Sqreen
7
+ module Ecosystem
8
+ module Tracing
9
+ module Modules
10
+ class Consumer
11
+ include ModuleApi::Tracing
12
+ include ModuleApi::TracingIdGeneration
13
+ include ModuleApi::Loggable
14
+
15
+ consumes ModuleApi::Tracing::ConsumerData
16
+ fixed_scope 'consumer'
17
+
18
+ # @param [ModuleApi::Tracing::ConsumerData] data
19
+ def receive(data)
20
+ signal = Tracing::Signals::TracingConsumer.new
21
+ signal.payload = Tracing::Signals::TracingConsumer::Payload.new(
22
+ message_type: data.message_type,
23
+ host: data.host || '',
24
+ ip: data.ip,
25
+ topic: data.topic,
26
+ tracing_identifier: data.tracing_identifier || create_tracing_id
27
+ )
28
+
29
+ submit_signal signal
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ require 'sqreen/ecosystem/module_api'
2
+
3
+ module Sqreen
4
+ module Ecosystem
5
+ module Tracing
6
+ module Modules
7
+ module DetermineIp
8
+ class << self
9
+ include ModuleApi::Loggable
10
+
11
+ def [](data)
12
+ return data.ip if data.ip
13
+
14
+ return nil unless data.host && !data.host.empty?
15
+
16
+ begin
17
+ IPSocket.getaddress data.host
18
+ rescue SocketError => e
19
+ logger.info { "Error resolving #{data.host}: #{e.message}" }
20
+ nil
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ require 'sqreen/ecosystem/tracing/modules/determine_ip'
2
+ require 'sqreen/ecosystem/tracing/signals/tracing_producer'
3
+ require 'sqreen/ecosystem/module_api'
4
+ require 'sqreen/ecosystem/module_api/tracing/producer_data'
5
+
6
+ module Sqreen
7
+ module Ecosystem
8
+ module Tracing
9
+ module Modules
10
+ class Producer
11
+ include ModuleApi::Tracing
12
+ include ModuleApi::TracingIdGeneration
13
+ include ModuleApi::Loggable
14
+
15
+ consumes ModuleApi::Tracing::ProducerData
16
+ fixed_scope 'producer'
17
+
18
+ # @param [ModuleApi::Tracing::ProducerData] data
19
+ def receive(data)
20
+ signal = Tracing::Signals::TracingProducer.new
21
+ signal.payload = Tracing::Signals::TracingProducer::Payload.new(
22
+ message_type: data.message_type,
23
+ host: data.host || '',
24
+ ip: data.ip,
25
+ topic: data.topic,
26
+ tracing_identifier: data.tracing_identifier || create_tracing_id
27
+ )
28
+
29
+ submit_signal signal
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,56 @@
1
+ require 'sqreen/kit/configuration'
2
+ require 'sqreen/kit/signals/point'
3
+ require 'sqreen/kit/signals/dto_helper'
4
+
5
+ # reference: https://github.com/sqreen/SignalsSchemas/blob/master/schemas/payload/tracing/consumer-2020-04-21/schema.cue
6
+
7
+ module Sqreen
8
+ module Ecosystem
9
+ module Tracing
10
+ module Signals
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ class Sqreen::Ecosystem::Tracing::Signals::TracingConsumer < Sqreen::Kit::Signals::Point
17
+ readonly_attrs :payload_schema, :source, :signal_name
18
+
19
+ def initialize(values = {})
20
+ self.payload_schema = Payload::SCHEMA_VERSION
21
+ self.source = Sqreen::Kit::Configuration.default_source
22
+ self.signal_name = 'tracing.consumer'
23
+ self.time = values[:time] || Time.now
24
+ super
25
+ end
26
+
27
+ def payload=(payload)
28
+ unless payload.is_a?(Payload)
29
+ raise ArgumentError, "Payload should be a #{Payload}"
30
+ end
31
+ super
32
+ end
33
+
34
+ class Payload
35
+ include Sqreen::Kit::Signals::DtoHelper
36
+
37
+ add_mandatory_attrs :message_type, :host, :tracing_identifier
38
+
39
+ SCHEMA_VERSION = 'tracing/consumer-2020-04-21'.freeze
40
+
41
+ # @return [Symbol]
42
+ attr_accessor :message_type
43
+
44
+ # @return [String]
45
+ attr_accessor :host
46
+
47
+ # @return [String]
48
+ attr_accessor :ip
49
+
50
+ # @return [String]
51
+ attr_accessor :topic
52
+
53
+ # @return [String]
54
+ attr_accessor :tracing_identifier
55
+ end
56
+ end