instana 1.193.3.pre1 → 1.193.3

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +18 -12
  3. data/.gitignore +2 -1
  4. data/Appraisals +4 -0
  5. data/gemfiles/cuba_30.gemfile +1 -0
  6. data/gemfiles/dalli_20.gemfile +1 -0
  7. data/gemfiles/excon_02.gemfile +1 -0
  8. data/gemfiles/graphql_10.gemfile +1 -0
  9. data/gemfiles/grpc_10.gemfile +1 -0
  10. data/gemfiles/net_http_01.gemfile +1 -0
  11. data/gemfiles/rack_16.gemfile +1 -0
  12. data/gemfiles/rack_20.gemfile +1 -0
  13. data/gemfiles/rails_42.gemfile +2 -0
  14. data/gemfiles/rails_50.gemfile +2 -0
  15. data/gemfiles/rails_52.gemfile +2 -0
  16. data/gemfiles/rails_60.gemfile +2 -0
  17. data/gemfiles/redis_40.gemfile +1 -0
  18. data/gemfiles/resque_122.gemfile +1 -0
  19. data/gemfiles/resque_20.gemfile +1 -0
  20. data/gemfiles/rest_client_16.gemfile +1 -0
  21. data/gemfiles/rest_client_20.gemfile +1 -0
  22. data/gemfiles/roda_20.gemfile +1 -0
  23. data/gemfiles/roda_30.gemfile +1 -0
  24. data/gemfiles/sidekiq_42.gemfile +1 -0
  25. data/gemfiles/sidekiq_50.gemfile +1 -0
  26. data/gemfiles/sinatra_14.gemfile +1 -0
  27. data/lib/instana/activators/action_controller_api.rb +18 -0
  28. data/lib/instana/activators/action_controller_base.rb +18 -0
  29. data/lib/instana/activators/action_view.rb +18 -0
  30. data/lib/instana/activators/active_record.rb +18 -0
  31. data/lib/instana/frameworks/rails.rb +20 -32
  32. data/lib/instana/instrumentation/action_controller.rb +81 -0
  33. data/lib/instana/instrumentation/action_view.rb +27 -0
  34. data/lib/instana/instrumentation/active_record.rb +47 -0
  35. data/lib/instana/version.rb +1 -1
  36. data/test/{frameworks/rails/actioncontroller_test.rb → instrumentation/rails_action_controller_test.rb} +37 -21
  37. data/test/instrumentation/rails_action_view_test.rb +138 -0
  38. data/test/instrumentation/rails_active_record_test.rb +121 -0
  39. data/test/support/apps/active_record/active_record.rb +21 -0
  40. metadata +19 -23
  41. data/lib/instana/frameworks/instrumentation/abstract_mysql_adapter.rb +0 -56
  42. data/lib/instana/frameworks/instrumentation/action_controller.rb +0 -194
  43. data/lib/instana/frameworks/instrumentation/action_view.rb +0 -39
  44. data/lib/instana/frameworks/instrumentation/active_record.rb +0 -27
  45. data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +0 -83
  46. data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +0 -60
  47. data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +0 -99
  48. data/test/frameworks/rails/actionview3_test.rb +0 -210
  49. data/test/frameworks/rails/actionview4_test.rb +0 -208
  50. data/test/frameworks/rails/actionview5_test.rb +0 -221
  51. data/test/frameworks/rails/activerecord_test.rb +0 -279
  52. data/test/frameworks/rails_test.rb +0 -15
