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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03473a7a2f7e8a5306869674ff671f1d5b66804e41bd1f687c512a33c0b07f3c
4
- data.tar.gz: aaf1ada0116589a5d33e1f74558a6c32801971e5f5f4e512be56ff6524ab447b
3
+ metadata.gz: 7f4a95f79f6ce7a30fe5f54797a8a47637dd659345043155c13eec90a8fe221c
4
+ data.tar.gz: 8206b32f50dd0f80386854ec216414cb976f3045ba113e5a86f161cba87a4736
5
5
  SHA512:
6
- metadata.gz: 6993a2dcb47b648445c97fea1017bcc9392f889270613078fd32fb2881365d88260ae0082e23eed6f32f9d111f67021dc9f2485f5cb4777b6317b7541352d40d
7
- data.tar.gz: 5c8c34a422def00edda43e613899a59b99bae6c1cf1323d79c135703b1c6ab5d565ece30f8b8f0497e0ea79a7cf1585912c17ddf5e8c363cb33f792e6f7a6903
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
@@ -1,4 +1,4 @@
1
1
  module Instana
2
- VERSION = "1.11.8"
2
+ VERSION = "1.12.0"
3
3
  VERSION_FULL = "instana-#{VERSION}"
4
4
  end
@@ -7,6 +7,10 @@ Cuba.define do
7
7
  on "hello" do
8
8
  res.write "Hello Instana!"
9
9
  end
10
+
11
+ on "greet/:name" do |name|
12
+ res.write "Hello, #{name}"
13
+ end
10
14
 
11
15
  on root do
12
16
  res.redirect '/hello'
@@ -6,5 +6,8 @@ class InstanaRodaApp < Roda
6
6
  r.get "hello" do
7
7
  "Hello Roda + Instana"
8
8
  end
9
+ r.get "greet", String do |name|
10
+ "Hello, #{name}!"
11
+ end
9
12
  end
10
13
  end
@@ -2,4 +2,8 @@ class InstanaSinatraApp < ::Sinatra::Base
2
2
  get '/' do
3
3
  "Hello Sinatra!"
4
4
  end
5
+
6
+ get '/greet/:name' do
7
+ "Hello, #{params[:name]}!"
8
+ end
5
9
  end
@@ -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 "/mrlobster" do
15
- run Rack::Lobster.new
16
- end
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.11.8
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: 2020-11-23 00:00:00.000000000 Z
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.0.6
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: