mnemosyne-ruby 1.0.1 → 1.1.0.rc1
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/.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
|