@@ -0,0 +1,81 @@
1
+ module Instana
2
+ module Instrumentation
3
+ module ActionController
4
+ def process_action(*args)
5
+ call_payload = {
6
+ actioncontroller: {
7
+ controller: self.class.name,
8
+ action: action_name
9
+ }
10
+ }
11
+
12
+ request.env['INSTANA_HTTP_PATH_TEMPLATE'] = matched_path_template
13
+ ::Instana::Tracer.trace(:actioncontroller, call_payload) { super(*args) }
14
+ end
15
+
16
+ def render(*args, &block)
17
+ call_payload = {
18
+ actionview: {
19
+ name: describe_render_options(args.first) || 'Default'
20
+ }
21
+ }
22
+
23
+ ::Instana::Tracer.trace(:actionview, call_payload) { super(*args, &block) }
24
+ end
25
+
26
+ private
27
+
28
+ def matched_path_template
29
+ Rails.application.routes.router.recognize(request) do |route, _, _|
30
+ path = route.path
31
+ return path.spec.to_s
32
+ end
33
+
34
+ nil
35
+ end
36
+
37
+ def describe_render_options(options)
38
+ return unless options
39
+
40
+ describe_layout(options[:layout]) ||
41
+ describe_direct(options)
42
+ end
43
+
44
+ def describe_layout(layout)
45
+ return unless layout
46
+
47
+ case layout
48
+ when FalseClass
49
+ 'Without layout'
50
+ when String
51
+ layout
52
+ when Proc
53
+ 'Proc'
54
+ else
55
+ 'Default'
56
+ end
57
+ end
58
+
59
+ def describe_direct(options)
60
+ case options
61
+ when ->(o) { o.key?(:nothing) }
62
+ 'Nothing'
63
+ when ->(o) { o.key?(:plain) }
64
+ 'Plaintext'
65
+ when ->(o) { o.key?(:json) }
66
+ 'JSON'
67
+ when ->(o) { o.key?(:xml) }
68
+ 'XML'
69
+ when ->(o) { o.key?(:body) }
70
+ 'Raw'
71
+ when ->(o) { o.key?(:js) }
72
+ 'Javascript'
73
+ when ->(o) { o.key?(:template) }
74
+ options[:template]
75
+ when ->(o) { o.key?(:file) }
76
+ options[:file]
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,27 @@
1
+ module Instana
2
+ module Instrumentation
3
+ module ActionView
4
+ def render_partial(*args)
5
+ call_payload = {
6
+ render: {
7
+ type: :partial,
8
+ name: @options.is_a?(Hash) ? @options[:partial].to_s : 'Unknown'
9
+ }
10
+ }
11
+
12
+ ::Instana::Tracer.trace(:render, call_payload) { super(*args) }
13
+ end
14
+
15
+ def render_collection(*args)
16
+ call_payload = {
17
+ render: {
18
+ type: :collection,
19
+ name: @path.to_s
20
+ }
21
+ }
22
+
23
+ ::Instana::Tracer.trace(:render, call_payload) { super(*args) }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ module Instana
2
+ module Instrumentation
3
+ module ActiveRecord
4
+ IGNORED_NAMES = %w[SCHEMA EXPLAIN CACHE].freeze
5
+ IGNORED_SQL = %w[BEGIN COMMIT SET].freeze
6
+ SANITIZE_REGEXP = /('[\s\S][^']*'|\d*\.\d+|\d+|NULL)/i.freeze
7
+
8
+ def log(sql, name = 'SQL', binds = [], *args)
9
+ call_payload = {
10
+ activerecord: {
11
+ adapter: @config[:adapter],
12
+ host: @config[:host],
13
+ username: @config[:username],
14
+ db: @config[:database],
15
+ sql: maybe_sanitize(sql)
16
+ }
17
+ }
18
+
19
+ if binds.all? { |b| b.respond_to?(:value_before_type_cast) }
20
+ mapped = binds.map(&:value_before_type_cast)
21
+ call_payload[:activerecord][:binds] = mapped
22
+ end
23
+
24
+ maybe_trace(call_payload, name) { super(sql, name, binds, *args) }
25
+ end
26
+
27
+ private
28
+
29
+ def maybe_sanitize(sql)
30
+ ::Instana.config[:sanitize_sql] ? sql.gsub(SANITIZE_REGEXP, '?') : sql
31
+ end
32
+
33
+ def maybe_trace(call_payload, name, &blk)
34
+ if ::Instana.tracer.tracing? && !ignored?(call_payload, name)
35
+ ::Instana.tracer.trace(:activerecord, call_payload, &blk)
36
+ else
37
+ yield
38
+ end
39
+ end
40
+
41
+ def ignored?(call_payload, name)
42
+ IGNORED_NAMES.include?(name) ||
43
+ IGNORED_SQL.any? { |s| call_payload[:activerecord][:sql].upcase.start_with?(s) }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,4 +1,4 @@
1
1
  module Instana
