sqreen 1.20.4 → 1.21.1
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/deliveries/batch.rb +8 -1
- data/lib/sqreen/dependency/detector.rb +11 -3
- data/lib/sqreen/dependency/new_relic.rb +10 -1
- data/lib/sqreen/ecosystem.rb +123 -0
- 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/dispatch_table.rb +43 -0
- data/lib/sqreen/ecosystem/exception_reporting.rb +28 -0
- data/lib/sqreen/ecosystem/http/net_http.rb +50 -0
- data/lib/sqreen/ecosystem/http/rack_request.rb +39 -0
- data/lib/sqreen/ecosystem/loggable.rb +13 -0
- 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.rb +30 -0
- data/lib/sqreen/ecosystem/module_api/event_listener.rb +18 -0
- data/lib/sqreen/ecosystem/module_api/instrumentation.rb +23 -0
- data/lib/sqreen/ecosystem/module_api/message_producer.rb +57 -0
- data/lib/sqreen/ecosystem/module_api/signal_producer.rb +24 -0
- 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/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_api/tracing/server_data.rb +27 -0
- data/lib/sqreen/ecosystem/module_api/tracing_id_generation.rb +16 -0
- data/lib/sqreen/ecosystem/module_api/transaction_storage.rb +71 -0
- data/lib/sqreen/ecosystem/module_registry.rb +48 -0
- data/lib/sqreen/ecosystem/tracing/modules/client.rb +35 -0
- 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/modules/server.rb +30 -0
- data/lib/sqreen/ecosystem/tracing/sampler.rb +160 -0
- data/lib/sqreen/ecosystem/tracing/sampling_configuration.rb +150 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_client.rb +53 -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/tracing/signals/tracing_server.rb +53 -0
- data/lib/sqreen/ecosystem/tracing_broker.rb +101 -0
- data/lib/sqreen/ecosystem/tracing_id_setup.rb +34 -0
- data/lib/sqreen/ecosystem/transaction_storage.rb +64 -0
- data/lib/sqreen/ecosystem/util/call_writers_from_init.rb +13 -0
- data/lib/sqreen/ecosystem_integration.rb +81 -0
- data/lib/sqreen/ecosystem_integration/around_callbacks.rb +89 -0
- data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +38 -0
- data/lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb +58 -0
- data/lib/sqreen/ecosystem_integration/signal_consumption.rb +35 -0
- data/lib/sqreen/frameworks/generic.rb +15 -1
- data/lib/sqreen/graft/call.rb +9 -0
- data/lib/sqreen/graft/hook.rb +5 -3
- data/lib/sqreen/graft/hook_point.rb +17 -10
- data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +2 -0
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +7 -1
- data/lib/sqreen/remote_command.rb +3 -0
- data/lib/sqreen/rules/custom_error_cb.rb +1 -1
- data/lib/sqreen/runner.rb +19 -5
- data/lib/sqreen/session.rb +2 -0
- data/lib/sqreen/signals/conversions.rb +6 -1
- data/lib/sqreen/version.rb +1 -1
- metadata +51 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6611caf7add24e05a248fce4026be48a4c47612335c5fc9a26c64c33cd0409e9
|
|
4
|
+
data.tar.gz: 8381eba611e37df32a8744848661bcf144eaffe00c818e306355508fe0267394
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65c820c306961ed812360c2c73a1f37396433238cff8fd79e2676132d7842eaa86d3555bf860d7c2f6fd465783f8c1aeb59100c94349b8c53588d83513265d2e
|
|
7
|
+
data.tar.gz: 38cda532df6f1037ac243c8cd5ccaecd708b880ff377d3fcbcecad329be184d40ec9f27deb61b69124be3d37ff74a16f88a7ab1032a6e6a0f6b5387645181027
|
data/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,8 @@ require 'sqreen/events/attack'
|
|
|
13
13
|
require 'sqreen/events/remote_exception'
|
|
14
14
|
require 'sqreen/mono_time'
|
|
15
15
|
require 'sqreen/deliveries/simple'
|
|
16
|
+
require 'sqreen/kit/signals/signal'
|
|
17
|
+
require 'sqreen/kit/signals/trace'
|
|
16
18
|
|
|
17
19
|
module Sqreen
|
|
18
20
|
module Deliveries
|
|
@@ -58,7 +60,7 @@ module Sqreen
|
|
|
58
60
|
def post_batch_needed?(event)
|
|
59
61
|
now = Sqreen.time
|
|
60
62
|
# do not use any? {} due to side effects inside block
|
|
61
|
-
event_keys(event).map do |key|
|
|
63
|
+
event_keys(event).uniq.map do |key|
|
|
62
64
|
was = @first_seen[key]
|
|
63
65
|
@first_seen[key] ||= now
|
|
64
66
|
was.nil? || current_batch.size > max_batch || now > (was + max_staleness)
|
|
@@ -86,6 +88,7 @@ module Sqreen
|
|
|
86
88
|
res += event.observed.fetch(:sdk, []).select { |e|
|
|
87
89
|
e[0] == :track
|
|
88
90
|
}.map { |e| "sdk-track".freeze }
|
|
91
|
+
res += event.observed.fetch(:signals, []).map { "signal".freeze }
|
|
89
92
|
return res
|
|
90
93
|
end
|
|
91
94
|
|
|
@@ -97,6 +100,10 @@ module Sqreen
|
|
|
97
100
|
"rex-#{event.klass}"
|
|
98
101
|
when Sqreen::AggregatedMetric
|
|
99
102
|
"agg-metric"
|
|
103
|
+
when Sqreen::Kit::Signals::Signal
|
|
104
|
+
"signal"
|
|
105
|
+
when Sqreen::Kit::Signals::Trace
|
|
106
|
+
"signal"
|
|
100
107
|
end
|
|
101
108
|
end
|
|
102
109
|
end
|
|
@@ -25,6 +25,14 @@ module Sqreen
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
def to_app_hook_strategy
|
|
29
|
+
if Sqreen::Dependency::NewRelic.bundled? || Sqreen::Dependency::NewRelic.required?
|
|
30
|
+
:chain
|
|
31
|
+
else
|
|
32
|
+
:prepend
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
28
36
|
def hook(&block)
|
|
29
37
|
Sqreen.log.debug "[#{Process.pid}] Startup command: #{$0}"
|
|
30
38
|
|
|
@@ -34,7 +42,7 @@ module Sqreen
|
|
|
34
42
|
Sqreen::Dependency::Rails.insert_sqreen_middlewares
|
|
35
43
|
end if Sqreen::Dependency::Rails.required?
|
|
36
44
|
|
|
37
|
-
Sqreen::Graft::Hook.add('Rack::Builder#to_app') do
|
|
45
|
+
Sqreen::Graft::Hook.add('Rack::Builder#to_app', to_app_hook_strategy) do
|
|
38
46
|
after do
|
|
39
47
|
Sqreen::Dependency::Rails.inspect_middlewares
|
|
40
48
|
end
|
|
@@ -48,7 +56,7 @@ module Sqreen
|
|
|
48
56
|
end
|
|
49
57
|
end.install if Sqreen::Dependency::Sinatra.required?
|
|
50
58
|
|
|
51
|
-
Sqreen::Graft::Hook.add('Rack::Builder#to_app') do
|
|
59
|
+
Sqreen::Graft::Hook.add('Rack::Builder#to_app', to_app_hook_strategy) do
|
|
52
60
|
after do |call|
|
|
53
61
|
builder = call.instance
|
|
54
62
|
|
|
@@ -58,7 +66,7 @@ module Sqreen
|
|
|
58
66
|
|
|
59
67
|
# ensure startup of thread in request handling processes
|
|
60
68
|
|
|
61
|
-
Sqreen::Graft::Hook.add('Rack::Builder#to_app') do
|
|
69
|
+
Sqreen::Graft::Hook.add('Rack::Builder#to_app', to_app_hook_strategy) do
|
|
62
70
|
after do |call|
|
|
63
71
|
callback = call.callback
|
|
64
72
|
|
|
@@ -8,8 +8,17 @@ module Sqreen
|
|
|
8
8
|
module NewRelic
|
|
9
9
|
module_function
|
|
10
10
|
|
|
11
|
+
def bundled?
|
|
12
|
+
defined?(Gem) && Gem.respond_to?(:loaded_specs) && !Gem.loaded_specs['newrelic_rpm'].nil?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def required?
|
|
16
|
+
Sqreen::Dependency.const_exist?('NewRelic::Agent::Agent')
|
|
17
|
+
end
|
|
18
|
+
|
|
11
19
|
def ignore_sqreen_exceptions
|
|
12
|
-
return unless
|
|
20
|
+
return unless required?
|
|
21
|
+
|
|
13
22
|
NewRelic::Agent::Agent.instance.error_collector.ignore(['Sqreen::AttackBlocked'])
|
|
14
23
|
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
|
15
24
|
Sqreen.log.warn "Failed ignoring AttackBlocked on NewRelic: #{e.inspect}"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'securerandom'
|
|
2
|
+
require 'sqreen/ecosystem/module_registry'
|
|
3
|
+
require 'sqreen/ecosystem/tracing/sampling_configuration'
|
|
4
|
+
require 'sqreen/ecosystem/transaction_storage'
|
|
5
|
+
require 'sqreen/ecosystem/tracing_broker'
|
|
6
|
+
require 'sqreen/ecosystem/tracing_id_setup'
|
|
7
|
+
require 'sqreen/ecosystem/module_api/message_producer'
|
|
8
|
+
require 'sqreen/ecosystem/module_api/tracing_id_generation'
|
|
9
|
+
require 'sqreen/ecosystem/module_api/tracing'
|
|
10
|
+
|
|
11
|
+
module Sqreen
|
|
12
|
+
# The API for the ecosystem client (together with the dispatch table)
|
|
13
|
+
module Ecosystem
|
|
14
|
+
class << self
|
|
15
|
+
def init(opts = {})
|
|
16
|
+
@registry = ModuleRegistry.new
|
|
17
|
+
register_modules(opts[:modules])
|
|
18
|
+
@registry.init_all
|
|
19
|
+
|
|
20
|
+
# setup tracing generation
|
|
21
|
+
tracing_id_mods = @registry.module_subset(ModuleApi::TracingIdGeneration)
|
|
22
|
+
@tracing_id_setup = TracingIdSetup.new(tracing_id_mods)
|
|
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
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def reset
|
|
39
|
+
instance_variables.each do |ia|
|
|
40
|
+
instance_variable_set(ia, nil)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# To be called by the Ecosystem client when a new transaction
|
|
45
|
+
# (generally: request) is started
|
|
46
|
+
# In the future, it's intended that request end/start detection be handled
|
|
47
|
+
# by the Ecosystem itself, so control will flow in the other direction,
|
|
48
|
+
# from the ecosystem to its client
|
|
49
|
+
def start_transaction
|
|
50
|
+
TransactionStorage.create_thread_local
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def end_transaction
|
|
54
|
+
TransactionStorage.destroy_thread_local
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @param [String] tracing_id_prefix
|
|
58
|
+
# @param [Array<Hash{String=>Object}>] sampling_config
|
|
59
|
+
def configure_sampling(tracing_id_prefix, sampling_config)
|
|
60
|
+
@tracing_id_setup.tracing_id_prefix = tracing_id_prefix
|
|
61
|
+
built_samp_cfg = Tracing::SamplingConfiguration.new(sampling_config)
|
|
62
|
+
@tracing_broker.sampling_configuration = built_samp_cfg
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def register_modules(modules)
|
|
68
|
+
return register_all_modules unless modules
|
|
69
|
+
|
|
70
|
+
modules.each { |mod| register mod }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def register_all_modules
|
|
74
|
+
# replace with something more magical?
|
|
75
|
+
require_relative 'ecosystem/http/rack_request'
|
|
76
|
+
register Http::RackRequest.new
|
|
77
|
+
|
|
78
|
+
require_relative 'ecosystem/http/net_http'
|
|
79
|
+
register Http::NetHttp.new
|
|
80
|
+
|
|
81
|
+
require_relative 'ecosystem/databases/postgres'
|
|
82
|
+
register Databases::Postgres.new
|
|
83
|
+
|
|
84
|
+
require_relative 'ecosystem/databases/mysql'
|
|
85
|
+
register Databases::Mysql.new
|
|
86
|
+
|
|
87
|
+
require_relative 'ecosystem/databases/mongo'
|
|
88
|
+
register Databases::Mongo.new
|
|
89
|
+
|
|
90
|
+
require_relative 'ecosystem/databases/redis'
|
|
91
|
+
register Databases::Redis.new
|
|
92
|
+
|
|
93
|
+
require_relative 'ecosystem/messaging/sqs'
|
|
94
|
+
register Messaging::Sqs.new
|
|
95
|
+
|
|
96
|
+
require_relative 'ecosystem/messaging/kinesis'
|
|
97
|
+
register Messaging::Kinesis.new
|
|
98
|
+
|
|
99
|
+
require_relative 'ecosystem/messaging/bunny'
|
|
100
|
+
register Messaging::Bunny.new
|
|
101
|
+
|
|
102
|
+
require_relative 'ecosystem/messaging/kafka'
|
|
103
|
+
register Messaging::Kafka.new
|
|
104
|
+
|
|
105
|
+
require_relative 'ecosystem/tracing/modules/client'
|
|
106
|
+
register Tracing::Modules::Client.new
|
|
107
|
+
|
|
108
|
+
require_relative 'ecosystem/tracing/modules/server'
|
|
109
|
+
register Tracing::Modules::Server.new
|
|
110
|
+
|
|
111
|
+
require_relative 'ecosystem/tracing/modules/producer'
|
|
112
|
+
register Tracing::Modules::Producer.new
|
|
113
|
+
|
|
114
|
+
require_relative 'ecosystem/tracing/modules/consumer'
|
|
115
|
+
register Tracing::Modules::Consumer.new
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def register(mod)
|
|
119
|
+
@registry.register mod
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'sqreen/ecosystem/module_api/tracing/client_data'
|
|
2
|
+
|
|
3
|
+
module Sqreen
|
|
4
|
+
module Ecosystem
|
|
5
|
+
module Databases
|
|
6
|
+
class DatabaseConnectionData
|
|
7
|
+
include ModuleApi::Tracing::ClientData
|
|
8
|
+
|
|
9
|
+
# @return [Integer]
|
|
10
|
+
attr_accessor :port
|
|
11
|
+
|
|
12
|
+
# @return [String]
|
|
13
|
+
attr_accessor :unix_socket
|
|
14
|
+
|
|
15
|
+
# @return [String]
|
|
16
|
+
attr_accessor :username
|
|
17
|
+
|
|
18
|
+
# @return [String]
|
|
19
|
+
attr_accessor :db
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
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/databases/database_connection_data'
|
|
5
|
+
|
|
6
|
+
module Sqreen
|
|
7
|
+
module Ecosystem
|
|
8
|
+
module Databases
|
|
9
|
+
class Mongo
|
|
10
|
+
include ModuleApi::Instrumentation
|
|
11
|
+
include ModuleApi::MessageProducer
|
|
12
|
+
|
|
13
|
+
def setup
|
|
14
|
+
advice = wrap_for_interest(DatabaseConnectionData, &method(:after_advice))
|
|
15
|
+
instrument 'Mongo::Client#initialize', after: advice
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# @param [Sqreen::Graft::CallbackCall] call
|
|
21
|
+
def after_advice(call, _ball)
|
|
22
|
+
return if call.raised
|
|
23
|
+
|
|
24
|
+
client = call.instance
|
|
25
|
+
server_addrs = client.cluster.servers.map(&:address)
|
|
26
|
+
|
|
27
|
+
server_addrs.map do |addr|
|
|
28
|
+
DatabaseConnectionData.new(
|
|
29
|
+
transport: :mongo,
|
|
30
|
+
host: addr.host,
|
|
31
|
+
port: addr.port,
|
|
32
|
+
db: client.database.name,
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
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'
|
|
6
|
+
|
|
7
|
+
module Sqreen
|
|
8
|
+
module Ecosystem
|
|
9
|
+
module Databases
|
|
10
|
+
class Mysql
|
|
11
|
+
include ModuleApi::Instrumentation
|
|
12
|
+
include ModuleApi::MessageProducer
|
|
13
|
+
|
|
14
|
+
def setup
|
|
15
|
+
advice = wrap_for_interest(DatabaseConnectionData, &method(:after_advice))
|
|
16
|
+
instrument 'Mysql2::Client#connect', after: advice
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
# instance is of type +Mysql2::Client+
|
|
22
|
+
# VALUE rb_mysql_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database,
|
|
23
|
+
# VALUE socket, VALUE flags, VALUE conn_attrs) {
|
|
24
|
+
# @param [Sqreen::Graft::CallbackCall]
|
|
25
|
+
def after_advice(call, _ball)
|
|
26
|
+
args = call.args
|
|
27
|
+
|
|
28
|
+
# build & submit signal
|
|
29
|
+
signal = DatabaseConnectionData.new(transport: :mysql)
|
|
30
|
+
|
|
31
|
+
user = args[0]
|
|
32
|
+
host = args[2]
|
|
33
|
+
port = args[3]
|
|
34
|
+
db = args[4]
|
|
35
|
+
socket = args[5]
|
|
36
|
+
|
|
37
|
+
if socket && !socket.empty?
|
|
38
|
+
signal.unix_socket = socket
|
|
39
|
+
signal.host = 'localhost'
|
|
40
|
+
signal.ip = '::1'
|
|
41
|
+
else
|
|
42
|
+
signal.host = host
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
signal.port = port if port != 0
|
|
46
|
+
signal.username = user
|
|
47
|
+
signal.db = db
|
|
48
|
+
|
|
49
|
+
signal
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
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/databases/database_connection_data'
|
|
5
|
+
|
|
6
|
+
module Sqreen
|
|
7
|
+
module Ecosystem
|
|
8
|
+
module Databases
|
|
9
|
+
class Postgres
|
|
10
|
+
include ModuleApi::Instrumentation
|
|
11
|
+
include ModuleApi::MessageProducer
|
|
12
|
+
|
|
13
|
+
def setup
|
|
14
|
+
advice = wrap_for_interest(DatabaseConnectionData, &method(:after_advice))
|
|
15
|
+
instrument 'PG::Connection#initialize', after: advice
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# instance is of type +PG::Connection+
|
|
21
|
+
# > c = PG::Connection.new(host: '172.17.0.2', password: 'mysecretpassword', user: 'postgres')
|
|
22
|
+
# => #<PG::Connection:0x000055b44d077d10>
|
|
23
|
+
# > %i{host port user db}.map { |m| c.send m }
|
|
24
|
+
# => ["172.17.0.2", 5432, "postgres", "postgres"]
|
|
25
|
+
def after_advice(call, _ball)
|
|
26
|
+
conn = call.instance
|
|
27
|
+
|
|
28
|
+
# build & submit signal
|
|
29
|
+
signal = DatabaseConnectionData.new(transport: :postgres)
|
|
30
|
+
|
|
31
|
+
host = conn.host
|
|
32
|
+
if host
|
|
33
|
+
if host.include?('/')
|
|
34
|
+
signal.unix_socket = host
|
|
35
|
+
signal.host = 'localhost'
|
|
36
|
+
signal.ip = '::1'
|
|
37
|
+
else
|
|
38
|
+
signal.host = host
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
signal.port = conn.port
|
|
43
|
+
signal.username = conn.user
|
|
44
|
+
signal.db = conn.db
|
|
45
|
+
|
|
46
|
+
signal
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
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/databases/database_connection_data'
|
|
5
|
+
|
|
6
|
+
module Sqreen
|
|
7
|
+
module Ecosystem
|
|
8
|
+
module Databases
|
|
9
|
+
class Redis
|
|
10
|
+
include ModuleApi::Instrumentation
|
|
11
|
+
include ModuleApi::MessageProducer
|
|
12
|
+
|
|
13
|
+
def setup
|
|
14
|
+
advice = wrap_for_interest(DatabaseConnectionData, &method(:after_advice))
|
|
15
|
+
instrument 'Redis#initialize', after: advice
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# @param [Sqreen::Graft::CallbackCall] call
|
|
21
|
+
def after_advice(call, _ball)
|
|
22
|
+
return if call.raised
|
|
23
|
+
|
|
24
|
+
conn = call.instance.connection
|
|
25
|
+
|
|
26
|
+
DatabaseConnectionData.new(
|
|
27
|
+
transport: :redis,
|
|
28
|
+
host: conn[:host],
|
|
29
|
+
port: conn[:port],
|
|
30
|
+
db: conn[:db].to_s,
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|