signalfx-rails-instrumentation 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -7
- data/.rubocop.yml +42 -0
- data/Appraisals +16 -13
- data/Gemfile +3 -7
- data/Gemfile.lock +173 -0
- data/LICENSE +2 -2
- data/README.md +118 -164
- data/Rakefile +6 -6
- data/bin/console +1 -1
- data/lib/rails/instrumentation.rb +60 -0
- data/lib/rails/instrumentation/patch.rb +38 -0
- data/lib/rails/instrumentation/subscriber.rb +45 -0
- data/lib/rails/instrumentation/subscribers/action_cable_subscriber.rb +69 -0
- data/lib/rails/instrumentation/subscribers/action_controller_subscriber.rb +172 -0
- data/lib/rails/instrumentation/subscribers/action_mailer_subscriber.rb +63 -0
- data/lib/rails/instrumentation/subscribers/action_view_subscriber.rb +48 -0
- data/lib/rails/instrumentation/subscribers/active_job_subscriber.rb +58 -0
- data/lib/rails/instrumentation/subscribers/active_record_subscriber.rb +45 -0
- data/lib/rails/instrumentation/subscribers/active_storage_subscriber.rb +91 -0
- data/lib/rails/instrumentation/subscribers/active_support_subscriber.rb +74 -0
- data/lib/rails/instrumentation/utils.rb +44 -0
- data/lib/rails/instrumentation/version.rb +5 -0
- data/rails-instrumentation.gemspec +32 -0
- metadata +54 -192
- data/.rspec +0 -2
- data/.ruby-version +0 -1
- data/.travis.yml +0 -25
- data/CHANGELOG.md +0 -47
- data/docker-compose.yml +0 -4
- data/gemfiles/.bundle/config +0 -2
- data/gemfiles/rails_32.gemfile +0 -11
- data/gemfiles/rails_4.gemfile +0 -10
- data/gemfiles/rails_40.gemfile +0 -10
- data/gemfiles/rails_41.gemfile +0 -10
- data/gemfiles/rails_42.gemfile +0 -10
- data/gemfiles/rails_5.gemfile +0 -10
- data/gemfiles/rails_50.gemfile +0 -10
- data/gemfiles/rails_51.gemfile +0 -10
- data/lib/rails-tracer.rb +0 -1
- data/lib/rails/action_controller/tracer.rb +0 -100
- data/lib/rails/action_view/tracer.rb +0 -105
- data/lib/rails/active_record/tracer.rb +0 -89
- data/lib/rails/active_support/cache/core_ext.rb +0 -11
- data/lib/rails/active_support/cache/dalli_tracer.rb +0 -106
- data/lib/rails/active_support/cache/manual_tracer.rb +0 -24
- data/lib/rails/active_support/cache/subscriber.rb +0 -62
- data/lib/rails/active_support/cache/tracer.rb +0 -55
- data/lib/rails/defer_notifications.rb +0 -78
- data/lib/rails/rack/tracer.rb +0 -61
- data/lib/rails/span_helpers.rb +0 -24
- data/lib/rails/tracer.rb +0 -38
- data/rails-tracer.gemspec +0 -44
data/.rspec
DELETED
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.4.2
|
data/.travis.yml
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
sudo: true
|
2
|
-
language: ruby
|
3
|
-
rvm:
|
4
|
-
- 2.2
|
5
|
-
- 2.3
|
6
|
-
- 2.4
|
7
|
-
gemfile:
|
8
|
-
- gemfiles/rails_32.gemfile
|
9
|
-
- gemfiles/rails_40.gemfile
|
10
|
-
- gemfiles/rails_41.gemfile
|
11
|
-
- gemfiles/rails_42.gemfile
|
12
|
-
- gemfiles/rails_50.gemfile
|
13
|
-
- gemfiles/rails_51.gemfile
|
14
|
-
matrix:
|
15
|
-
exclude:
|
16
|
-
- rvm: 2.4
|
17
|
-
gemfile: gemfiles/rails_32.gemfile
|
18
|
-
- rvm: 2.4
|
19
|
-
gemfile: gemfiles/rails_40.gemfile
|
20
|
-
- rvm: 2.4
|
21
|
-
gemfile: gemfiles/rails_41.gemfile
|
22
|
-
before_install:
|
23
|
-
- gem install bundler -v 1.15.3
|
24
|
-
services:
|
25
|
-
- memcached
|
data/CHANGELOG.md
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
## v0.5.0
|
2
|
-
|
3
|
-
* Expose global Rails::Tracer which instruments all sub-modules [#26](https://github.com/iaintshine/ruby-rails-tracer/pull/26)
|
4
|
-
* Allow to disable sub-tracers [#25](https://github.com/iaintshine/ruby-rails-tracer/pull/25)
|
5
|
-
* Support Evented and Timed subscribers in cache instrumentation [#24](https://github.com/iaintshine/ruby-rails-tracer/pull/24)
|
6
|
-
* Test and add support for multiple Rails versions - 3.2+ [#23](https://github.com/iaintshine/ruby-rails-tracer/pull/23)
|
7
|
-
* Development instructions update [#27](https://github.com/iaintshine/ruby-rails-tracer/pull/27)
|
8
|
-
|
9
|
-
## v0.4.3
|
10
|
-
|
11
|
-
* Handle instrumentation exceptions and mark spans as failed [#21](https://github.com/iaintshine/ruby-rails-tracer/pull/21)
|
12
|
-
|
13
|
-
## v0.4.2
|
14
|
-
|
15
|
-
* Test the gem with multiple Ruby versions 2.2+ [#20](https://github.com/iaintshine/ruby-rails-tracer/pull/20)
|
16
|
-
* Set explicit Ruby version requirement in gemspec.
|
17
|
-
|
18
|
-
## v0.4.1
|
19
|
-
|
20
|
-
* Use tracing matchers in tests [#19](https://github.com/iaintshine/ruby-rails-tracer/pull/19)
|
21
|
-
|
22
|
-
## v0.4.0
|
23
|
-
|
24
|
-
* Start maintaining CHANGELOG.md [#18](https://github.com/iaintshine/ruby-rails-tracer/pull/18)
|
25
|
-
* Auto enable tracing-logger when Dalli is auto-instrumented [#17](https://github.com/iaintshine/ruby-rails-tracer/pull/17)
|
26
|
-
* Introduce Dalli and ActiveSupport::Cache::DalliStore auto-instrumentation [#9](https://github.com/iaintshine/ruby-rails-tracer/pull/9)
|
27
|
-
* Introduce docker-compose with all required external dependencies.
|
28
|
-
|
29
|
-
## v0.3.0
|
30
|
-
|
31
|
-
* Introduce ActiveSupport::Cache auto-instrumentation [#4](https://github.com/iaintshine/ruby-rails-tracer/pull/4)
|
32
|
-
* Add ActiveRecord::Tracer tests for active span propagation
|
33
|
-
|
34
|
-
## v0.2.0
|
35
|
-
|
36
|
-
* Introduce ActiveRecord auto-instrumentation [#3](https://github.com/iaintshine/ruby-rails-tracer/pull/3)
|
37
|
-
* Add Rails test application to be used in specs
|
38
|
-
|
39
|
-
## v0.1.1
|
40
|
-
|
41
|
-
* Replace RecordingTracer with Test::Tracer [#6](https://github.com/iaintshine/ruby-rails-tracer/pull/6)
|
42
|
-
* README typo fix [#2](https://github.com/iaintshine/ruby-rails-tracer/pull/2)
|
43
|
-
|
44
|
-
## v0.1.0
|
45
|
-
|
46
|
-
* Initial release
|
47
|
-
* Introduced a rack middleware, to generate more informative operation names based on information supplied by ActionDispatch. [#1](https://github.com/iaintshine/ruby-rails-tracer/pull/1)
|
data/docker-compose.yml
DELETED
data/gemfiles/.bundle/config
DELETED
data/gemfiles/rails_32.gemfile
DELETED
data/gemfiles/rails_4.gemfile
DELETED
data/gemfiles/rails_40.gemfile
DELETED
data/gemfiles/rails_41.gemfile
DELETED
data/gemfiles/rails_42.gemfile
DELETED
data/gemfiles/rails_5.gemfile
DELETED
data/gemfiles/rails_50.gemfile
DELETED
data/gemfiles/rails_51.gemfile
DELETED
data/lib/rails-tracer.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'rails/tracer'
|
@@ -1,100 +0,0 @@
|
|
1
|
-
|
2
|
-
module ActionController
|
3
|
-
module Tracer
|
4
|
-
COMPONENT = "ActionController".freeze
|
5
|
-
|
6
|
-
class << self
|
7
|
-
def instrument(tracer: OpenTracing.global_tracer, active_span: nil)
|
8
|
-
@subscribers = []
|
9
|
-
@subscribers << ::ActiveSupport::Notifications.subscribe('start_processing.action_controller') do |*args|
|
10
|
-
ActionController::Tracer.start_processing(tracer: tracer, active_span: active_span, args: args)
|
11
|
-
end
|
12
|
-
@subscribers << ::ActiveSupport::Notifications.subscribe('process_action.action_controller') do |*args|
|
13
|
-
ActionController::Tracer.process_action(tracer: tracer, active_span: active_span, args: args)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def disable
|
18
|
-
@subscribers.each do |subscriber|
|
19
|
-
::ActiveSupport::Notifications.unsubscribe(subscriber)
|
20
|
-
end
|
21
|
-
@subscribers.clear
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
|
-
def start_processing(tracer: OpenTracing.global_tracer, active_span: nil, args: {})
|
26
|
-
event, start, finish, id, payload = *args
|
27
|
-
|
28
|
-
# extract the rack context, if it exists
|
29
|
-
# it seems like this might be the earliest place env is available
|
30
|
-
rack_span = Rails::Tracer::SpanHelpers.rack_span(payload)
|
31
|
-
Rails::Tracer::Defer.add_parent(id, rack_span)
|
32
|
-
|
33
|
-
path = payload.fetch(:path, 'unknown')
|
34
|
-
name = "#{payload.fetch(:controller, 'unknown')}##{payload.fetch(:action, 'unknown')} #{event} #{path}"
|
35
|
-
tags = {
|
36
|
-
'component' => COMPONENT,
|
37
|
-
'span.kind' => 'client',
|
38
|
-
'http.method' => payload.fetch(:method, 'unknown'),
|
39
|
-
'http.path' => path,
|
40
|
-
}
|
41
|
-
|
42
|
-
if !Rails::Tracer::Defer.enabled
|
43
|
-
span = tracer.start_span(name,
|
44
|
-
child_of: active_span.respond_to?(:call) ? active_span.call : active_span,
|
45
|
-
start_time: start,
|
46
|
-
tags: tags)
|
47
|
-
|
48
|
-
span.finish(end_time: finish) if span
|
49
|
-
else
|
50
|
-
spaninfo = {
|
51
|
-
'event' => event,
|
52
|
-
'name' => name,
|
53
|
-
'start' => start,
|
54
|
-
'finish' => finish,
|
55
|
-
'tags' => tags,
|
56
|
-
}
|
57
|
-
|
58
|
-
Rails::Tracer::Defer.defer_span(id: id, spaninfo: spaninfo)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def process_action(tracer: OpenTracing.global_tracer, active_span: nil, args: {})
|
63
|
-
event, start, finish, id, payload = *args
|
64
|
-
|
65
|
-
path = payload.fetch(:path, 'unknown')
|
66
|
-
name = "#{payload.fetch(:controller, 'unknown')}##{payload.fetch(:action, 'unknown')} #{path}"
|
67
|
-
tags = {
|
68
|
-
'component' => COMPONENT,
|
69
|
-
'span.kind' => 'client',
|
70
|
-
'http.method' => payload.fetch(:method, 'unknown'),
|
71
|
-
'http.status_code' => payload.fetch(:status, 'unknown'),
|
72
|
-
'http.path' => path,
|
73
|
-
'view.runtime' => payload.fetch(:view_runtime, 'unknown'),
|
74
|
-
'db.runtime' => payload.fetch(:db_runtime, 'unknown'),
|
75
|
-
}
|
76
|
-
|
77
|
-
if !Rails::Tracer::Defer.enabled
|
78
|
-
# write out the span
|
79
|
-
span = tracer.start_span(name,
|
80
|
-
child_of: active_span.respond_to?(:call) ? active_span.call : active_span,
|
81
|
-
start_time: start,
|
82
|
-
tags: tags)
|
83
|
-
|
84
|
-
span.finish(end_time: finish) if span
|
85
|
-
else
|
86
|
-
# defer the spans if full_trace is configured
|
87
|
-
spaninfo = {
|
88
|
-
'event' => event,
|
89
|
-
'name' => name,
|
90
|
-
'start' => start,
|
91
|
-
'finish' => finish,
|
92
|
-
'tags' => tags,
|
93
|
-
}
|
94
|
-
|
95
|
-
Rails::Tracer::Defer.defer_span(id: id, spaninfo: spaninfo)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
@@ -1,105 +0,0 @@
|
|
1
|
-
|
2
|
-
module ActionView
|
3
|
-
module Tracer
|
4
|
-
COMPONENT = "ActionView".freeze
|
5
|
-
|
6
|
-
class << self
|
7
|
-
def instrument(tracer: OpenTracing.global_tracer, active_span: nil)
|
8
|
-
@subscribers = []
|
9
|
-
@subscribers << ::ActiveSupport::Notifications.subscribe('render_template.action_view') do |*args|
|
10
|
-
ActionView::Tracer.render_template(tracer: tracer, active_span: active_span, args: args)
|
11
|
-
end
|
12
|
-
@subscribers << ::ActiveSupport::Notifications.subscribe('render_partial.action_view') do |*args|
|
13
|
-
ActionView::Tracer.render_partial(tracer: tracer, active_span: active_span, args: args)
|
14
|
-
end
|
15
|
-
@subscribers << ::ActiveSupport::Notifications.subscribe('render_collection.action_view') do |*args|
|
16
|
-
ActionView::Tracer.render_collection(tracer: tracer, active_span: active_span, args: args)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def disable
|
21
|
-
@subscribers.each do |subscriber|
|
22
|
-
::ActiveSupport::Notifications.unsubscribe(subscriber)
|
23
|
-
end
|
24
|
-
@subscribers = []
|
25
|
-
self
|
26
|
-
end
|
27
|
-
|
28
|
-
def render_template(tracer: OpenTracing.global_tracer, active_span: nil, args: {})
|
29
|
-
event, start, finish, id, payload = *args
|
30
|
-
|
31
|
-
tags = {
|
32
|
-
'component' => COMPONENT,
|
33
|
-
'span.kind' => 'client',
|
34
|
-
'template_path' => payload.fetch(:identifier, 'unknown'),
|
35
|
-
'layout' => payload.fetch(:layout, 'unknown'),
|
36
|
-
}
|
37
|
-
|
38
|
-
handle_notification(tracer: tracer,
|
39
|
-
active_span: active_span,
|
40
|
-
id: id,
|
41
|
-
name: event,
|
42
|
-
tags: tags,
|
43
|
-
start: start,
|
44
|
-
finish: finish)
|
45
|
-
end
|
46
|
-
|
47
|
-
def render_partial(tracer: OpenTracing.global_tracer, active_span: nil, args: {})
|
48
|
-
event, start, finish, id, payload = *args
|
49
|
-
|
50
|
-
tags = {
|
51
|
-
'component' => COMPONENT,
|
52
|
-
'span.kind' => 'client',
|
53
|
-
'template_path' => payload.fetch(:identifier, 'unknown'),
|
54
|
-
}
|
55
|
-
|
56
|
-
handle_notification(tracer: tracer,
|
57
|
-
active_span: active_span,
|
58
|
-
id: id,
|
59
|
-
name: event,
|
60
|
-
tags: tags,
|
61
|
-
start: start,
|
62
|
-
finish: finish)
|
63
|
-
end
|
64
|
-
|
65
|
-
def render_collection(tracer: OpenTracing.global_tracer, active_span: nil, args: {})
|
66
|
-
event, start, finish, id, payload = *args
|
67
|
-
|
68
|
-
tags = {
|
69
|
-
'component' => COMPONENT,
|
70
|
-
'span.kind' => 'client',
|
71
|
-
'template_path' => payload.fetch(:identifier, 'unknown'),
|
72
|
-
'collection_size' => payload.fetch(:count, 'unknown'),
|
73
|
-
}
|
74
|
-
|
75
|
-
handle_notification(tracer: tracer,
|
76
|
-
active_span: active_span,
|
77
|
-
id: id,
|
78
|
-
name: event,
|
79
|
-
tags: tags,
|
80
|
-
start: start,
|
81
|
-
finish: finish)
|
82
|
-
end
|
83
|
-
|
84
|
-
def handle_notification(tracer:, active_span:, id:, name:, tags:, start:, finish:)
|
85
|
-
if !Rails::Tracer::Defer.enabled
|
86
|
-
span = tracer.start_span(name,
|
87
|
-
child_of: active_span.respond_to?(:call) ? active_span.call : active_span,
|
88
|
-
start_time: start,
|
89
|
-
tags: tags)
|
90
|
-
|
91
|
-
span.finish(end_time: finish) if span
|
92
|
-
else
|
93
|
-
spaninfo = {
|
94
|
-
'event' => name,
|
95
|
-
'name' => name,
|
96
|
-
'start' => start,
|
97
|
-
'finish' => finish,
|
98
|
-
'tags' => tags,
|
99
|
-
}
|
100
|
-
Rails::Tracer::Defer.defer_span(id: id, spaninfo: spaninfo)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
@@ -1,89 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Tracer
|
3
|
-
DEFAULT_OPERATION_NAME = "sql.query".freeze
|
4
|
-
|
5
|
-
class << self
|
6
|
-
def instrument(tracer: OpenTracing.global_tracer, active_span: nil)
|
7
|
-
clear_subscribers
|
8
|
-
@subscriber = ::ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
|
9
|
-
ActiveRecord::Tracer.sql(tracer: tracer, active_span: active_span, args: args)
|
10
|
-
end
|
11
|
-
|
12
|
-
self
|
13
|
-
end
|
14
|
-
|
15
|
-
def disable
|
16
|
-
if @subscriber
|
17
|
-
ActiveSupport::Notifications.unsubscribe(@subscriber)
|
18
|
-
@subscriber = nil
|
19
|
-
end
|
20
|
-
|
21
|
-
self
|
22
|
-
end
|
23
|
-
alias :clear_subscribers :disable
|
24
|
-
|
25
|
-
def sql(tracer: OpenTracing.global_tracer, active_span: nil, args:)
|
26
|
-
event, start, finish, id, payload = *args
|
27
|
-
|
28
|
-
connection_config = ::ActiveRecord::Base.connection_config
|
29
|
-
name = payload.fetch(:name, 'unknown')
|
30
|
-
tags = {
|
31
|
-
'component' => 'ActiveRecord',
|
32
|
-
'span.kind' => 'client',
|
33
|
-
'db.user' => connection_config.fetch(:username, 'unknown'),
|
34
|
-
'db.instance' => connection_config.fetch(:database, 'unknown'),
|
35
|
-
'db.vendor' => connection_config.fetch(:adapter, 'unknown'),
|
36
|
-
'db.connection_id' => payload.fetch(:connection_id, 'unknown'),
|
37
|
-
'db.cached' => payload.fetch(:cached, false),
|
38
|
-
'db.statement' => payload.fetch(:sql, 'unknown'),
|
39
|
-
'db.type' => 'sql'
|
40
|
-
}
|
41
|
-
|
42
|
-
if !Rails::Tracer::Defer.enabled
|
43
|
-
span = tracer.start_span(name || DEFAULT_OPERATION_NAME,
|
44
|
-
child_of: active_span.respond_to?(:call) ? active_span.call : active_span,
|
45
|
-
start_time: start,
|
46
|
-
tags: tags)
|
47
|
-
|
48
|
-
if payload[:exception]
|
49
|
-
Rails::Tracer::SpanHelpers.set_error(span, payload[:exception_object] || payload[:exception])
|
50
|
-
end
|
51
|
-
|
52
|
-
span.finish(end_time: finish) if span
|
53
|
-
else
|
54
|
-
spaninfo = {
|
55
|
-
'event' => event,
|
56
|
-
'name' => name || DEFAULT_OPERATION_NAME,
|
57
|
-
'start' => start,
|
58
|
-
'finish' => finish,
|
59
|
-
'tags' => tags,
|
60
|
-
}
|
61
|
-
|
62
|
-
# errors aren't being propagated yet this way...
|
63
|
-
|
64
|
-
Rails::Tracer::Defer.defer_span(id: id, spaninfo: spaninfo)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def start_span(operation_name, tracer: OpenTracing.global_tracer, active_span: nil, start_time: Time.now, **fields)
|
69
|
-
connection_config = ::ActiveRecord::Base.connection_config
|
70
|
-
|
71
|
-
span = tracer.start_span(operation_name || DEFAULT_OPERATION_NAME,
|
72
|
-
child_of: active_span.respond_to?(:call) ? active_span.call : active_span,
|
73
|
-
start_time: start_time,
|
74
|
-
tags: {
|
75
|
-
'component' => 'ActiveRecord',
|
76
|
-
'span.kind' => 'client',
|
77
|
-
'db.user' => connection_config.fetch(:username, 'unknown'),
|
78
|
-
'db.instance' => connection_config.fetch(:database, 'unknown'),
|
79
|
-
'db.vendor' => connection_config.fetch(:adapter, 'unknown'),
|
80
|
-
'db.connection_id' => fields.fetch(:connection_id, 'unknown'),
|
81
|
-
'db.cached' => fields.fetch(:cached, false),
|
82
|
-
'db.statement' => fields.fetch(:sql, 'unknown'),
|
83
|
-
'db.type' => 'sql'
|
84
|
-
})
|
85
|
-
span
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|