2
- VERSION = "1.193.3.pre1"
2
+ VERSION = "1.193.3"
3
3
  VERSION_FULL = "instana-#{VERSION}"
4
4
  end
@@ -1,6 +1,13 @@
1
1
  require 'test_helper'
2
2
 
3
- class ActionControllerTest < Minitest::Test
3
+ class RailsActionControllerTest < Minitest::Test
4
+ include Rack::Test::Methods
5
+ APP = Rack::Builder.parse_file('test/support/apps/action_controller/config.ru').first
6
+
7
+ def app
8
+ APP
9
+ end
10
+
4
11
  def test_config_defaults
5
12
  assert ::Instana.config[:action_controller].is_a?(Hash)
6
13
  assert ::Instana.config[:action_controller].key?(:enabled)
@@ -10,33 +17,35 @@ class ActionControllerTest < Minitest::Test
10
17
  def test_controller_reporting
11
18
  clear_all!
12
19
 
13
- Net::HTTP.get(URI.parse('http://localhost:3205/test/world'))
20
+ get '/base/world'
21
+ assert last_response.ok?
14
22
 
15
23
  spans = ::Instana.processor.queued_spans
16
24
  assert_equal 3, spans.length
17
25
 
18
26
  ac_span = find_first_span_by_name(spans, :actioncontroller)
19
27
 
20
- assert_equal "TestController", ac_span[:data][:actioncontroller][:controller]
28
+ assert_equal "TestBaseController", ac_span[:data][:actioncontroller][:controller]
21
29
  assert_equal "world", ac_span[:data][:actioncontroller][:action]
22
30
  end
23
31
 
24
32
  def test_controller_error
25
33
  clear_all!
26
34
 
27
- Net::HTTP.get(URI.parse('http://localhost:3205/test/error'))
35
+ get '/base/error'
36
+ refute last_response.ok?
28
37
 
29
38
  spans = ::Instana.processor.queued_spans
30
39
  assert_equal 2, spans.length
31
40
 
32
41
  ac_span = find_first_span_by_name(spans, :actioncontroller)
33
42
 
34
- assert_equal "TestController", ac_span[:data][:actioncontroller][:controller]
43
+ assert_equal "TestBaseController", ac_span[:data][:actioncontroller][:controller]
35
44
  assert_equal "error", ac_span[:data][:actioncontroller][:action]
36
45
  assert ac_span.key?(:error)
37
46
  assert ac_span.key?(:stack)
38
47
  assert_equal "Warning: This is a simulated Error", ac_span[:data][:log][:message]
39
- assert_equal "Exception", ac_span[:data][:log][:parameters]
48
+ assert_equal "StandardError", ac_span[:data][:log][:parameters]
40
49
  end
41
50
 
42
51
  def test_api_controller_reporting
@@ -45,7 +54,8 @@ class ActionControllerTest < Minitest::Test
45
54
 
46
55
  clear_all!
47
56
 
48
- Net::HTTP.get(URI.parse('http://localhost:3205/api/world'))
57
+ get '/api/world'
58
+ assert last_response.ok?
49
59
 
50
60
  spans = ::Instana.processor.queued_spans
51
61
  assert_equal 3, spans.length
@@ -53,7 +63,7 @@ class ActionControllerTest < Minitest::Test
53
63
  ac_span = find_first_span_by_name(spans, :actioncontroller)
54
64
 
55
65
  assert_equal :actioncontroller, ac_span[:n]
56
- assert_equal "SocketController", ac_span[:data][:actioncontroller][:controller]
66
+ assert_equal "TestApiController", ac_span[:data][:actioncontroller][:controller]
57
67
  assert_equal "world", ac_span[:data][:actioncontroller][:action]
58
68
  end
59
69
 
@@ -63,28 +73,30 @@ class ActionControllerTest < Minitest::Test
63
73
 
64
74
  clear_all!
65
75
 
66
- Net::HTTP.get(URI.parse('http://localhost:3205/api/error'))
76
+ get '/api/error'
77
+ refute last_response.ok?
67
78
 
68
79
  spans = ::Instana.processor.queued_spans
69
80
  assert_equal 2, spans.length
70
81
 
71
82
  ac_span = find_first_span_by_name(spans, :actioncontroller)
72
83
 
