sqreen 1.21.0.beta3-java → 1.21.0-java

Sign up to get free protection for your applications and to get access to all the features.
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