mnemosyne-ruby 1.0.1 → 1.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +10 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +11 -0
- data/lib/mnemosyne/client.rb +11 -4
- data/lib/mnemosyne/configuration.rb +7 -5
- data/lib/mnemosyne/instrumenter.rb +19 -17
- data/lib/mnemosyne/middleware/acfs.rb +2 -2
- data/lib/mnemosyne/middleware/rack.rb +1 -10
- data/lib/mnemosyne/middleware/restify.rb +6 -7
- data/lib/mnemosyne/middleware/sidekiq.rb +39 -0
- data/lib/mnemosyne/probe.rb +0 -1
- data/lib/mnemosyne/probes/acfs/request.rb +0 -1
- data/lib/mnemosyne/probes/action_controller/process_action.rb +0 -1
- data/lib/mnemosyne/probes/action_controller/renderers.rb +0 -1
- data/lib/mnemosyne/probes/action_view/render_partial.rb +0 -1
- data/lib/mnemosyne/probes/action_view/render_template.rb +0 -1
- data/lib/mnemosyne/probes/active_record/query.rb +0 -1
- data/lib/mnemosyne/probes/grape/endpoint_render.rb +0 -1
- data/lib/mnemosyne/probes/grape/endpoint_run.rb +0 -1
- data/lib/mnemosyne/probes/grape/endpoint_run_filters.rb +0 -1
- data/lib/mnemosyne/probes/mnemosyne/tracer.rb +0 -1
- data/lib/mnemosyne/probes/msgr/client.rb +42 -0
- data/lib/mnemosyne/probes/msgr/consumer.rb +70 -0
- data/lib/mnemosyne/probes/responder/respond.rb +0 -1
- data/lib/mnemosyne/probes/sidekiq/client.rb +44 -0
- data/lib/mnemosyne/probes/sidekiq/server.rb +23 -0
- data/lib/mnemosyne/probes.rb +7 -61
- data/lib/mnemosyne/registry.rb +87 -0
- data/lib/mnemosyne/span.rb +15 -2
- data/lib/mnemosyne/trace.rb +3 -3
- data/lib/mnemosyne/version.rb +3 -3
- data/lib/mnemosyne.rb +5 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99dce4e5dc6cc2a267e8189e7d02bec8bc06beae
|
4
|
+
data.tar.gz: 0b5f1bf920009d85c5147ee52a2fdbf6fe313ce9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77e0cd8aad0ccc076168d44f433a9dee967d7d426807fd5d8870892888523ddbe046fa5d9f3e980050abb1a3d844f7fe7d82a101a470ad160e25089925ed047b
|
7
|
+
data.tar.gz: da9ad5a98a9cfded7a8358dd18f62132e238b501d82264d6b9ed04d748206814613fa1c0973cf7b484cc080a50b38e6269ff8e7d60b055910dc4500f82891be3
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -46,5 +46,15 @@ Metrics/LineLength:
|
|
46
46
|
Exclude:
|
47
47
|
- 'mnemosyne.gemspec'
|
48
48
|
|
49
|
+
Metrics/BlockLength:
|
50
|
+
Exclude:
|
51
|
+
- 'spec/**/*'
|
52
|
+
|
53
|
+
Metrics/ParameterLists:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
Metrics/MethodLength:
|
57
|
+
Enabled: false
|
58
|
+
|
49
59
|
Style/Documentation:
|
50
60
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.1.0
|
4
|
+
|
5
|
+
* Add msgr server & client instrumentation
|
6
|
+
* Add sidekiq client instrumentation
|
7
|
+
* Add sidekiq server instrumentation
|
8
|
+
* Add acfs request parameter tracing
|
9
|
+
|
3
10
|
## 1.0.1
|
4
11
|
|
5
12
|
* Fix issue with `enabled` configuration flag (#1)
|
data/Gemfile
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
source 'https://rubygems.org'
|
3
4
|
|
4
5
|
# Specify your gem's dependencies in mnemosyne.gemspec
|
5
6
|
gemspec
|
7
|
+
|
8
|
+
group :development, :test do
|
9
|
+
gem 'pry', require: false
|
10
|
+
gem 'pry-byebug', require: false
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem 'restify', require: false
|
15
|
+
gem 'sidekiq', require: false
|
16
|
+
end
|
data/lib/mnemosyne/client.rb
CHANGED
@@ -30,12 +30,19 @@ module Mnemosyne
|
|
30
30
|
@exchange ||= channel.topic @config.exchange, durable: true
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
|
33
|
+
def call(trace)
|
34
|
+
message = {
|
35
|
+
hostname: @config.hostname,
|
36
|
+
platform: @config.platform,
|
37
|
+
application: @config.application
|
38
|
+
}
|
35
39
|
|
36
|
-
|
37
|
-
|
40
|
+
# TODO: nest
|
41
|
+
message.merge! trace.serialize
|
42
|
+
|
43
|
+
exchange.publish JSON.dump(message),
|
38
44
|
persistent: true,
|
45
|
+
routing_key: 'mnemosyne.trace',
|
39
46
|
content_type: 'application/json'
|
40
47
|
end
|
41
48
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'socket'
|
3
4
|
require 'uri'
|
4
5
|
require 'cgi'
|
@@ -13,14 +14,15 @@ module Mnemosyne
|
|
13
14
|
attr_reader :logger
|
14
15
|
attr_reader :server
|
15
16
|
|
16
|
-
# rubocop:disable
|
17
|
-
def initialize(config)
|
17
|
+
def initialize(config) # rubocop:disable AbcSize
|
18
18
|
@platform = config.fetch('platform', 'default').to_s.strip.freeze
|
19
19
|
@application = config.fetch('application', nil).to_s.strip.freeze
|
20
20
|
@enabled = config.fetch('enabled', true)
|
21
|
-
@hostname = config.fetch('hostname') { default_hostname }.to_s.strip.freeze
|
22
21
|
@exchange = config.fetch('exchange', 'mnemosyne').to_s.freeze
|
23
|
-
@logger = config.fetch('logger') { Logger.new(
|
22
|
+
@logger = config.fetch('logger') { Logger.new(STDOUT) }
|
23
|
+
|
24
|
+
hostname = config.fetch('hostname') { default_hostname }
|
25
|
+
@hostname = hostname.to_s.strip.freeze
|
24
26
|
|
25
27
|
server = config.fetch('server', 'amqp://localhost')
|
26
28
|
@amqp = AMQ::Settings.configure(server).freeze
|
@@ -40,7 +42,7 @@ module Mnemosyne
|
|
40
42
|
Socket.gethostname
|
41
43
|
end
|
42
44
|
|
43
|
-
def make_amqp_uri(amqp)
|
45
|
+
def make_amqp_uri(amqp) # rubocop:disable AbcSize
|
44
46
|
uri = URI('')
|
45
47
|
|
46
48
|
uri.scheme = amqp[:scheme]
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'thread'
|
3
4
|
|
4
5
|
module Mnemosyne
|
@@ -8,13 +9,12 @@ module Mnemosyne
|
|
8
9
|
|
9
10
|
attr_reader :logger
|
10
11
|
|
11
|
-
def initialize(config)
|
12
|
+
def initialize(config:, client:, logger:)
|
13
|
+
@client = client
|
12
14
|
@config = config
|
15
|
+
@logger = logger
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
@logger = config.logger
|
17
|
-
@client = Client.new(config)
|
17
|
+
::Mnemosyne::Probes.activate!
|
18
18
|
|
19
19
|
logger.info 'Mnemosyne instrumenter started.'
|
20
20
|
end
|
@@ -27,7 +27,6 @@ module Mnemosyne
|
|
27
27
|
Thread.current[IDENT] = trace
|
28
28
|
end
|
29
29
|
|
30
|
-
# rubocop:disable Metrics/MethodLength
|
31
30
|
def trace(name, **kwargs)
|
32
31
|
if (trace = current_trace)
|
33
32
|
return yield trace if block_given?
|
@@ -47,18 +46,9 @@ module Mnemosyne
|
|
47
46
|
end
|
48
47
|
|
49
48
|
def submit(trace)
|
50
|
-
blob = {
|
51
|
-
hostname: @config.hostname,
|
52
|
-
platform: @config.platform,
|
53
|
-
application: @config.application,
|
54
|
-
}
|
55
|
-
|
56
|
-
# TODO: nest
|
57
|
-
blob.merge! trace.serialize
|
58
|
-
|
59
49
|
logger.debug { "Submit trace #{trace.uuid}" }
|
60
50
|
|
61
|
-
@client.
|
51
|
+
@client.call trace
|
62
52
|
end
|
63
53
|
|
64
54
|
def release(trace)
|
@@ -76,7 +66,10 @@ module Mnemosyne
|
|
76
66
|
MUTEX.synchronize do
|
77
67
|
return @instance if @instance
|
78
68
|
|
79
|
-
|
69
|
+
client = Client.new(config)
|
70
|
+
logger = config.logger
|
71
|
+
|
72
|
+
@instance = new(config: config, client: client, logger: logger)
|
80
73
|
end
|
81
74
|
rescue => err
|
82
75
|
message = "Unable to start instrumenter: #{err}"
|
@@ -90,6 +83,15 @@ module Mnemosyne
|
|
90
83
|
raise
|
91
84
|
end
|
92
85
|
|
86
|
+
def with(instrumenter)
|
87
|
+
old = instance
|
88
|
+
@instance = instrumenter
|
89
|
+
|
90
|
+
yield(instrumenter)
|
91
|
+
ensure
|
92
|
+
@instance = old
|
93
|
+
end
|
94
|
+
|
93
95
|
def trace(*args)
|
94
96
|
return unless (instrumenter = instance)
|
95
97
|
instrumenter.trace(*args)
|
@@ -7,7 +7,6 @@ module Mnemosyne
|
|
7
7
|
@app = app
|
8
8
|
end
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/MethodLength
|
11
10
|
def call(request)
|
12
11
|
trace = ::Mnemosyne::Instrumenter.current_trace
|
13
12
|
|
@@ -35,8 +34,9 @@ module Mnemosyne
|
|
35
34
|
|
36
35
|
def extract_meta(request)
|
37
36
|
{
|
37
|
+
url: request.url,
|
38
38
|
method: request.method,
|
39
|
-
|
39
|
+
params: request.params
|
40
40
|
}
|
41
41
|
end
|
42
42
|
end
|
@@ -54,7 +54,6 @@ module Mnemosyne
|
|
54
54
|
@app = app
|
55
55
|
end
|
56
56
|
|
57
|
-
# rubocop:disable Metrics/MethodLength
|
58
57
|
def call(env)
|
59
58
|
origin = env.fetch('HTTP_X_MNEMOSYNE_ORIGIN', false)
|
60
59
|
transaction = env.fetch('HTTP_X_MNEMOSYNE_TRANSACTION') do
|
@@ -74,20 +73,12 @@ module Mnemosyne
|
|
74
73
|
else
|
75
74
|
@app.call env
|
76
75
|
end
|
77
|
-
|
78
|
-
# rubocop:disable Lint/RescueException
|
79
|
-
rescue Exception
|
76
|
+
rescue Exception # rubocop:disable RescueException
|
80
77
|
trace.submit if trace
|
81
78
|
raise
|
82
79
|
ensure
|
83
80
|
trace.release if trace
|
84
81
|
end
|
85
82
|
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
def _uuid
|
90
|
-
::SecureRandom.uuid
|
91
|
-
end
|
92
83
|
end
|
93
84
|
end
|
@@ -3,10 +3,9 @@
|
|
3
3
|
module Mnemosyne
|
4
4
|
module Middleware
|
5
5
|
module Restify
|
6
|
-
# rubocop:disable Metrics/MethodLength
|
7
6
|
def call(request)
|
8
7
|
if (trace = ::Mnemosyne::Instrumenter.current_trace)
|
9
|
-
meta = {url: request.uri, method: request.method}
|
8
|
+
meta = {url: request.uri.to_s, method: request.method}
|
10
9
|
|
11
10
|
span = ::Mnemosyne::Span.new('external.http.restify', meta: meta)
|
12
11
|
span.start!
|
@@ -14,11 +13,11 @@ module Mnemosyne
|
|
14
13
|
request.headers['X-Mnemosyne-Transaction'] = trace.transaction
|
15
14
|
request.headers['X-Mnemosyne-Origin'] = span.uuid
|
16
15
|
|
17
|
-
super.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
super.tap do |x|
|
17
|
+
x.add_observer do |_, _response, _err|
|
18
|
+
span.finish!
|
19
|
+
trace << span
|
20
|
+
end
|
22
21
|
end
|
23
22
|
else
|
24
23
|
super
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mnemosyne
|
4
|
+
module Middleware
|
5
|
+
class Sidekiq
|
6
|
+
def call(worker, job, queue)
|
7
|
+
origin = job.delete('mnemosyne.origin') { false }
|
8
|
+
transaction = job.delete('mnemosyne.transaction') { uuid }
|
9
|
+
|
10
|
+
meta = {
|
11
|
+
raw: job,
|
12
|
+
queue: queue,
|
13
|
+
worker: worker.class.name,
|
14
|
+
arguments: job['args']
|
15
|
+
}
|
16
|
+
|
17
|
+
trace = ::Mnemosyne::Instrumenter.trace 'app.job.perform.sidekiq',
|
18
|
+
transaction: transaction,
|
19
|
+
origin: origin,
|
20
|
+
meta: meta
|
21
|
+
|
22
|
+
trace.start! if trace
|
23
|
+
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
if trace
|
27
|
+
trace.submit
|
28
|
+
trace.release
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def uuid
|
35
|
+
::SecureRandom.uuid
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/mnemosyne/probe.rb
CHANGED
@@ -13,7 +13,6 @@ module Mnemosyne
|
|
13
13
|
::Acfs::Runner.use ::Mnemosyne::Middleware::Acfs
|
14
14
|
end
|
15
15
|
|
16
|
-
# rubocop:disable Metrics/ParameterLists
|
17
16
|
def call(trace, _name, start, finish, _id, _payload)
|
18
17
|
start = ::Mnemosyne::Clock.to_tick(start)
|
19
18
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -7,7 +7,6 @@ module Mnemosyne
|
|
7
7
|
class Probe < ::Mnemosyne::Probe
|
8
8
|
subscribe 'process_action.action_controller'
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/ParameterLists
|
11
10
|
def call(trace, _name, start, finish, _id, payload)
|
12
11
|
start = ::Mnemosyne::Clock.to_tick(start)
|
13
12
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -13,7 +13,6 @@ module Mnemosyne
|
|
13
13
|
::ActionController::Base.prepend Instrumentation
|
14
14
|
end
|
15
15
|
|
16
|
-
# rubocop:disable Metrics/ParameterLists
|
17
16
|
def call(trace, _name, start, finish, _id, _payload)
|
18
17
|
start = ::Mnemosyne::Clock.to_tick(start)
|
19
18
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -7,7 +7,6 @@ module Mnemosyne
|
|
7
7
|
class Probe < ::Mnemosyne::Probe
|
8
8
|
subscribe 'render_partial.action_view'
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/ParameterLists
|
11
10
|
def call(trace, _name, start, finish, _id, payload)
|
12
11
|
start = ::Mnemosyne::Clock.to_tick(start)
|
13
12
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -7,7 +7,6 @@ module Mnemosyne
|
|
7
7
|
class Probe < ::Mnemosyne::Probe
|
8
8
|
subscribe 'render_template.action_view'
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/ParameterLists
|
11
10
|
def call(trace, _name, start, finish, _id, payload)
|
12
11
|
start = ::Mnemosyne::Clock.to_tick(start)
|
13
12
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -7,7 +7,6 @@ module Mnemosyne
|
|
7
7
|
class Probe < ::Mnemosyne::Probe
|
8
8
|
subscribe 'endpoint_render.grape'
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/ParameterLists
|
11
10
|
def call(trace, _name, start, finish, _id, payload)
|
12
11
|
start = ::Mnemosyne::Clock.to_tick(start)
|
13
12
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -7,7 +7,6 @@ module Mnemosyne
|
|
7
7
|
class Probe < ::Mnemosyne::Probe
|
8
8
|
subscribe 'endpoint_run.grape'
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/ParameterLists
|
11
10
|
def call(trace, _name, start, finish, _id, payload)
|
12
11
|
start = ::Mnemosyne::Clock.to_tick(start)
|
13
12
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -7,7 +7,6 @@ module Mnemosyne
|
|
7
7
|
class Probe < ::Mnemosyne::Probe
|
8
8
|
subscribe 'endpoint_run_filters.grape'
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/ParameterLists
|
11
10
|
def call(trace, _name, start, finish, _id, payload)
|
12
11
|
start = ::Mnemosyne::Clock.to_tick(start)
|
13
12
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -7,7 +7,6 @@ module Mnemosyne
|
|
7
7
|
class Probe < ::Mnemosyne::Probe
|
8
8
|
subscribe 'trace.mnemosyne'
|
9
9
|
|
10
|
-
# rubocop:disable Metrics/ParameterLists
|
11
10
|
def call(trace, _name, start, finish, _id, payload)
|
12
11
|
start = ::Mnemosyne::Clock.to_tick(start)
|
13
12
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mnemosyne
|
4
|
+
module Probes
|
5
|
+
module Msgr
|
6
|
+
module Client
|
7
|
+
NAME = 'external.publish.msgr'.freeze
|
8
|
+
|
9
|
+
class Probe < ::Mnemosyne::Probe
|
10
|
+
def setup
|
11
|
+
::Msgr::Client.send :prepend, Instrumentation
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Instrumentation
|
16
|
+
def publish(payload, **options)
|
17
|
+
if (trace = ::Mnemosyne::Instrumenter.current_trace)
|
18
|
+
meta = {}
|
19
|
+
span = ::Mnemosyne::Span.new(NAME, meta: meta)
|
20
|
+
span.start!
|
21
|
+
|
22
|
+
options[:headers] ||= {}
|
23
|
+
options[:headers][:'mnemosyne.transaction'] = trace.transaction
|
24
|
+
options[:headers][:'mnemosyne.origin'] = span.uuid
|
25
|
+
|
26
|
+
begin
|
27
|
+
super
|
28
|
+
ensure
|
29
|
+
span.finish!
|
30
|
+
trace << span
|
31
|
+
end
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
register 'Msgr::Client', 'msgr/client', Msgr::Client::Probe.new
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mnemosyne
|
4
|
+
module Probes
|
5
|
+
module Msgr
|
6
|
+
module Consumer
|
7
|
+
NAME = 'app.messaging.receive.msgr'.freeze
|
8
|
+
|
9
|
+
class Probe < ::Mnemosyne::Probe
|
10
|
+
def setup
|
11
|
+
::Msgr::Consumer.send :prepend, Instrumentation
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Instrumentation
|
16
|
+
def dispatch(message) # rubocop:disable AbcSize
|
17
|
+
route = message.route
|
18
|
+
metadata = message.metadata
|
19
|
+
delivery_info = message.delivery_info
|
20
|
+
|
21
|
+
origin = metadata.headers.delete('mnemosyne.origin')
|
22
|
+
transaction = metadata.headers.delete('mnemosyne.transaction') do
|
23
|
+
::SecureRandom.uuid
|
24
|
+
end
|
25
|
+
|
26
|
+
trace = ::Mnemosyne::Instrumenter.trace NAME,
|
27
|
+
transaction: transaction,
|
28
|
+
origin: origin
|
29
|
+
|
30
|
+
if trace
|
31
|
+
trace.meta[:properties] = {
|
32
|
+
content_type: metadata.content_type,
|
33
|
+
priority: metadata.priority,
|
34
|
+
headers: metadata.headers,
|
35
|
+
type: metadata.type,
|
36
|
+
reply_to: metadata.reply_to,
|
37
|
+
correlation_id: metadata.correlation_id,
|
38
|
+
message_id: metadata.message_id,
|
39
|
+
app_id: metadata.app_id
|
40
|
+
}
|
41
|
+
|
42
|
+
trace.meta[:delivery_info] = {
|
43
|
+
consumer_tag: delivery_info.consumer_tag,
|
44
|
+
redelivered: delivery_info.redelivered?,
|
45
|
+
routing_key: delivery_info.routing_key,
|
46
|
+
exchange: delivery_info.exchange
|
47
|
+
}
|
48
|
+
|
49
|
+
trace.meta[:route] = {
|
50
|
+
consumer: route.consumer,
|
51
|
+
action: route.action
|
52
|
+
}
|
53
|
+
|
54
|
+
trace.start!
|
55
|
+
end
|
56
|
+
|
57
|
+
super
|
58
|
+
ensure
|
59
|
+
if trace
|
60
|
+
trace.submit
|
61
|
+
trace.release
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
register 'Msgr::Consumer', 'msgr/consumer', Msgr::Consumer::Probe.new
|
69
|
+
end
|
70
|
+
end
|
@@ -12,7 +12,6 @@ module Mnemosyne
|
|
12
12
|
::Mnemosyne::Probes::Responder::Respond::Instrumentation
|
13
13
|
end
|
14
14
|
|
15
|
-
# rubocop:disable Metrics/ParameterLists
|
16
15
|
def call(trace, _name, start, finish, _id, _payload)
|
17
16
|
start = ::Mnemosyne::Clock.to_tick(start)
|
18
17
|
finish = ::Mnemosyne::Clock.to_tick(finish)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mnemosyne
|
4
|
+
module Probes
|
5
|
+
module Sidekiq
|
6
|
+
module Client
|
7
|
+
class Probe < ::Mnemosyne::Probe
|
8
|
+
def setup
|
9
|
+
::Sidekiq.configure_client do |config|
|
10
|
+
config.client_middleware do |chain|
|
11
|
+
chain.prepend Middleware
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Middleware
|
18
|
+
def call(_worker, job, _queue, _redis)
|
19
|
+
if (trace = ::Mnemosyne::Instrumenter.current_trace)
|
20
|
+
meta = {
|
21
|
+
worker: job['class'],
|
22
|
+
queue: job['queue'],
|
23
|
+
arguments: job['args'],
|
24
|
+
raw: job.clone
|
25
|
+
}
|
26
|
+
|
27
|
+
span = ::Mnemosyne::Span.new('external.job.sidekiq', meta: meta)
|
28
|
+
span.finish! oneshot: true
|
29
|
+
|
30
|
+
job['mnemosyne.transaction'] = trace.transaction
|
31
|
+
job['mnemosyne.origin'] = span.uuid
|
32
|
+
|
33
|
+
trace << span
|
34
|
+
end
|
35
|
+
|
36
|
+
yield
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
register 'Sidekiq::Client', 'sidekiq/client', Sidekiq::Client::Probe.new
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mnemosyne
|
4
|
+
module Probes
|
5
|
+
module Sidekiq
|
6
|
+
module Server
|
7
|
+
class Probe < ::Mnemosyne::Probe
|
8
|
+
def setup
|
9
|
+
require 'mnemosyne/middleware/sidekiq'
|
10
|
+
|
11
|
+
::Sidekiq.configure_server do |config|
|
12
|
+
config.server_middleware do |chain|
|
13
|
+
chain.prepend ::Mnemosyne::Middleware::Sidekiq
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
register 'Sidekiq::Worker', 'sidekiq/worker', Sidekiq::Server::Probe.new
|
22
|
+
end
|
23
|
+
end
|
data/lib/mnemosyne/probes.rb
CHANGED
@@ -1,71 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'forwardable'
|
3
2
|
|
4
3
|
module Mnemosyne
|
5
4
|
module Probes
|
6
|
-
class Registration
|
7
|
-
extend ::Forwardable
|
8
|
-
|
9
|
-
attr_reader :class_name, :require_paths
|
10
|
-
|
11
|
-
def initialize(class_name, require_paths, probe)
|
12
|
-
@class_name = class_name
|
13
|
-
@require_paths = Array require_paths
|
14
|
-
@probe = probe
|
15
|
-
end
|
16
|
-
|
17
|
-
def installable?
|
18
|
-
return true unless class_name
|
19
|
-
|
20
|
-
::Mnemosyne::Probes.class_available? class_name
|
21
|
-
end
|
22
|
-
|
23
|
-
delegate install: :@probe
|
24
|
-
end
|
25
|
-
|
26
5
|
class << self
|
27
|
-
def class_available?(class_name)
|
28
|
-
Module.const_get(class_name).is_a? Class
|
29
|
-
rescue NameError
|
30
|
-
false
|
31
|
-
end
|
32
|
-
|
33
6
|
def register(*args)
|
34
|
-
|
35
|
-
|
36
|
-
if registration.installable?
|
37
|
-
registration.install
|
38
|
-
else
|
39
|
-
register_require_hook registration
|
40
|
-
end
|
7
|
+
registry.register(*args)
|
41
8
|
end
|
42
9
|
|
43
|
-
def
|
44
|
-
|
45
|
-
return unless registration
|
46
|
-
return unless registration.installable?
|
47
|
-
|
48
|
-
registration.install
|
49
|
-
|
50
|
-
unregister_require_hook registration
|
51
|
-
end
|
52
|
-
|
53
|
-
def register_require_hook(registration)
|
54
|
-
registration.require_paths.each do |path|
|
55
|
-
require_hooks[path] = registration
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def unregister_require_hook(registration)
|
60
|
-
registration.require_paths.each do |path|
|
61
|
-
require_hooks.delete path
|
62
|
-
end
|
10
|
+
def activate!
|
11
|
+
registry.activate!
|
63
12
|
end
|
64
13
|
|
65
14
|
private
|
66
15
|
|
67
|
-
def
|
68
|
-
@
|
16
|
+
def registry
|
17
|
+
@registry ||= ::Mnemosyne::Registry.new
|
69
18
|
end
|
70
19
|
end
|
71
20
|
end
|
@@ -77,12 +26,9 @@ module Kernel
|
|
77
26
|
def require(name)
|
78
27
|
ret = require_without_mn(name)
|
79
28
|
|
80
|
-
# rubocop:disable Lint/RescueException
|
81
29
|
begin
|
82
|
-
::Mnemosyne::Probes.
|
83
|
-
|
84
|
-
# rubocop:disable Lint/HandleExceptions
|
85
|
-
rescue Exception
|
30
|
+
::Mnemosyne::Probes.registry.required(name)
|
31
|
+
rescue Exception # rubocop:disable RescueException, HandleExceptions
|
86
32
|
end
|
87
33
|
|
88
34
|
ret
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Mnemosyne
|
6
|
+
class Registry
|
7
|
+
class Registration
|
8
|
+
extend ::Forwardable
|
9
|
+
|
10
|
+
attr_reader :class_name, :require_paths
|
11
|
+
|
12
|
+
def initialize(class_name, require_paths, probe)
|
13
|
+
@class_name = class_name
|
14
|
+
@require_paths = Array(require_paths)
|
15
|
+
@probe = probe
|
16
|
+
end
|
17
|
+
|
18
|
+
def installable?
|
19
|
+
return true unless class_name
|
20
|
+
|
21
|
+
begin
|
22
|
+
Module.const_get(class_name).is_a?(Class) ||
|
23
|
+
Module.const_get(class_name).is_a?(Module)
|
24
|
+
rescue NameError
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
delegate install: :@probe
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@registrations = []
|
34
|
+
@activated = false
|
35
|
+
@monitor = Monitor.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def activate!
|
39
|
+
return if activated?
|
40
|
+
|
41
|
+
@registrations.each(&method(:activate))
|
42
|
+
|
43
|
+
@activated = true
|
44
|
+
end
|
45
|
+
|
46
|
+
def activated?
|
47
|
+
@activated
|
48
|
+
end
|
49
|
+
|
50
|
+
def register(*args)
|
51
|
+
@registrations << (registration = Registration.new(*args))
|
52
|
+
|
53
|
+
activate(registration) if activated?
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
attr_reader :monitor
|
59
|
+
|
60
|
+
def activate(registration)
|
61
|
+
if registration.installable?
|
62
|
+
registration.install
|
63
|
+
else
|
64
|
+
monitor << registration
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Monitor
|
69
|
+
def initialize
|
70
|
+
@requirements = {}
|
71
|
+
end
|
72
|
+
|
73
|
+
def <<(registration)
|
74
|
+
registration.require_paths.each do |path|
|
75
|
+
@requirements[path] ||= []
|
76
|
+
@requirements[path] << registration
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def delete(registration)
|
81
|
+
registration.require_paths.each do |path|
|
82
|
+
@requirements[path].delete(registration)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/mnemosyne/span.rb
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
module Mnemosyne
|
4
4
|
class Span
|
5
|
-
attr_reader :uuid, :name, :start, :finish, :meta
|
5
|
+
attr_reader :uuid, :name, :start, :finish, :meta, :type
|
6
6
|
|
7
7
|
def initialize(name, start: false, finish: false, meta: {})
|
8
|
+
@type = nil
|
8
9
|
@name = name
|
9
10
|
@meta = meta
|
10
11
|
@uuid = ::SecureRandom.uuid
|
@@ -14,12 +15,23 @@ module Mnemosyne
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def start!
|
18
|
+
raise 'Already started' if @start
|
19
|
+
|
17
20
|
@start = ::Mnemosyne::Clock.tick
|
21
|
+
|
18
22
|
self
|
19
23
|
end
|
20
24
|
|
21
|
-
def finish!
|
25
|
+
def finish!(oneshot: false)
|
26
|
+
raise 'Already finished' if @finish
|
27
|
+
|
22
28
|
@finish = ::Mnemosyne::Clock.tick
|
29
|
+
|
30
|
+
if oneshot
|
31
|
+
@start = @finish unless @start
|
32
|
+
@type = :oneshot
|
33
|
+
end
|
34
|
+
|
23
35
|
self
|
24
36
|
end
|
25
37
|
|
@@ -27,6 +39,7 @@ module Mnemosyne
|
|
27
39
|
{
|
28
40
|
uuid: uuid,
|
29
41
|
name: name,
|
42
|
+
type: type,
|
30
43
|
start: start,
|
31
44
|
stop: finish,
|
32
45
|
meta: meta
|
data/lib/mnemosyne/trace.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
module Mnemosyne
|
4
4
|
class Trace < Span
|
5
|
-
attr_reader :uuid, :transaction, :origin
|
5
|
+
attr_reader :uuid, :transaction, :origin, :span
|
6
6
|
|
7
|
-
def initialize(instrumenter, name, transaction: nil, origin: nil)
|
8
|
-
super
|
7
|
+
def initialize(instrumenter, name, transaction: nil, origin: nil, **kwargs)
|
8
|
+
super(name, **kwargs)
|
9
9
|
|
10
10
|
@uuid = ::SecureRandom.uuid
|
11
11
|
@span = []
|
data/lib/mnemosyne/version.rb
CHANGED
data/lib/mnemosyne.rb
CHANGED
@@ -17,6 +17,7 @@ module Mnemosyne
|
|
17
17
|
require 'mnemosyne/client'
|
18
18
|
require 'mnemosyne/instrumenter'
|
19
19
|
|
20
|
+
require 'mnemosyne/registry'
|
20
21
|
require 'mnemosyne/probe'
|
21
22
|
require 'mnemosyne/probes'
|
22
23
|
|
@@ -32,8 +33,12 @@ module Mnemosyne
|
|
32
33
|
require 'mnemosyne/probes/grape/endpoint_render'
|
33
34
|
require 'mnemosyne/probes/grape/endpoint_run'
|
34
35
|
require 'mnemosyne/probes/grape/endpoint_run_filters'
|
36
|
+
require 'mnemosyne/probes/msgr/client'
|
37
|
+
require 'mnemosyne/probes/msgr/consumer'
|
35
38
|
require 'mnemosyne/probes/responder/respond'
|
36
39
|
require 'mnemosyne/probes/restify/base'
|
40
|
+
require 'mnemosyne/probes/sidekiq/client'
|
41
|
+
require 'mnemosyne/probes/sidekiq/server'
|
37
42
|
end
|
38
43
|
|
39
44
|
module Middleware
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mnemosyne-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.1.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Graichen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- lib/mnemosyne/middleware/acfs.rb
|
135
135
|
- lib/mnemosyne/middleware/rack.rb
|
136
136
|
- lib/mnemosyne/middleware/restify.rb
|
137
|
+
- lib/mnemosyne/middleware/sidekiq.rb
|
137
138
|
- lib/mnemosyne/probe.rb
|
138
139
|
- lib/mnemosyne/probes.rb
|
139
140
|
- lib/mnemosyne/probes/acfs/request.rb
|
@@ -146,9 +147,14 @@ files:
|
|
146
147
|
- lib/mnemosyne/probes/grape/endpoint_run.rb
|
147
148
|
- lib/mnemosyne/probes/grape/endpoint_run_filters.rb
|
148
149
|
- lib/mnemosyne/probes/mnemosyne/tracer.rb
|
150
|
+
- lib/mnemosyne/probes/msgr/client.rb
|
151
|
+
- lib/mnemosyne/probes/msgr/consumer.rb
|
149
152
|
- lib/mnemosyne/probes/responder/respond.rb
|
150
153
|
- lib/mnemosyne/probes/restify/base.rb
|
154
|
+
- lib/mnemosyne/probes/sidekiq/client.rb
|
155
|
+
- lib/mnemosyne/probes/sidekiq/server.rb
|
151
156
|
- lib/mnemosyne/railtie.rb
|
157
|
+
- lib/mnemosyne/registry.rb
|
152
158
|
- lib/mnemosyne/span.rb
|
153
159
|
- lib/mnemosyne/trace.rb
|
154
160
|
- lib/mnemosyne/version.rb
|
@@ -170,9 +176,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
170
176
|
version: '0'
|
171
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
178
|
requirements:
|
173
|
-
- - "
|
179
|
+
- - ">"
|
174
180
|
- !ruby/object:Gem::Version
|
175
|
-
version:
|
181
|
+
version: 1.3.1
|
176
182
|
requirements: []
|
177
183
|
rubyforge_project:
|
178
184
|
rubygems_version: 2.6.11
|