instana 1.11.8 → 1.12.0
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/lib/instana/frameworks/cuba.rb +33 -0
- data/lib/instana/frameworks/instrumentation/action_controller.rb +11 -0
- data/lib/instana/frameworks/roda.rb +41 -0
- data/lib/instana/frameworks/sinatra.rb +17 -0
- data/lib/instana/instrumentation/rack.rb +5 -0
- data/lib/instana/version.rb +1 -1
- data/test/apps/cuba.rb +4 -0
- data/test/apps/roda.rb +3 -0
- data/test/apps/sinatra.rb +4 -0
- data/test/frameworks/cuba_test.rb +14 -1
- data/test/frameworks/rack_test.rb +25 -5
- data/test/frameworks/rails/actioncontroller_test.rb +12 -0
- data/test/frameworks/roda_test.rb +14 -0
- data/test/frameworks/sinatra_test.rb +14 -0
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f4a95f79f6ce7a30fe5f54797a8a47637dd659345043155c13eec90a8fe221c
|
4
|
+
data.tar.gz: 8206b32f50dd0f80386854ec216414cb976f3045ba113e5a86f161cba87a4736
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9eada422ab4a40b7566fa1ae44614efc0ca2874ba0018fecd494ec01e31d1fa66c3a5ba18f86d6ded8089cbad85b196a21b57eaa79a17372ae954385c9ddfd7e
|
7
|
+
data.tar.gz: ffa1dd9e0eac0d0041945d1ddd10ecfcb813c82dcfa5aa241302838c02af17a015457af0344654bb77cc6ffb245958c8ab712c9eab450fbb627fa185ab591075
|
@@ -1,6 +1,39 @@
|
|
1
1
|
require "instana/rack"
|
2
2
|
|
3
|
+
module Instana
|
4
|
+
module CubaPathTemplateExtractor
|
5
|
+
REPLACE_TARGET = /:(?<term>[^\/]+)/i
|
6
|
+
|
7
|
+
def self.prepended(base)
|
8
|
+
::Instana.logger.debug "#{base} prepended #{self}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def on(*args, &blk)
|
12
|
+
wrapper = lambda do |*caputres|
|
13
|
+
env['INSTANA_PATH_TEMPLATE_FRAGMENTS'] << args
|
14
|
+
.select { |a| a.is_a?(String) }
|
15
|
+
.join('/')
|
16
|
+
|
17
|
+
blk.call(*captures)
|
18
|
+
end
|
19
|
+
|
20
|
+
super(*args, &wrapper)
|
21
|
+
end
|
22
|
+
|
23
|
+
def call!(env)
|
24
|
+
env['INSTANA_PATH_TEMPLATE_FRAGMENTS'] = []
|
25
|
+
response = super(env)
|
26
|
+
env['INSTANA_HTTP_PATH_TEMPLATE'] = env['INSTANA_PATH_TEMPLATE_FRAGMENTS']
|
27
|
+
.join('/')
|
28
|
+
.gsub(REPLACE_TARGET, '{\k<term>}')
|
29
|
+
response
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
3
35
|
if defined?(::Cuba)
|
4
36
|
::Instana.logger.debug "Instrumenting Cuba"
|
5
37
|
Cuba.use ::Instana::Rack
|
38
|
+
Cuba.prepend ::Instana::CubaPathTemplateExtractor
|
6
39
|
end
|
@@ -64,6 +64,15 @@ module Instana
|
|
64
64
|
end
|
65
65
|
name
|
66
66
|
end
|
67
|
+
|
68
|
+
def matched_path_template
|
69
|
+
Rails.application.routes.router.recognize(request) do |route, _, _|
|
70
|
+
path = route.path
|
71
|
+
return path.spec.to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
nil
|
75
|
+
end
|
67
76
|
end
|
68
77
|
|
69
78
|
# Used in ActionPack versions 5 and beyond, this module provides
|
@@ -83,6 +92,7 @@ module Instana
|
|
83
92
|
::Instana.tracer.log_entry(:actioncontroller, kv_payload)
|
84
93
|
|
85
94
|
super(*args)
|
95
|
+
request.env['INSTANA_HTTP_PATH_TEMPLATE'] = matched_path_template
|
86
96
|
rescue Exception => e
|
87
97
|
::Instana.tracer.log_error(e) unless has_rails_handler?(e)
|
88
98
|
raise
|
@@ -135,6 +145,7 @@ module Instana
|
|
135
145
|
::Instana.tracer.log_entry(:actioncontroller, kv_payload)
|
136
146
|
|
137
147
|
process_action_without_instana(*args)
|
148
|
+
request.env['INSTANA_HTTP_PATH_TEMPLATE'] = matched_path_template
|
138
149
|
rescue Exception => e
|
139
150
|
::Instana.tracer.log_error(e) unless has_rails_handler?(e)
|
140
151
|
raise
|
@@ -1,6 +1,47 @@
|
|
1
1
|
require "instana/rack"
|
2
2
|
|
3
|
+
module Instana
|
4
|
+
module RodaPathTemplateExtractor
|
5
|
+
module RequestMethods
|
6
|
+
TERM = defined?(::Roda) ? ::Roda::RodaPlugins::Base::RequestMethods::TERM : Object
|
7
|
+
|
8
|
+
def if_match(args, &blk)
|
9
|
+
path = @remaining_path
|
10
|
+
captures = @captures.clear
|
11
|
+
|
12
|
+
if match_all(args)
|
13
|
+
(env['INSTANA_PATH_TEMPLATE_FRAGMENTS'] ||= []).concat(named_args(args, blk))
|
14
|
+
block_result(blk.(*captures))
|
15
|
+
env['INSTANA_HTTP_PATH_TEMPLATE'] = env['INSTANA_PATH_TEMPLATE_FRAGMENTS']
|
16
|
+
.join('/')
|
17
|
+
.prepend('/')
|
18
|
+
throw :halt, response.finish
|
19
|
+
else
|
20
|
+
@remaining_path = path
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def named_args(args, blk)
|
26
|
+
parameters = blk.parameters
|
27
|
+
args.map do |a|
|
28
|
+
case a
|
29
|
+
when String
|
30
|
+
a
|
31
|
+
when TERM
|
32
|
+
nil
|
33
|
+
else
|
34
|
+
_, name = parameters.pop
|
35
|
+
"{#{name}}"
|
36
|
+
end
|
37
|
+
end.compact
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
3
43
|
if defined?(::Roda)
|
4
44
|
::Instana.logger.debug "Instrumenting Roda"
|
5
45
|
Roda.use ::Instana::Rack
|
46
|
+
Roda.plugin ::Instana::RodaPathTemplateExtractor
|
6
47
|
end
|
@@ -3,7 +3,24 @@ require "instana/rack"
|
|
3
3
|
# This instrumentation will insert Rack into Sinatra _and_ Padrino since
|
4
4
|
# the latter is based on Sinatra
|
5
5
|
|
6
|
+
module Instana
|
7
|
+
module SinatraPathTemplateExtractor
|
8
|
+
def self.extended(base)
|
9
|
+
::Instana.logger.debug "#{base} extended #{self}"
|
10
|
+
base.store_path_template
|
11
|
+
end
|
12
|
+
|
13
|
+
def store_path_template
|
14
|
+
after do
|
15
|
+
@env["INSTANA_HTTP_PATH_TEMPLATE"] = @env["sinatra.route"]
|
16
|
+
.sub("#{@request.request_method} ", '')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
6
22
|
if defined?(::Sinatra)
|
7
23
|
::Instana.logger.debug "Instrumenting Sinatra"
|
8
24
|
::Sinatra::Base.use ::Instana::Rack
|
25
|
+
::Sinatra::Base.register ::Instana::SinatraPathTemplateExtractor
|
9
26
|
end
|
@@ -76,6 +76,11 @@ module Instana
|
|
76
76
|
::Instana.tracer.log_error(nil)
|
77
77
|
end
|
78
78
|
|
79
|
+
# If the framework instrumentation provides a path template,
|
80
|
+
# pass it into the span here.
|
81
|
+
# See: https://www.instana.com/docs/tracing/custom-best-practices/#path-templates-visual-grouping-of-http-endpoints
|
82
|
+
kvs[:http][:path_tpl] = env['INSTANA_HTTP_PATH_TEMPLATE'] if env['INSTANA_HTTP_PATH_TEMPLATE']
|
83
|
+
|
79
84
|
# Save the IDs before the trace ends so we can place
|
80
85
|
# them in the response headers in the ensure block
|
81
86
|
trace_id = ::Instana.tracer.current_span.trace_id
|
data/lib/instana/version.rb
CHANGED
data/test/apps/cuba.rb
CHANGED
data/test/apps/roda.rb
CHANGED
data/test/apps/sinatra.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
if defined?(::Cuba)
|
3
2
|
require 'test_helper'
|
4
3
|
require File.expand_path(File.dirname(__FILE__) + '/../apps/cuba')
|
@@ -40,5 +39,19 @@ if defined?(::Cuba)
|
|
40
39
|
assert first_span[:data][:http].key?(:host)
|
41
40
|
assert_equal "example.org", first_span[:data][:http][:host]
|
42
41
|
end
|
42
|
+
|
43
|
+
def test_path_template
|
44
|
+
clear_all!
|
45
|
+
|
46
|
+
r = get '/greet/instana'
|
47
|
+
assert last_response.ok?
|
48
|
+
|
49
|
+
spans = ::Instana.processor.queued_spans
|
50
|
+
assert_equal 1, spans.count
|
51
|
+
|
52
|
+
first_span = spans.first
|
53
|
+
assert_equal :rack, first_span[:n]
|
54
|
+
assert_equal '/greet/{name}', first_span[:data][:http][:path_tpl]
|
55
|
+
end
|
43
56
|
end
|
44
57
|
end
|
@@ -5,16 +5,22 @@ require "instana/rack"
|
|
5
5
|
|
6
6
|
class RackTest < Minitest::Test
|
7
7
|
include Rack::Test::Methods
|
8
|
+
|
9
|
+
class PathTemplateApp
|
10
|
+
def call(env)
|
11
|
+
env['INSTANA_HTTP_PATH_TEMPLATE'] = 'sample_template'
|
12
|
+
[200, {}, ['Ok']]
|
13
|
+
end
|
14
|
+
end
|
8
15
|
|
9
16
|
def app
|
10
|
-
@app = Rack::Builder.new
|
17
|
+
@app = Rack::Builder.new do
|
11
18
|
use Rack::CommonLogger
|
12
19
|
use Rack::ShowExceptions
|
13
20
|
use Instana::Rack
|
14
|
-
map
|
15
|
-
|
16
|
-
|
17
|
-
}
|
21
|
+
map("/mrlobster") { run Rack::Lobster.new }
|
22
|
+
map("/path_tpl") { run PathTemplateApp.new }
|
23
|
+
end
|
18
24
|
end
|
19
25
|
|
20
26
|
def test_basic_get
|
@@ -237,4 +243,18 @@ class RackTest < Minitest::Test
|
|
237
243
|
::Instana.config[:collect_backtraces] = false
|
238
244
|
::Instana.agent.extra_headers = nil
|
239
245
|
end
|
246
|
+
|
247
|
+
def test_capture_http_path_template
|
248
|
+
clear_all!
|
249
|
+
|
250
|
+
get '/path_tpl'
|
251
|
+
assert last_response.ok?
|
252
|
+
|
253
|
+
spans = ::Instana.processor.queued_spans
|
254
|
+
assert_equal 1, spans.length
|
255
|
+
|
256
|
+
rack_span = spans.first
|
257
|
+
assert_equal :rack, rack_span[:n]
|
258
|
+
assert_equal 'sample_template', rack_span[:data][:http][:path_tpl]
|
259
|
+
end
|
240
260
|
end
|
@@ -153,4 +153,16 @@ class ActionControllerTest < Minitest::Test
|
|
153
153
|
assert ac_span.key?(:stack)
|
154
154
|
assert 1, ac_span[:ec]
|
155
155
|
end
|
156
|
+
|
157
|
+
def test_path_template
|
158
|
+
clear_all!
|
159
|
+
|
160
|
+
Net::HTTP.get(URI.parse('http://localhost:3205/test/world'))
|
161
|
+
|
162
|
+
spans = ::Instana.processor.queued_spans
|
163
|
+
rack_span = find_first_span_by_name(spans, :rack)
|
164
|
+
|
165
|
+
assert_equal false, rack_span.key?(:error)
|
166
|
+
assert_equal '/test/world(.:format)', rack_span[:data][:http][:path_tpl]
|
167
|
+
end
|
156
168
|
end
|
@@ -40,5 +40,19 @@ if defined?(::Roda)
|
|
40
40
|
assert first_span[:data][:http].key?(:host)
|
41
41
|
assert_equal "example.org", first_span[:data][:http][:host]
|
42
42
|
end
|
43
|
+
|
44
|
+
def test_path_template
|
45
|
+
clear_all!
|
46
|
+
|
47
|
+
r = get '/greet/instana'
|
48
|
+
assert last_response.ok?
|
49
|
+
|
50
|
+
spans = ::Instana.processor.queued_spans
|
51
|
+
assert_equal 1, spans.count
|
52
|
+
|
53
|
+
first_span = spans.first
|
54
|
+
assert_equal :rack, first_span[:n]
|
55
|
+
assert_equal '/greet/{name}', first_span[:data][:http][:path_tpl]
|
56
|
+
end
|
43
57
|
end
|
44
58
|
end
|
@@ -48,5 +48,19 @@ if defined?(::Sinatra)
|
|
48
48
|
assert rack_span[:data][:http].key?(:host)
|
49
49
|
assert_equal "example.org", rack_span[:data][:http][:host]
|
50
50
|
end
|
51
|
+
|
52
|
+
def test_path_template
|
53
|
+
clear_all!
|
54
|
+
|
55
|
+
r = get '/greet/instana'
|
56
|
+
assert last_response.ok?
|
57
|
+
|
58
|
+
spans = ::Instana.processor.queued_spans
|
59
|
+
assert_equal 1, spans.count
|
60
|
+
|
61
|
+
first_span = spans.first
|
62
|
+
assert_equal :rack, first_span[:n]
|
63
|
+
assert_equal '/greet/:name', first_span[:data][:http][:path_tpl]
|
64
|
+
end
|
51
65
|
end
|
52
66
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Giacomo Lombardo
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -306,7 +306,7 @@ metadata:
|
|
306
306
|
documentation_uri: https://docs.instana.io/ecosystem/ruby/
|
307
307
|
homepage_uri: https://www.instana.com/
|
308
308
|
source_code_uri: https://github.com/instana/ruby-sensor
|
309
|
-
post_install_message:
|
309
|
+
post_install_message:
|
310
310
|
rdoc_options: []
|
311
311
|
require_paths:
|
312
312
|
- lib
|
@@ -321,8 +321,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
321
321
|
- !ruby/object:Gem::Version
|
322
322
|
version: '0'
|
323
323
|
requirements: []
|
324
|
-
rubygems_version: 3.
|
325
|
-
signing_key:
|
324
|
+
rubygems_version: 3.1.4
|
325
|
+
signing_key:
|
326
326
|
specification_version: 4
|
327
327
|
summary: Ruby Distributed Tracing & Metrics Sensor for Instana
|
328
328
|
test_files:
|