73
- assert_equal "SocketController", ac_span[:data][:actioncontroller][:controller]
84
+ assert_equal "TestApiController", ac_span[:data][:actioncontroller][:controller]
74
85
  assert_equal "error", ac_span[:data][:actioncontroller][:action]
75
86
  assert ac_span.key?(:error)
76
87
  assert ac_span.key?(:stack)
77
88
  assert_equal "Warning: This is a simulated Socket API Error", ac_span[:data][:log][:message]
78
- assert_equal "Exception", ac_span[:data][:log][:parameters]
89
+ assert_equal "StandardError", ac_span[:data][:log][:parameters]
79
90
  end
80
91
 
81
- def test_api_controller_404
92
+ def test_api_controller_not_found
82
93
  # Run only when ActionController::API is used/defined
83
94
  skip unless defined?(::ActionController::API)
84
95
 
85
96
  clear_all!
86
97
 
87
- Net::HTTP.get(URI.parse('http://localhost:3205/api/thispathdoesnotexist'))
98
+ get '/api/thispathdoesnotexist'
99
+ refute last_response.ok?
88
100
 
89
101
  spans = ::Instana.processor.queued_spans
90
102
  assert_equal 1, spans.length
@@ -103,7 +115,8 @@ class ActionControllerTest < Minitest::Test
103
115
 
104
116
  clear_all!
105
117
 
106
- Net::HTTP.get(URI.parse('http://localhost:3205/api/raise_route_error'))
118
+ get '/api/raise_route_error'
119
+ refute last_response.ok?
107
120
 
108
121
  spans = ::Instana.processor.queued_spans
109
122
  assert_equal 2, spans.length
@@ -121,10 +134,11 @@ class ActionControllerTest < Minitest::Test
121
134
  assert 1, ac_span[:ec]
122
135
  end
123
136
 
124
- def test_404
137
+ def test_not_found
125
138
  clear_all!
126
139
 
127
- Net::HTTP.get(URI.parse('http://localhost:3205/test/404'))
140
+ get '/base/404'
141
+ refute last_response.ok?
128
142
 
129
143
  spans = ::Instana.processor.queued_spans
130
144
  assert_equal 1, spans.length
@@ -138,7 +152,8 @@ class ActionControllerTest < Minitest::Test
138
152
  def test_raise_routing_error
139
153
  clear_all!
140
154
 
141
- Net::HTTP.get(URI.parse('http://localhost:3205/test/raise_route_error'))
155
+ get '/base/raise_route_error'
156
+ refute last_response.ok?
142
157
 
143
158
  spans = ::Instana.processor.queued_spans
144
159
  assert_equal 2, spans.length
@@ -153,16 +168,17 @@ class ActionControllerTest < Minitest::Test
153
168
  assert ac_span.key?(:stack)
154
169
  assert 1, ac_span[:ec]
155
170
  end
156
-
171
+
157
172
  def test_path_template
158
173
  clear_all!
159
174
 
160
- Net::HTTP.get(URI.parse('http://localhost:3205/test/world'))
161
-
175
+ get '/base/world'
176
+ assert last_response.ok?
177
+
162
178
  spans = ::Instana.processor.queued_spans
163
179
  rack_span = find_first_span_by_name(spans, :rack)
164
180
 
165
181
  assert_equal false, rack_span.key?(:error)
166
- assert_equal '/test/world(.:format)', rack_span[:data][:http][:path_tpl]
182
+ assert_equal '/base/world(.:format)', rack_span[:data][:http][:path_tpl]
167
183
  end
168
184
  end
