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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -15
- data/lib/sqreen/condition_evaluator.rb +5 -6
- data/lib/sqreen/conditionable.rb +6 -24
- data/lib/sqreen/ecosystem.rb +29 -2
- data/lib/sqreen/ecosystem/databases/database_connection_data.rb +23 -0
- data/lib/sqreen/ecosystem/databases/mongo.rb +39 -0
- data/lib/sqreen/ecosystem/databases/mysql.rb +54 -0
- data/lib/sqreen/ecosystem/databases/postgres.rb +51 -0
- data/lib/sqreen/ecosystem/databases/redis.rb +36 -0
- data/lib/sqreen/ecosystem/exception_reporting.rb +4 -2
- data/lib/sqreen/ecosystem/messaging/bunny.rb +61 -0
- data/lib/sqreen/ecosystem/messaging/kafka.rb +70 -0
- data/lib/sqreen/ecosystem/messaging/kinesis.rb +66 -0
- data/lib/sqreen/ecosystem/messaging/sqs.rb +68 -0
- data/lib/sqreen/ecosystem/module_api/message_producer.rb +9 -3
- data/lib/sqreen/ecosystem/module_api/tracing/consumer_data.rb +13 -0
- data/lib/sqreen/ecosystem/module_api/tracing/messaging_data.rb +35 -0
- data/lib/sqreen/ecosystem/module_api/tracing/producer_data.rb +13 -0
- data/lib/sqreen/ecosystem/module_registry.rb +5 -1
- data/lib/sqreen/ecosystem/tracing/modules/client.rb +7 -3
- data/lib/sqreen/ecosystem/tracing/modules/consumer.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/modules/determine_ip.rb +28 -0
- data/lib/sqreen/ecosystem/tracing/modules/producer.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_consumer.rb +56 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_producer.rb +56 -0
- data/lib/sqreen/ecosystem_integration.rb +1 -7
- data/lib/sqreen/ecosystem_integration/around_callbacks.rb +10 -20
- data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +4 -8
- data/lib/sqreen/graft/call.rb +1 -21
- data/lib/sqreen/graft/hook.rb +75 -83
- data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +2 -0
- data/lib/sqreen/metrics.rb +0 -1
- data/lib/sqreen/rules/custom_error_cb.rb +1 -1
- data/lib/sqreen/rules/rule_cb.rb +2 -2
- data/lib/sqreen/runner.rb +12 -27
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/budget.rb +14 -3
- data/lib/sqreen/weave/legacy/instrumentation.rb +94 -145
- metadata +22 -9
- data/lib/sqreen/ecosystem/redis/redis_connection.rb +0 -43
- 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
|
-
|
44
|
-
|
45
|
-
|
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,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
|
@@ -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
|
-
|
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
|