signalfx-rails-instrumentation 0.1.1 → 0.2.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.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -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 +116 -162
  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 +51 -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)
34
- name = "#{payload.fetch(:controller)}##{payload.fetch(:action)} #{event} #{path}"
35
- tags = {
36
- 'component' => COMPONENT,
37
- 'span.kind' => 'client',
38
- 'http.method' => payload.fetch(:method),
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)
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)
66
- name = "#{payload.fetch(:controller)}##{payload.fetch(:action)} #{path}"
67
- tags = {
68
- 'component' => COMPONENT,
69
- 'span.kind' => 'client',
70
- 'http.method' => payload.fetch(:method),
71
- 'http.status_code' => payload.fetch(:status),
72
- 'http.path' => path,
73
- 'view.runtime' => payload.fetch(:view_runtime),
74
- 'db.runtime' => payload.fetch(:db_runtime),
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)
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),
35
- 'layout' => payload.fetch(:layout),
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),
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),
72
- 'collection_size' => payload.fetch(:count),
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)
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)
30
- tags = {
31
- 'component' => 'ActiveRecord',
32
- 'span.kind' => 'client',
33
- 'db.user' => connection_config.fetch(:username, 'unknown'),
34
- 'db.instance' => connection_config.fetch(:database),
35
- 'db.vendor' => connection_config.fetch(:adapter),
36
- 'db.connection_id' => payload.fetch(:connection_id, 'unknown'),
37
- 'db.cached' => payload.fetch(:cached, false),
38
- 'db.statement' => payload.fetch(:sql),
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)
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),
79
- 'db.vendor' => connection_config.fetch(:adapter),
80
- 'db.connection_id' => fields.fetch(:connection_id, 'unknown'),
81
- 'db.cached' => fields.fetch(:cached, false),
82
- 'db.statement' => fields.fetch(:sql),
83
- 'db.type' => 'sql'
84
- })
85
- span
86
- end
87
- end
88
- end
89
- end