@@ -0,0 +1,138 @@
1
+ require 'test_helper'
2
+
3
+ class RailsActionViewTest < Minitest::Test
4
+ include Rack::Test::Methods
5
+ APP = Rack::Builder.parse_file('test/support/apps/action_view/config.ru').first
6
+
7
+ def app
8
+ APP
9
+ end
10
+
11
+ def setup
12
+ clear_all!
13
+ end
14
+
15
+ def test_config_defaults
16
+ assert ::Instana.config[:action_view].is_a?(Hash)
17
+ assert ::Instana.config[:action_view].key?(:enabled)
18
+ assert_equal true, ::Instana.config[:action_view][:enabled]
19
+ end
20
+
21
+ def test_render_view
22
+ get '/render_view'
23
+ assert last_response.ok?
24
+
25
+ spans = ::Instana.processor.queued_spans
26
+ span = find_first_span_by_name(spans, :actionview)
27
+
28
+ assert_equal 'Default', span[:data][:actionview][:name]
29
+ end
30
+
31
+ def test_render_nothing
32
+ # `render nothing: true` was removed in 5.1
33
+ skip unless Rails::VERSION::MAJOR <= 5 && Rails::VERSION::MINOR <= 1
34
+ get '/render_nothing'
35
+ assert last_response.ok?
36
+
37
+ spans = ::Instana.processor.queued_spans
38
+ span = find_first_span_by_name(spans, :actionview)
39
+
40
+ assert_equal 'Nothing', span[:data][:actionview][:name]
41
+ end
42
+
43
+ def test_render_file
44
+ get '/render_file'
45
+ assert last_response.ok?
46
+
47
+ spans = ::Instana.processor.queued_spans
48
+ span = find_first_span_by_name(spans, :actionview)
49
+
50
+ assert_equal 'test/support/apps/action_view/config.ru', span[:data][:actionview][:name]
51
+ end
52
+
53
+ def test_render_json
54
+ get '/render_json'
55
+ assert last_response.ok?
56
+
57
+ spans = ::Instana.processor.queued_spans
58
+ span = find_first_span_by_name(spans, :actionview)
59
+
60
+ assert_equal 'JSON', span[:data][:actionview][:name]
61
+ end
62
+
63
+ def test_render_xml
64
+ get '/render_xml'
65
+ assert last_response.ok?
66
+
67
+ spans = ::Instana.processor.queued_spans
68
+ span = find_first_span_by_name(spans, :actionview)
69
+
70
+ assert_equal 'XML', span[:data][:actionview][:name]
71
+ end
72
+
73
+ def test_render_body
74
+ get '/render_rawbody'
75
+ assert last_response.ok?
76
+
77
+ spans = ::Instana.processor.queued_spans
78
+ span = find_first_span_by_name(spans, :actionview)
79
+
80
+ assert_equal 'Raw', span[:data][:actionview][:name]
81
+ end
82
+
83
+ def test_render_js
84
+ get '/render_js'
85
+ assert last_response.ok?
86
+
87
+ spans = ::Instana.processor.queued_spans
88
+ span = find_first_span_by_name(spans, :actionview)
89
+
90
+ assert_equal 'Javascript', span[:data][:actionview][:name]
91
+ end
92
+
93
+ def test_render_alternate_layout
94
+ get '/render_alternate_layout'
95
+ assert last_response.ok?
96
+
97
+ spans = ::Instana.processor.queued_spans
98
+ span = find_first_span_by_name(spans, :actionview)
99
+
100
+ assert_equal 'layouts/mobile', span[:data][:actionview][:name]
101
+ end
102
+
103
+ def test_render_partial
104
+ get '/render_partial'
105
+ assert last_response.ok?
106
+
107
+ spans = ::Instana.processor.queued_spans
108
+ span = find_first_span_by_name(spans, :render)
109
+
110
+ assert_equal 'message', span[:data][:render][:name]
111
+ end
112
+
113
+ def test_render_partial_that_errors
114
+ get '/render_partial_that_errors'
115
+ refute last_response.ok?
116
+
117
+ spans = ::Instana.processor.queued_spans
118
+ span = find_first_span_by_name(spans, :render)
119
+
120
+ assert_equal :partial, span[:data][:render][:type]
121
+ assert_equal 'syntax_error', span[:data][:render][:name]
122
+ assert span[:data][:log].key?(:message)
123
+ assert span[:data][:log][:parameters].include?('SyntaxError')
124
+ assert span[:error]
125
+ assert span[:stack]
126
+ end
127
+
128
+ def test_render_collection
129
+ get '/render_collection'
130
+ assert last_response.ok?
131
+
132
+ spans = ::Instana.processor.queued_spans
133
+ span = find_first_span_by_name(spans, :render)
134
+
135
+ assert_equal :collection, span[:data][:render][:type]
136
+ assert_equal 'blocks/block', span[:data][:render][:name]
137
+ end
138
+ end