instana 1.193.3.pre1 → 1.193.3

Sign up to get free protection for your applications and to get access to all the features.
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