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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +18 -12
- data/.gitignore +2 -1
- data/Appraisals +4 -0
- data/gemfiles/cuba_30.gemfile +1 -0
- data/gemfiles/dalli_20.gemfile +1 -0
- data/gemfiles/excon_02.gemfile +1 -0
- data/gemfiles/graphql_10.gemfile +1 -0
- data/gemfiles/grpc_10.gemfile +1 -0
- data/gemfiles/net_http_01.gemfile +1 -0
- data/gemfiles/rack_16.gemfile +1 -0
- data/gemfiles/rack_20.gemfile +1 -0
- data/gemfiles/rails_42.gemfile +2 -0
- data/gemfiles/rails_50.gemfile +2 -0
- data/gemfiles/rails_52.gemfile +2 -0
- data/gemfiles/rails_60.gemfile +2 -0
- data/gemfiles/redis_40.gemfile +1 -0
- data/gemfiles/resque_122.gemfile +1 -0
- data/gemfiles/resque_20.gemfile +1 -0
- data/gemfiles/rest_client_16.gemfile +1 -0
- data/gemfiles/rest_client_20.gemfile +1 -0
- data/gemfiles/roda_20.gemfile +1 -0
- data/gemfiles/roda_30.gemfile +1 -0
- data/gemfiles/sidekiq_42.gemfile +1 -0
- data/gemfiles/sidekiq_50.gemfile +1 -0
- data/gemfiles/sinatra_14.gemfile +1 -0
- data/lib/instana/activators/action_controller_api.rb +18 -0
- data/lib/instana/activators/action_controller_base.rb +18 -0
- data/lib/instana/activators/action_view.rb +18 -0
- data/lib/instana/activators/active_record.rb +18 -0
- data/lib/instana/frameworks/rails.rb +20 -32
- data/lib/instana/instrumentation/action_controller.rb +81 -0
- data/lib/instana/instrumentation/action_view.rb +27 -0
- data/lib/instana/instrumentation/active_record.rb +47 -0
- data/lib/instana/version.rb +1 -1
- data/test/{frameworks/rails/actioncontroller_test.rb → instrumentation/rails_action_controller_test.rb} +37 -21
- data/test/instrumentation/rails_action_view_test.rb +138 -0
- data/test/instrumentation/rails_active_record_test.rb +121 -0
- data/test/support/apps/active_record/active_record.rb +21 -0
- metadata +19 -23
- data/lib/instana/frameworks/instrumentation/abstract_mysql_adapter.rb +0 -56
- data/lib/instana/frameworks/instrumentation/action_controller.rb +0 -194
- data/lib/instana/frameworks/instrumentation/action_view.rb +0 -39
- data/lib/instana/frameworks/instrumentation/active_record.rb +0 -27
- data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +0 -83
- data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +0 -60
- data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +0 -99
- data/test/frameworks/rails/actionview3_test.rb +0 -210
- data/test/frameworks/rails/actionview4_test.rb +0 -208
- data/test/frameworks/rails/actionview5_test.rb +0 -221
- data/test/frameworks/rails/activerecord_test.rb +0 -279
- 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
|
data/lib/instana/version.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
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
|
-
|
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 "
|
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
|
-
|
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 "
|
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 "
|
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
|
-
|
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 "
|
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
|
-
|
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 "
|
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 "
|
89
|
+
assert_equal "StandardError", ac_span[:data][:log][:parameters]
|
79
90
|
end
|
80
91
|
|
81
|
-
def
|
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
|
-
|
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
|
-
|
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
|
137
|
+
def test_not_found
|
125
138
|
clear_all!
|
126
139
|
|
127
|
-
|
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
|
-
|
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
|
-
|
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 '/
|
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
|