instana 1.11.5 → 1.13.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/.circleci/config.yml +168 -0
- data/Rakefile +26 -37
- data/lib/instana/agent.rb +6 -0
- data/lib/instana/base.rb +2 -0
- 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/excon.rb +1 -1
- data/lib/instana/instrumentation/net-http.rb +2 -0
- data/lib/instana/instrumentation/rack.rb +23 -3
- data/lib/instana/instrumentation/redis.rb +39 -33
- data/lib/instana/secrets.rb +42 -0
- data/lib/instana/setup.rb +1 -0
- data/lib/instana/test.rb +4 -3
- data/lib/instana/tracing/span.rb +9 -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/config_test.rb +1 -17
- data/test/frameworks/cuba_test.rb +14 -1
- data/test/frameworks/rack_test.rb +125 -65
- data/test/frameworks/rails/actioncontroller_test.rb +12 -0
- data/test/frameworks/roda_test.rb +14 -0
- data/test/frameworks/sinatra_test.rb +37 -15
- data/test/instrumentation/grpc_test.rb +1 -1
- data/test/instrumentation/resque_test.rb +9 -16
- data/test/jobs/resque_error_job.rb +2 -2
- data/test/jobs/resque_fast_job.rb +2 -2
- data/test/secrets_test.rb +73 -0
- data/test/test_helper.rb +3 -3
- data/test/tracing/tracer_test.rb +31 -1
- metadata +7 -6
- data/.travis.yml +0 -43
- data/test/tracing/trace_test.rb +0 -67
@@ -32,6 +32,8 @@ if defined?(::Net::HTTP) && ::Instana.config[:nethttp][:enabled]
|
|
32
32
|
kv_payload[:http][:url] = "http://#{@address}:#{@port}#{request.path}"
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
kv_payload[:http][:url] = ::Instana.secrets.remove_from_query(kv_payload[:http][:url])
|
35
37
|
|
36
38
|
# The core call
|
37
39
|
response = request_without_instana(*args, &block)
|
@@ -8,8 +8,9 @@ module Instana
|
|
8
8
|
@app = app
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
kvs = {
|
11
|
+
def collect_kvs(env)
|
12
|
+
kvs = {}
|
13
|
+
kvs[:http] = {}
|
13
14
|
kvs[:http][:method] = env['REQUEST_METHOD']
|
14
15
|
kvs[:http][:url] = ::CGI.unescape(env['PATH_INFO'])
|
15
16
|
|
@@ -37,15 +38,27 @@ module Instana
|
|
37
38
|
end
|
38
39
|
}
|
39
40
|
end
|
41
|
+
return kvs
|
42
|
+
end
|
40
43
|
|
44
|
+
def call(env)
|
41
45
|
# Check incoming context
|
42
46
|
incoming_context = {}
|
43
47
|
if env.key?('HTTP_X_INSTANA_T')
|
44
48
|
incoming_context[:trace_id] = ::Instana::Util.header_to_id(env['HTTP_X_INSTANA_T'])
|
45
49
|
incoming_context[:span_id] = ::Instana::Util.header_to_id(env['HTTP_X_INSTANA_S']) if env.key?('HTTP_X_INSTANA_S')
|
46
50
|
incoming_context[:level] = env['HTTP_X_INSTANA_L'] if env.key?('HTTP_X_INSTANA_L')
|
51
|
+
|
52
|
+
# Honor X-Instana-L
|
53
|
+
if incoming_context[:level] and incoming_context[:level].length > 0
|
54
|
+
if incoming_context[:level][0] == "0"
|
55
|
+
return @app.call(env)
|
56
|
+
end
|
57
|
+
end
|
47
58
|
end
|
48
59
|
|
60
|
+
kvs = collect_kvs(env)
|
61
|
+
|
49
62
|
::Instana.tracer.log_start_or_continue(:rack, {}, incoming_context)
|
50
63
|
|
51
64
|
status, headers, response = @app.call(env)
|
@@ -63,6 +76,11 @@ module Instana
|
|
63
76
|
::Instana.tracer.log_error(nil)
|
64
77
|
end
|
65
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
|
+
|
66
84
|
# Save the IDs before the trace ends so we can place
|
67
85
|
# them in the response headers in the ensure block
|
68
86
|
trace_id = ::Instana.tracer.current_span.trace_id
|
@@ -78,8 +96,10 @@ module Instana
|
|
78
96
|
# Set reponse headers; encode as hex string
|
79
97
|
headers['X-Instana-T'] = ::Instana::Util.id_to_header(trace_id)
|
80
98
|
headers['X-Instana-S'] = ::Instana::Util.id_to_header(span_id)
|
99
|
+
headers['X-Instana-L'] = '1'
|
100
|
+
headers['Server-Timing'] = "intid;desc=#{::Instana::Util.id_to_header(trace_id)}"
|
101
|
+
::Instana.tracer.log_end(:rack, kvs)
|
81
102
|
end
|
82
|
-
::Instana.tracer.log_end(:rack, kvs)
|
83
103
|
end
|
84
104
|
end
|
85
105
|
end
|
@@ -2,28 +2,31 @@ if defined?(::Redis) && ::Instana.config[:redis][:enabled]
|
|
2
2
|
::Redis::Client.class_eval do
|
3
3
|
def call_with_instana(*args, &block)
|
4
4
|
kv_payload = { redis: {} }
|
5
|
+
dnt_spans = [:redis, :'resque-client', :'sidekiq-client']
|
5
6
|
|
6
|
-
if !Instana.tracer.tracing? || ::Instana.tracer.
|
7
|
+
if !Instana.tracer.tracing? || dnt_spans.include?(::Instana.tracer.current_span.name)
|
7
8
|
return call_without_instana(*args, &block)
|
8
9
|
end
|
9
10
|
|
10
|
-
::Instana.tracer.log_entry(:redis)
|
11
|
-
|
12
11
|
begin
|
13
|
-
|
14
|
-
kv_payload[:redis][:db] = db.to_s
|
15
|
-
kv_payload[:redis][:command] = args[0][0].to_s.upcase
|
16
|
-
rescue
|
17
|
-
nil
|
18
|
-
end
|
12
|
+
::Instana.tracer.log_entry(:redis)
|
19
13
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
begin
|
15
|
+
kv_payload[:redis][:connection] = "#{self.host}:#{self.port}"
|
16
|
+
kv_payload[:redis][:db] = db.to_s
|
17
|
+
kv_payload[:redis][:command] = args[0][0].to_s.upcase
|
18
|
+
rescue
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
call_without_instana(*args, &block)
|
23
|
+
rescue => e
|
24
|
+
::Instana.tracer.log_info({ redis: {error: true} })
|
25
|
+
::Instana.tracer.log_error(e)
|
26
|
+
raise
|
27
|
+
ensure
|
28
|
+
::Instana.tracer.log_exit(:redis, kv_payload)
|
29
|
+
end
|
27
30
|
end
|
28
31
|
|
29
32
|
::Instana.logger.debug "Instrumenting Redis"
|
@@ -33,29 +36,32 @@ if defined?(::Redis) && ::Instana.config[:redis][:enabled]
|
|
33
36
|
|
34
37
|
def call_pipeline_with_instana(*args, &block)
|
35
38
|
kv_payload = { redis: {} }
|
39
|
+
dnt_spans = [:redis, :'resque-client', :'sidekiq-client']
|
36
40
|
|
37
|
-
if !Instana.tracer.tracing? || ::Instana.tracer.
|
41
|
+
if !Instana.tracer.tracing? || dnt_spans.include?(::Instana.tracer.current_span.name)
|
38
42
|
return call_pipeline_without_instana(*args, &block)
|
39
43
|
end
|
40
44
|
|
41
|
-
::Instana.tracer.log_entry(:redis)
|
42
|
-
|
43
|
-
pipeline = args.first
|
44
45
|
begin
|
45
|
-
|
46
|
-
kv_payload[:redis][:db] = db.to_s
|
47
|
-
kv_payload[:redis][:command] = pipeline.is_a?(::Redis::Pipeline::Multi) ? 'MULTI' : 'PIPELINE'
|
48
|
-
rescue
|
49
|
-
nil
|
50
|
-
end
|
46
|
+
::Instana.tracer.log_entry(:redis)
|
51
47
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
48
|
+
pipeline = args.first
|
49
|
+
begin
|
50
|
+
kv_payload[:redis][:connection] = "#{self.host}:#{self.port}"
|
51
|
+
kv_payload[:redis][:db] = db.to_s
|
52
|
+
kv_payload[:redis][:command] = pipeline.is_a?(::Redis::Pipeline::Multi) ? 'MULTI' : 'PIPELINE'
|
53
|
+
rescue
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
call_pipeline_without_instana(*args, &block)
|
58
|
+
rescue => e
|
59
|
+
::Instana.tracer.log_info({ redis: {error: true} })
|
60
|
+
::Instana.tracer.log_error(e)
|
61
|
+
raise
|
62
|
+
ensure
|
63
|
+
::Instana.tracer.log_exit(:redis, kv_payload)
|
64
|
+
end
|
59
65
|
end
|
60
66
|
|
61
67
|
alias call_pipeline_without_instana call_pipeline
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
module Instana
|
5
|
+
class Secrets
|
6
|
+
def remove_from_query(str, secret_values = Instana.agent.secret_values)
|
7
|
+
return str unless secret_values
|
8
|
+
|
9
|
+
url = URI(str)
|
10
|
+
params = CGI.parse(url.query)
|
11
|
+
|
12
|
+
redacted = params.map do |k, v|
|
13
|
+
needs_redaction = secret_values['list']
|
14
|
+
.any? { |t| matcher(secret_values['matcher']).(t,k) }
|
15
|
+
[k, needs_redaction ? '<redacted>' : v]
|
16
|
+
end
|
17
|
+
|
18
|
+
url.query = URI.encode_www_form(redacted)
|
19
|
+
CGI.unescape(url.to_s)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def matcher(name)
|
25
|
+
case name
|
26
|
+
when 'equals-ignore-case'
|
27
|
+
->(expected, actual) { expected.casecmp(actual) == 0 }
|
28
|
+
when 'equals'
|
29
|
+
->(expected, actual) { (expected <=> actual) == 0 }
|
30
|
+
when 'contains-ignore-case'
|
31
|
+
->(expected, actual) { actual.downcase.include?(expected) }
|
32
|
+
when 'contains'
|
33
|
+
->(expected, actual) { actual.include?(expected) }
|
34
|
+
when 'regex'
|
35
|
+
->(expected, actual) { !Regexp.new(expected).match(actual).nil? }
|
36
|
+
else
|
37
|
+
::Instana.logger.warn("Matcher #{name} is not supported.")
|
38
|
+
lambda { false }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/instana/setup.rb
CHANGED
data/lib/instana/test.rb
CHANGED
@@ -7,14 +7,15 @@ module Instana
|
|
7
7
|
def setup_environment
|
8
8
|
# Set defaults if not set
|
9
9
|
ENV['MEMCACHED_HOST'] ||= '127.0.0.1:11211'
|
10
|
-
ENV['
|
11
|
-
ENV['
|
10
|
+
ENV['POSTGRES_HOST'] ||= "127.0.0.1"
|
11
|
+
ENV['POSTGRES_USER'] ||= "stan"
|
12
|
+
ENV['POSTGRES_PASSWORD'] ||= "stanlikesdata"
|
12
13
|
ENV['TRAVIS_MYSQL_HOST'] ||= "127.0.0.1"
|
13
14
|
ENV['TRAVIS_MYSQL_USER'] ||= "root"
|
14
15
|
|
15
16
|
if !ENV.key?('DATABASE_URL')
|
16
17
|
if ENV['DB_FLAVOR'] == 'postgresql'
|
17
|
-
ENV['DATABASE_URL'] = "postgresql://#{ENV['
|
18
|
+
ENV['DATABASE_URL'] = "postgresql://#{ENV['POSTGRES_USER']}:#{ENV['POSTGRES_PASSWORD']}@#{ENV['POSTGRES_HOST']}:5432/#{ENV['POSTGRES_USER']}"
|
18
19
|
elsif ENV['DB_FLAVOR'] == 'mysql'
|
19
20
|
ENV['DATABASE_URL'] = "mysql://#{ENV['TRAVIS_MYSQL_USER']}:#{ENV['TRAVIS_MYSQL_PASS']}@#{ENV['TRAVIS_MYSQL_HOST']}:3306/travis_ci_test"
|
20
21
|
else
|
data/lib/instana/tracing/span.rb
CHANGED
@@ -303,6 +303,15 @@ module Instana
|
|
303
303
|
# a String, Numeric, or Boolean it will be encoded with to_s
|
304
304
|
#
|
305
305
|
def set_tag(key, value)
|
306
|
+
if ![Symbol, String].include?(key.class)
|
307
|
+
key = key.to_s
|
308
|
+
end
|
309
|
+
|
310
|
+
# If <value> is not a Symbol, String, Array, Hash or Numeric - convert to string
|
311
|
+
if ![Symbol, String, Array, TrueClass, FalseClass, Hash].include?(value.class) && !value.is_a?(Numeric)
|
312
|
+
value = value.to_s
|
313
|
+
end
|
314
|
+
|
306
315
|
if custom?
|
307
316
|
@data[:data][:sdk][:custom] ||= {}
|
308
317
|
@data[:data][:sdk][:custom][:tags] ||= {}
|
data/lib/instana/version.rb
CHANGED
data/test/apps/cuba.rb
CHANGED
data/test/apps/roda.rb
CHANGED
data/test/apps/sinatra.rb
CHANGED
data/test/config_test.rb
CHANGED
@@ -10,28 +10,12 @@ class ConfigTest < Minitest::Test
|
|
10
10
|
assert_equal '127.0.0.1', ::Instana.config[:agent_host]
|
11
11
|
assert_equal 42699, ::Instana.config[:agent_port]
|
12
12
|
|
13
|
-
assert ::Instana.config[:enabled]
|
14
13
|
assert ::Instana.config[:tracing][:enabled]
|
15
14
|
assert ::Instana.config[:metrics][:enabled]
|
16
15
|
|
17
16
|
::Instana.config[:metrics].each do |k, v|
|
17
|
+
next unless v.is_a? Hash
|
18
18
|
assert_equal true, ::Instana.config[:metrics][k].key?(:enabled)
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
def test_that_global_affects_children
|
23
|
-
# Disabling the gem should explicitly disable
|
24
|
-
# metrics and tracing flags
|
25
|
-
::Instana.config[:enabled] = false
|
26
|
-
|
27
|
-
assert_equal false, ::Instana.config[:tracing][:enabled]
|
28
|
-
assert_equal false, ::Instana.config[:metrics][:enabled]
|
29
|
-
|
30
|
-
# Enabling the gem should explicitly enable
|
31
|
-
# metrics and tracing flags
|
32
|
-
::Instana.config[:enabled] = true
|
33
|
-
|
34
|
-
assert_equal ::Instana.config[:tracing][:enabled]
|
35
|
-
assert_equal ::Instana.config[:metrics][:enabled]
|
36
|
-
end
|
37
21
|
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
|
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
|
@@ -29,23 +35,33 @@ class RackTest < Minitest::Test
|
|
29
35
|
# Span validation
|
30
36
|
assert_equal 1, spans.count
|
31
37
|
|
32
|
-
|
33
|
-
assert_equal :rack,
|
34
|
-
|
35
|
-
assert
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
assert
|
41
|
-
assert
|
42
|
-
assert
|
43
|
-
|
38
|
+
rack_span = spans.first
|
39
|
+
assert_equal :rack, rack_span[:n]
|
40
|
+
|
41
|
+
assert last_response.headers.key?("X-Instana-T")
|
42
|
+
assert last_response.headers["X-Instana-T"] == ::Instana::Util.id_to_header(rack_span[:t])
|
43
|
+
assert last_response.headers.key?("X-Instana-S")
|
44
|
+
assert last_response.headers["X-Instana-S"] == ::Instana::Util.id_to_header(rack_span[:s])
|
45
|
+
assert last_response.headers.key?("X-Instana-L")
|
46
|
+
assert last_response.headers["X-Instana-L"] == '1'
|
47
|
+
assert last_response.headers.key?("Server-Timing")
|
48
|
+
assert last_response.headers["Server-Timing"] == "intid;desc=#{::Instana::Util.id_to_header(rack_span[:t])}"
|
49
|
+
|
50
|
+
assert rack_span.key?(:data)
|
51
|
+
assert rack_span[:data].key?(:http)
|
52
|
+
assert_equal "GET", rack_span[:data][:http][:method]
|
53
|
+
assert_equal "/mrlobster", rack_span[:data][:http][:url]
|
54
|
+
assert_equal 200, rack_span[:data][:http][:status]
|
55
|
+
assert_equal 'example.org', rack_span[:data][:http][:host]
|
56
|
+
assert rack_span.key?(:f)
|
57
|
+
assert rack_span[:f].key?(:e)
|
58
|
+
assert rack_span[:f].key?(:h)
|
59
|
+
assert_equal ::Instana.agent.agent_uuid, rack_span[:f][:h]
|
44
60
|
|
45
61
|
# Backtrace fingerprint validation
|
46
|
-
assert
|
47
|
-
assert_equal 2,
|
48
|
-
refute_nil
|
62
|
+
assert rack_span.key?(:stack)
|
63
|
+
assert_equal 2, rack_span[:stack].count
|
64
|
+
refute_nil rack_span[:stack].first[:c].match(/instana\/instrumentation\/rack.rb/)
|
49
65
|
|
50
66
|
# Restore to default
|
51
67
|
::Instana.config[:collect_backtraces] = false
|
@@ -63,8 +79,8 @@ class RackTest < Minitest::Test
|
|
63
79
|
# Span validation
|
64
80
|
assert_equal 1, spans.count
|
65
81
|
|
66
|
-
|
67
|
-
assert_equal 'WalterBishop',
|
82
|
+
rack_span = spans.first
|
83
|
+
assert_equal 'WalterBishop', rack_span[:data][:service]
|
68
84
|
|
69
85
|
ENV.delete('INSTANA_SERVICE_NAME')
|
70
86
|
end
|
@@ -78,17 +94,27 @@ class RackTest < Minitest::Test
|
|
78
94
|
|
79
95
|
# Span validation
|
80
96
|
assert_equal 1, spans.count
|
81
|
-
|
82
|
-
assert_equal :rack,
|
83
|
-
|
84
|
-
assert
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
assert
|
89
|
-
assert
|
90
|
-
assert
|
91
|
-
|
97
|
+
rack_span = spans.first
|
98
|
+
assert_equal :rack, rack_span[:n]
|
99
|
+
|
100
|
+
assert last_response.headers.key?("X-Instana-T")
|
101
|
+
assert last_response.headers["X-Instana-T"] == ::Instana::Util.id_to_header(rack_span[:t])
|
102
|
+
assert last_response.headers.key?("X-Instana-S")
|
103
|
+
assert last_response.headers["X-Instana-S"] == ::Instana::Util.id_to_header(rack_span[:s])
|
104
|
+
assert last_response.headers.key?("X-Instana-L")
|
105
|
+
assert last_response.headers["X-Instana-L"] == '1'
|
106
|
+
assert last_response.headers.key?("Server-Timing")
|
107
|
+
assert last_response.headers["Server-Timing"] == "intid;desc=#{::Instana::Util.id_to_header(rack_span[:t])}"
|
108
|
+
|
109
|
+
assert rack_span.key?(:data)
|
110
|
+
assert rack_span[:data].key?(:http)
|
111
|
+
assert_equal "POST", rack_span[:data][:http][:method]
|
112
|
+
assert_equal "/mrlobster", rack_span[:data][:http][:url]
|
113
|
+
assert_equal 200, rack_span[:data][:http][:status]
|
114
|
+
assert rack_span.key?(:f)
|
115
|
+
assert rack_span[:f].key?(:e)
|
116
|
+
assert rack_span[:f].key?(:h)
|
117
|
+
assert_equal ::Instana.agent.agent_uuid, rack_span[:f][:h]
|
92
118
|
end
|
93
119
|
|
94
120
|
def test_basic_put
|
@@ -100,17 +126,27 @@ class RackTest < Minitest::Test
|
|
100
126
|
|
101
127
|
# Span validation
|
102
128
|
assert_equal 1, spans.count
|
103
|
-
|
104
|
-
assert_equal :rack,
|
105
|
-
|
106
|
-
assert
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
assert
|
111
|
-
assert
|
112
|
-
assert
|
113
|
-
|
129
|
+
rack_span = spans.first
|
130
|
+
assert_equal :rack, rack_span[:n]
|
131
|
+
|
132
|
+
assert last_response.headers.key?("X-Instana-T")
|
133
|
+
assert last_response.headers["X-Instana-T"] == ::Instana::Util.id_to_header(rack_span[:t])
|
134
|
+
assert last_response.headers.key?("X-Instana-S")
|
135
|
+
assert last_response.headers["X-Instana-S"] == ::Instana::Util.id_to_header(rack_span[:s])
|
136
|
+
assert last_response.headers.key?("X-Instana-L")
|
137
|
+
assert last_response.headers["X-Instana-L"] == '1'
|
138
|
+
assert last_response.headers.key?("Server-Timing")
|
139
|
+
assert last_response.headers["Server-Timing"] == "intid;desc=#{::Instana::Util.id_to_header(rack_span[:t])}"
|
140
|
+
|
141
|
+
assert rack_span.key?(:data)
|
142
|
+
assert rack_span[:data].key?(:http)
|
143
|
+
assert_equal "PUT", rack_span[:data][:http][:method]
|
144
|
+
assert_equal "/mrlobster", rack_span[:data][:http][:url]
|
145
|
+
assert_equal 200, rack_span[:data][:http][:status]
|
146
|
+
assert rack_span.key?(:f)
|
147
|
+
assert rack_span[:f].key?(:e)
|
148
|
+
assert rack_span[:f].key?(:h)
|
149
|
+
assert_equal ::Instana.agent.agent_uuid, rack_span[:f][:h]
|
114
150
|
end
|
115
151
|
|
116
152
|
def test_context_continuation
|
@@ -125,23 +161,33 @@ class RackTest < Minitest::Test
|
|
125
161
|
|
126
162
|
# Span validation
|
127
163
|
assert_equal 1, spans.count
|
128
|
-
|
129
|
-
assert_equal :rack,
|
130
|
-
|
131
|
-
assert
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
assert
|
136
|
-
assert
|
137
|
-
assert
|
138
|
-
|
164
|
+
rack_span = spans.first
|
165
|
+
assert_equal :rack, rack_span[:n]
|
166
|
+
|
167
|
+
assert last_response.headers.key?("X-Instana-T")
|
168
|
+
assert last_response.headers["X-Instana-T"] == ::Instana::Util.id_to_header(rack_span[:t])
|
169
|
+
assert last_response.headers.key?("X-Instana-S")
|
170
|
+
assert last_response.headers["X-Instana-S"] == ::Instana::Util.id_to_header(rack_span[:s])
|
171
|
+
assert last_response.headers.key?("X-Instana-L")
|
172
|
+
assert last_response.headers["X-Instana-L"] == '1'
|
173
|
+
assert last_response.headers.key?("Server-Timing")
|
174
|
+
assert last_response.headers["Server-Timing"] == "intid;desc=#{::Instana::Util.id_to_header(rack_span[:t])}"
|
175
|
+
|
176
|
+
assert rack_span.key?(:data)
|
177
|
+
assert rack_span[:data].key?(:http)
|
178
|
+
assert_equal "GET", rack_span[:data][:http][:method]
|
179
|
+
assert_equal "/mrlobster", rack_span[:data][:http][:url]
|
180
|
+
assert_equal 200, rack_span[:data][:http][:status]
|
181
|
+
assert rack_span.key?(:f)
|
182
|
+
assert rack_span[:f].key?(:e)
|
183
|
+
assert rack_span[:f].key?(:h)
|
184
|
+
assert_equal ::Instana.agent.agent_uuid, rack_span[:f][:h]
|
139
185
|
|
140
186
|
# Context validation
|
141
187
|
# The first span should have the passed in trace ID
|
142
188
|
# and specify the passed in span ID as it's parent.
|
143
|
-
assert_equal 1234,
|
144
|
-
assert_equal 4321,
|
189
|
+
assert_equal 1234, rack_span[:t]
|
190
|
+
assert_equal 4321, rack_span[:p]
|
145
191
|
end
|
146
192
|
|
147
193
|
def test_instana_response_headers
|
@@ -181,20 +227,34 @@ class RackTest < Minitest::Test
|
|
181
227
|
|
182
228
|
# Span validation
|
183
229
|
assert_equal 1, spans.count
|
184
|
-
|
230
|
+
rack_span = spans.first
|
185
231
|
|
186
|
-
assert
|
187
|
-
assert
|
188
|
-
assert !
|
189
|
-
assert_equal "ThereYouGo",
|
232
|
+
assert rack_span[:data][:http].key?(:header)
|
233
|
+
assert rack_span[:data][:http][:header].key?(:"X-Capture-This")
|
234
|
+
assert !rack_span[:data][:http][:header].key?(:"X-Capture-That")
|
235
|
+
assert_equal "ThereYouGo", rack_span[:data][:http][:header][:"X-Capture-This"]
|
190
236
|
|
191
237
|
# Backtrace fingerprint validation
|
192
|
-
assert
|
193
|
-
assert_equal 2,
|
194
|
-
refute_nil
|
238
|
+
assert rack_span.key?(:stack)
|
239
|
+
assert_equal 2, rack_span[:stack].count
|
240
|
+
refute_nil rack_span[:stack].first[:c].match(/instana\/instrumentation\/rack.rb/)
|
195
241
|
|
196
242
|
# Restore to default
|
197
243
|
::Instana.config[:collect_backtraces] = false
|
198
244
|
::Instana.agent.extra_headers = nil
|
199
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
|
200
260
|
end
|