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.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -7
  3. data/.rubocop.yml +42 -0
  4. data/Appraisals +16 -13
  5. data/Gemfile +3 -7
  6. data/Gemfile.lock +173 -0
  7. data/LICENSE +2 -2
  8. data/README.md +118 -164
  9. data/Rakefile +6 -6
  10. data/bin/console +1 -1
  11. data/lib/rails/instrumentation.rb +60 -0
  12. data/lib/rails/instrumentation/patch.rb +38 -0
  13. data/lib/rails/instrumentation/subscriber.rb +45 -0
  14. data/lib/rails/instrumentation/subscribers/action_cable_subscriber.rb +69 -0
  15. data/lib/rails/instrumentation/subscribers/action_controller_subscriber.rb +172 -0
  16. data/lib/rails/instrumentation/subscribers/action_mailer_subscriber.rb +63 -0
  17. data/lib/rails/instrumentation/subscribers/action_view_subscriber.rb +48 -0
  18. data/lib/rails/instrumentation/subscribers/active_job_subscriber.rb +58 -0
  19. data/lib/rails/instrumentation/subscribers/active_record_subscriber.rb +45 -0
  20. data/lib/rails/instrumentation/subscribers/active_storage_subscriber.rb +91 -0
  21. data/lib/rails/instrumentation/subscribers/active_support_subscriber.rb +74 -0
  22. data/lib/rails/instrumentation/utils.rb +44 -0
  23. data/lib/rails/instrumentation/version.rb +5 -0
  24. data/rails-instrumentation.gemspec +32 -0
  25. metadata +54 -192
  26. data/.rspec +0 -2
  27. data/.ruby-version +0 -1
  28. data/.travis.yml +0 -25
  29. data/CHANGELOG.md +0 -47
  30. data/docker-compose.yml +0 -4
  31. data/gemfiles/.bundle/config +0 -2
  32. data/gemfiles/rails_32.gemfile +0 -11
  33. data/gemfiles/rails_4.gemfile +0 -10
  34. data/gemfiles/rails_40.gemfile +0 -10
  35. data/gemfiles/rails_41.gemfile +0 -10
  36. data/gemfiles/rails_42.gemfile +0 -10
  37. data/gemfiles/rails_5.gemfile +0 -10
  38. data/gemfiles/rails_50.gemfile +0 -10
  39. data/gemfiles/rails_51.gemfile +0 -10
  40. data/lib/rails-tracer.rb +0 -1
  41. data/lib/rails/action_controller/tracer.rb +0 -100
  42. data/lib/rails/action_view/tracer.rb +0 -105
  43. data/lib/rails/active_record/tracer.rb +0 -89
  44. data/lib/rails/active_support/cache/core_ext.rb +0 -11
  45. data/lib/rails/active_support/cache/dalli_tracer.rb +0 -106
  46. data/lib/rails/active_support/cache/manual_tracer.rb +0 -24
  47. data/lib/rails/active_support/cache/subscriber.rb +0 -62
  48. data/lib/rails/active_support/cache/tracer.rb +0 -55
  49. data/lib/rails/defer_notifications.rb +0 -78
  50. data/lib/rails/rack/tracer.rb +0 -61
  51. data/lib/rails/span_helpers.rb +0 -24
  52. data/lib/rails/tracer.rb +0 -38
  53. data/rails-tracer.gemspec +0 -44
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
@@ -1 +0,0 @@
1
- 2.4.2
@@ -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
@@ -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)
@@ -1,4 +0,0 @@
1
- memcached:
2
- image: memcached
3
- ports:
4
- - 11211:11211
@@ -1,2 +0,0 @@
1
- ---
2
- BUNDLE_RETRY: "1"
@@ -1,11 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry"
6
- gem "pry-stack_explorer"
7
- gem "pry-byebug"
8
- gem "rails", "~> 3.2.0"
9
- gem "test-unit", "~> 3.0"
10
-
11
- gemspec path: "../"
@@ -1,10 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry"
6
- gem "pry-stack_explorer"
7
- gem "pry-byebug"
8
- gem "rails", "~> 5.1.3"
9
-
10
- gemspec path: "../"
@@ -1,10 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry"
6
- gem "pry-stack_explorer"
7
- gem "pry-byebug"
8
- gem "rails", "~> 4.0.0"
9
-
10
- gemspec path: "../"
@@ -1,10 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry"
6
- gem "pry-stack_explorer"
7
- gem "pry-byebug"
8
- gem "rails", "~> 4.1.0"
9
-
10
- gemspec path: "../"
@@ -1,10 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry"
6
- gem "pry-stack_explorer"
7
- gem "pry-byebug"
8
- gem "rails", "~> 4.2.0"
9
-
10
- gemspec path: "../"
@@ -1,10 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry"
6
- gem "pry-stack_explorer"
7
- gem "pry-byebug"
8
- gem "rails", "~> 5.1.3"
9
-
10
- gemspec path: "../"
@@ -1,10 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry"
6
- gem "pry-stack_explorer"
7
- gem "pry-byebug"
8
- gem "rails", "~> 5.0.0"
9
-
10
- gemspec path: "../"
@@ -1,10 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry"
6
- gem "pry-stack_explorer"
7
- gem "pry-byebug"
8
- gem "rails", "~> 5.1.0"
9
-
10
- gemspec path: "../"
@@ -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