instana 1.10.1-java

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.
Files changed (125) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +23 -0
  3. data/.gitignore +16 -0
  4. data/.rubocop.yml +1156 -0
  5. data/.travis.yml +43 -0
  6. data/Configuration.md +149 -0
  7. data/Dockerfile +13 -0
  8. data/Gemfile +41 -0
  9. data/LICENSE +21 -0
  10. data/README.md +102 -0
  11. data/Rakefile +56 -0
  12. data/Tracing.md +145 -0
  13. data/Troubleshooting.md +32 -0
  14. data/benchmarks/Gemfile +7 -0
  15. data/benchmarks/id_generation.rb +12 -0
  16. data/benchmarks/opentracing.rb +26 -0
  17. data/benchmarks/rack_vanilla_vs_traced.rb +80 -0
  18. data/benchmarks/stackprof_rack_tracing.rb +77 -0
  19. data/benchmarks/time_processing.rb +12 -0
  20. data/bin/console +7 -0
  21. data/bin/setup +8 -0
  22. data/examples/opentracing.rb +31 -0
  23. data/examples/tracing.rb +80 -0
  24. data/gemfiles/libraries.gemfile +71 -0
  25. data/gemfiles/rails32.gemfile +51 -0
  26. data/gemfiles/rails42.gemfile +50 -0
  27. data/gemfiles/rails50.gemfile +52 -0
  28. data/instana.gemspec +46 -0
  29. data/lib/instana.rb +12 -0
  30. data/lib/instana/agent.rb +441 -0
  31. data/lib/instana/agent/helpers.rb +61 -0
  32. data/lib/instana/agent/hooks.rb +37 -0
  33. data/lib/instana/agent/tasks.rb +48 -0
  34. data/lib/instana/base.rb +54 -0
  35. data/lib/instana/collector.rb +116 -0
  36. data/lib/instana/collectors/gc.rb +57 -0
  37. data/lib/instana/collectors/memory.rb +34 -0
  38. data/lib/instana/collectors/thread.rb +30 -0
  39. data/lib/instana/config.rb +79 -0
  40. data/lib/instana/eum/eum-test.js.erb +16 -0
  41. data/lib/instana/eum/eum.js.erb +14 -0
  42. data/lib/instana/frameworks/cuba.rb +6 -0
  43. data/lib/instana/frameworks/instrumentation/abstract_mysql_adapter.rb +58 -0
  44. data/lib/instana/frameworks/instrumentation/action_controller.rb +183 -0
  45. data/lib/instana/frameworks/instrumentation/action_view.rb +43 -0
  46. data/lib/instana/frameworks/instrumentation/active_record.rb +27 -0
  47. data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +81 -0
  48. data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +56 -0
  49. data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +71 -0
  50. data/lib/instana/frameworks/rails.rb +42 -0
  51. data/lib/instana/frameworks/roda.rb +6 -0
  52. data/lib/instana/frameworks/sinatra.rb +9 -0
  53. data/lib/instana/helpers.rb +40 -0
  54. data/lib/instana/instrumentation.rb +21 -0
  55. data/lib/instana/instrumentation/dalli.rb +78 -0
  56. data/lib/instana/instrumentation/excon.rb +74 -0
  57. data/lib/instana/instrumentation/grpc.rb +84 -0
  58. data/lib/instana/instrumentation/net-http.rb +66 -0
  59. data/lib/instana/instrumentation/rack.rb +77 -0
  60. data/lib/instana/instrumentation/redis.rb +82 -0
  61. data/lib/instana/instrumentation/resque.rb +131 -0
  62. data/lib/instana/instrumentation/rest-client.rb +34 -0
  63. data/lib/instana/instrumentation/sidekiq-client.rb +45 -0
  64. data/lib/instana/instrumentation/sidekiq-worker.rb +54 -0
  65. data/lib/instana/opentracing/carrier.rb +4 -0
  66. data/lib/instana/opentracing/tracer.rb +18 -0
  67. data/lib/instana/rack.rb +10 -0
  68. data/lib/instana/setup.rb +36 -0
  69. data/lib/instana/test.rb +40 -0
  70. data/lib/instana/thread_local.rb +15 -0
  71. data/lib/instana/tracer.rb +392 -0
  72. data/lib/instana/tracing/processor.rb +92 -0
  73. data/lib/instana/tracing/span.rb +401 -0
  74. data/lib/instana/tracing/span_context.rb +33 -0
  75. data/lib/instana/util.rb +261 -0
  76. data/lib/instana/version.rb +4 -0
  77. data/lib/oj_check.rb +16 -0
  78. data/lib/opentracing.rb +6 -0
  79. data/test/agent/agent_test.rb +143 -0
  80. data/test/apps/cuba.rb +15 -0
  81. data/test/apps/grpc_server.rb +81 -0
  82. data/test/apps/roda.rb +10 -0
  83. data/test/apps/sinatra.rb +5 -0
  84. data/test/benchmarks/bench_id_generation.rb +12 -0
  85. data/test/benchmarks/bench_opentracing.rb +13 -0
  86. data/test/config_test.rb +37 -0
  87. data/test/frameworks/cuba_test.rb +44 -0
  88. data/test/frameworks/rack_test.rb +167 -0
  89. data/test/frameworks/rails/actioncontroller_test.rb +93 -0
  90. data/test/frameworks/rails/actionview3_test.rb +255 -0
  91. data/test/frameworks/rails/actionview4_test.rb +254 -0
  92. data/test/frameworks/rails/actionview5_test.rb +221 -0
  93. data/test/frameworks/rails/activerecord3_test.rb +134 -0
  94. data/test/frameworks/rails/activerecord4_test.rb +134 -0
  95. data/test/frameworks/rails/activerecord5_test.rb +87 -0
  96. data/test/frameworks/roda_test.rb +44 -0
  97. data/test/frameworks/sinatra_test.rb +44 -0
  98. data/test/instana_test.rb +27 -0
  99. data/test/instrumentation/dalli_test.rb +253 -0
  100. data/test/instrumentation/excon_test.rb +147 -0
  101. data/test/instrumentation/grpc_test.rb +377 -0
  102. data/test/instrumentation/net-http_test.rb +160 -0
  103. data/test/instrumentation/redis_test.rb +119 -0
  104. data/test/instrumentation/resque_test.rb +128 -0
  105. data/test/instrumentation/rest-client_test.rb +55 -0
  106. data/test/instrumentation/sidekiq-client_test.rb +125 -0
  107. data/test/instrumentation/sidekiq-worker_test.rb +173 -0
  108. data/test/jobs/resque_error_job.rb +22 -0
  109. data/test/jobs/resque_fast_job.rb +20 -0
  110. data/test/jobs/sidekiq_job_1.rb +6 -0
  111. data/test/jobs/sidekiq_job_2.rb +7 -0
  112. data/test/models/block.rb +18 -0
  113. data/test/servers/grpc_50051.rb +20 -0
  114. data/test/servers/helpers/sidekiq_worker_initializer.rb +27 -0
  115. data/test/servers/rackapp_6511.rb +25 -0
  116. data/test/servers/rails_3205.rb +167 -0
  117. data/test/servers/sidekiq/worker.rb +27 -0
  118. data/test/test_helper.rb +145 -0
  119. data/test/tracing/custom_test.rb +158 -0
  120. data/test/tracing/id_management_test.rb +130 -0
  121. data/test/tracing/opentracing_test.rb +335 -0
  122. data/test/tracing/trace_test.rb +67 -0
  123. data/test/tracing/tracer_async_test.rb +198 -0
  124. data/test/tracing/tracer_test.rb +223 -0
  125. metadata +327 -0
@@ -0,0 +1,167 @@
1
+
2
+ ::Instana.logger.warn "Starting background Ruby on Rails #{Rails::VERSION::STRING} application on port 3205"
3
+
4
+ if Rails::VERSION::STRING >= '5.0' && ::Instana::Test.mysql?
5
+ ::Instana.logger.fatal "Rails 5.x doesn't support the mysql adapter (discontinued). Set DB_FLAVOR=msyql2 instead. This will fail as is."
6
+ end
7
+
8
+ require "rails/all"
9
+ require "action_controller/railtie" # require more if needed
10
+ require 'rack/handler/puma'
11
+ require File.expand_path(File.dirname(__FILE__) + '/../models/block')
12
+
13
+ ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
14
+
15
+ unless ActiveRecord::Base.connection.table_exists? 'blocks'
16
+ if Rails::VERSION::STRING < '4.0'
17
+ CreateBlocks.migrate(:up)
18
+ else
19
+ ActiveRecord::Migration.run(CreateBlocks)
20
+ end
21
+ end
22
+
23
+ class RailsTestApp < Rails::Application
24
+ routes.append do
25
+ get "/test/world" => "test#world"
26
+ get "/test/db" => "test#db"
27
+ get "/test/error" => "test#error"
28
+ get "/test/render_view" => "test#render_view"
29
+ get "/test/render_partial" => "test#render_partial"
30
+ get "/test/render_collection" => "test#render_collection"
31
+ get "/test/render_file" => "test#render_file"
32
+ get "/test/render_nothing" => "test#render_nothing"
33
+ get "/test/render_json" => "test#render_json"
34
+ get "/test/render_xml" => "test#render_xml"
35
+ get "/test/render_rawbody" => "test#render_rawbody"
36
+ get "/test/render_js" => "test#render_js"
37
+ get "/test/render_alternate_layout" => "test#render_alternate_layout"
38
+ get "/test/render_partial_that_errors" => "test#render_partial_that_errors"
39
+
40
+ get "/api/world" => "socket#world"
41
+ get "/api/error" => "socket#error"
42
+ end
43
+
44
+ # Enable cache classes. Production style.
45
+ config.cache_classes = true
46
+ config.eager_load = false
47
+
48
+ # uncomment below to display errors
49
+ # config.consider_all_requests_local = true
50
+
51
+ config.paths['app/views'].unshift(File.expand_path(File.dirname(__FILE__) + '/../views'))
52
+
53
+ config.active_support.deprecation = :stderr
54
+
55
+ config.middleware.delete Rack::Lock
56
+ config.middleware.delete ActionDispatch::Flash
57
+
58
+ # We need a secret token for session, cookies, etc.
59
+ config.secret_token = "doesntneedtobesecurefortests"
60
+ config.secret_key_base = "blueredaquarossoseven"
61
+ end
62
+
63
+ class TestController < ActionController::Base
64
+ def world
65
+ if ::Rails::VERSION::MAJOR > 4
66
+ render :plain => "Hello test world!"
67
+ else
68
+ render :text => "Hello test world!"
69
+ end
70
+ end
71
+
72
+ def db
73
+ white_block = Block.new(:name => 'Part #28349', :color => 'White')
74
+ white_block.save
75
+ found = Block.where(:name => 'Part #28349').first
76
+ found.delete
77
+
78
+ if ::Rails::VERSION::MAJOR > 4
79
+ render :plain => "Hello test db!"
80
+ else
81
+ render :text => "Hello test db!"
82
+ end
83
+ end
84
+
85
+ def render_view
86
+ @message = "Hello Instana!"
87
+ end
88
+
89
+ def render_partial
90
+ @message = "Hello Instana!"
91
+ end
92
+
93
+ def render_partial_that_errors
94
+ @message = "Hello Instana!"
95
+ end
96
+
97
+ def render_collection
98
+ @blocks = Block.all
99
+ end
100
+
101
+ def render_file
102
+ @message = "Hello Instana!"
103
+ render :file => '/etc/issue'
104
+ end
105
+
106
+ def render_alternate_layout
107
+ @message = "Hello Instana!"
108
+ render :layout => 'layouts/mobile'
109
+ end
110
+
111
+ def render_nothing
112
+ @message = "Hello Instana!"
113
+ render :nothing => true
114
+ end
115
+
116
+ def render_json
117
+ @message = "Hello Instana!"
118
+ render :json => @message
119
+ end
120
+
121
+ def render_xml
122
+ @message = "Hello Instana!"
123
+ render :xml => @message
124
+ end
125
+
126
+ def render_rawbody
127
+ @message = "Hello Instana!"
128
+ render :body => 'raw body output'
129
+ end
130
+
131
+ def render_js
132
+ @message = "Hello Instana!"
133
+ render :js => @message
134
+ end
135
+
136
+ def error
137
+ raise Exception.new("Warning: This is a simulated Error")
138
+ end
139
+ end
140
+
141
+ if ::Rails::VERSION::MAJOR > 4
142
+ class SocketController < ActionController::API
143
+ def world
144
+ if ::Rails::VERSION::MAJOR > 4
145
+ render :plain => "Hello api world!"
146
+ else
147
+ render :text => "Hello api world!"
148
+ end
149
+ end
150
+
151
+ def error
152
+ raise Exception.new("Warning: This is a simulated Socket API Error")
153
+ end
154
+ end
155
+ end
156
+
157
+ RailsTestApp.initialize!
158
+
159
+ # Initialize some blocks so we have stuff to test against.
160
+ Block.new(:name => :corner, :color => :blue).save
161
+ Block.new(:name => :floor, :color => :green).save
162
+
163
+ Thread.new do
164
+ Rack::Handler::Puma.run(RailsTestApp.to_app, {:Host => '127.0.0.1', :Port => 3205})
165
+ end
166
+
167
+ sleep(1)
@@ -0,0 +1,27 @@
1
+ require 'sidekiq/launcher'
2
+ require 'sidekiq/cli'
3
+ require 'sidekiq/api'
4
+ require 'sidekiq/processor'
5
+
6
+ require Dir.pwd + '/test/jobs/sidekiq_job_1.rb'
7
+ require Dir.pwd + '/test/jobs/sidekiq_job_2.rb'
8
+
9
+ ::Instana.logger.info "Booting instrumented sidekiq worker for tests."
10
+ ::Sidekiq.logger.level = ::Logger::FATAL
11
+
12
+ sidekiq_thread = Thread.new do
13
+ launcher = ::Sidekiq::Launcher.new(
14
+ ::Sidekiq.options.merge(
15
+ queues: ['important'],
16
+ concurrency: 2
17
+ )
18
+ )
19
+ launcher.run
20
+ Thread.current[:worker] = launcher
21
+ end
22
+
23
+ Minitest.after_run do
24
+ ::Instana.logger.info "Killing Sidekiq worker"
25
+ sidekiq_thread[:worker].stop
26
+ sleep 1
27
+ end
@@ -0,0 +1,145 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ ENV['INSTANA_TEST'] = 'true'
3
+ require "rubygems"
4
+ require "bundler/setup"
5
+ Bundler.require(:default, :test)
6
+
7
+ require "minitest/spec"
8
+ require "minitest/autorun"
9
+ require "minitest/reporters"
10
+ require "minitest/debugger" if ENV['DEBUG']
11
+ require "minitest/benchmark"
12
+ require 'webmock/minitest'
13
+
14
+ require "instana/test"
15
+ ::Instana::Test.setup_environment
16
+
17
+ # Webmock: Whitelist local IPs
18
+ whitelist = ['127.0.0.1', 'localhost', '172.17.0.1', '172.0.12.100']
19
+ allowed_sites = lambda{|uri|
20
+ whitelist.include?(uri.host)
21
+ }
22
+ ::WebMock.disable_net_connect!(allow: allowed_sites)
23
+
24
+ # Boot background webservers to test against.
25
+ require "./test/servers/rackapp_6511"
26
+
27
+ case File.basename(ENV['BUNDLE_GEMFILE'])
28
+ when /rails50|rails42|rails32/
29
+ require './test/servers/rails_3205'
30
+ when /libraries/
31
+ # Configure gRPC
32
+ require './test/servers/grpc_50051.rb'
33
+
34
+ # Hook into sidekiq to control the current mode
35
+ $sidekiq_mode = :client
36
+ class << Sidekiq
37
+ def server?
38
+ $sidekiq_mode == :server
39
+ end
40
+ end
41
+
42
+ ENV['I_REDIS_URL'] ||= 'redis://127.0.0.1:6379'
43
+
44
+ # Configure redis for sidekiq client
45
+ Sidekiq.configure_client do |config|
46
+ config.redis = { url: ENV['I_REDIS_URL'] }
47
+ end
48
+
49
+ # Configure redis for sidekiq worker
50
+ $sidekiq_mode = :server
51
+ ::Sidekiq.configure_server do |config|
52
+ config.redis = { url: ENV['I_REDIS_URL'] }
53
+ end
54
+ $sidekiq_mode = :client
55
+
56
+ require './test/servers/sidekiq/worker'
57
+ end
58
+
59
+ if defined?(::Redis)
60
+ $redis = Redis.new(url: ENV['I_REDIS_URL'])
61
+ end
62
+
63
+ Minitest::Reporters.use! MiniTest::Reporters::SpecReporter.new
64
+
65
+ # Used to reset the gem to boot state. It clears out any queued and/or staged
66
+ # traces and resets the tracer to no active trace.
67
+ #
68
+ def clear_all!
69
+ ::Instana.processor.clear!
70
+ ::Instana.tracer.clear!
71
+ $redis.flushall if $redis
72
+ nil
73
+ end
74
+
75
+ def disable_redis_instrumentation
76
+ ::Redis::Client.class_eval do
77
+ alias call call_without_instana
78
+ alias call_pipeline call_pipeline_without_instana
79
+ end
80
+ end
81
+
82
+ def enable_redis_instrumentation
83
+ ::Redis::Client.class_eval do
84
+ alias call call_with_instana
85
+ alias call_pipeline call_pipeline_with_instana
86
+ end
87
+ end
88
+
89
+ def validate_sdk_span(json_span, sdk_hash = {}, errored = false, ec = 1)
90
+ assert_equal :sdk, json_span[:n]
91
+ assert json_span.key?(:k)
92
+ assert json_span.key?(:d)
93
+ assert json_span.key?(:ts)
94
+
95
+ for k,v in sdk_hash
96
+ assert_equal v, json_span[:data][:sdk][k]
97
+ end
98
+
99
+ if errored
100
+ assert_equal true, json_span[:error]
101
+ assert_equal 1, json_span[:ec]
102
+ end
103
+ end
104
+
105
+ def find_spans_by_name(spans, name)
106
+ result = []
107
+ for span in spans
108
+ if span[:n] == :sdk
109
+ if span[:data][:sdk][:name] == name
110
+ result << span
111
+ end
112
+ elsif span[:n] == name
113
+ result << span
114
+ end
115
+ end
116
+ if result.empty?
117
+ raise Exception.new("No SDK spans (#{name}) could be found")
118
+ else
119
+ return result
120
+ end
121
+ end
122
+
123
+ def find_first_span_by_name(spans, name)
124
+ for span in spans
125
+ if span[:n] == :sdk
126
+ if span[:data][:sdk][:name] == name
127
+ return span
128
+ end
129
+ else
130
+ if span[:n] == name
131
+ return span
132
+ end
133
+ end
134
+ end
135
+ raise Exception.new("Span (#{name}) not found")
136
+ end
137
+
138
+ def find_span_by_id(spans, id)
139
+ for span in spans
140
+ if span[:s] == id
141
+ return span
142
+ end
143
+ end
144
+ raise Exception.new("Span with id (#{id}) not found")
145
+ end
@@ -0,0 +1,158 @@
1
+ require 'test_helper'
2
+
3
+ class CustomTracingTest < Minitest::Test
4
+ def test_custom_tracing
5
+ clear_all!
6
+
7
+ assert_equal false, ::Instana.tracer.tracing?
8
+ # Start tracing
9
+ ::Instana.tracer.log_start_or_continue(:custom_trace, {:one => 1})
10
+ assert_equal true, ::Instana.tracer.tracing?
11
+ ::Instana.tracer.log_info({:info_logged => 1})
12
+ # End tracing
13
+ ::Instana.tracer.log_end(:custom_trace, {:close_one => 1})
14
+ assert_equal false, ::Instana.tracer.tracing?
15
+
16
+ spans = ::Instana.processor.queued_spans
17
+ assert_equal 1, spans.length
18
+
19
+ first_span = spans.first
20
+ assert_equal :sdk, first_span[:n]
21
+
22
+ assert first_span[:ts].is_a?(Integer)
23
+ assert first_span[:ts] > 0
24
+ assert first_span[:d].is_a?(Integer)
25
+ assert first_span[:d].between?(0, 5)
26
+
27
+ assert first_span.key?(:data)
28
+ assert first_span[:data].key?(:sdk)
29
+ assert first_span[:data][:sdk].key?(:custom)
30
+ assert first_span[:data][:sdk][:custom].key?(:tags)
31
+ assert_equal :custom_trace, first_span[:data][:sdk][:name]
32
+ assert_equal 1, first_span[:data][:sdk][:custom][:tags][:one]
33
+
34
+ assert first_span.key?(:f)
35
+ assert first_span[:f].key?(:e)
36
+ assert first_span[:f].key?(:h)
37
+ assert_equal ::Instana.agent.agent_uuid, first_span[:f][:h]
38
+ end
39
+
40
+ def test_custom_tracing_with_args
41
+ clear_all!
42
+ assert_equal false, ::Instana.tracer.tracing?
43
+
44
+ # Start tracing
45
+ ::Instana.tracer.log_start_or_continue(:rack, :on_trace_start => 1)
46
+ assert_equal true, ::Instana.tracer.tracing?
47
+
48
+ kvs = {}
49
+ kvs[:on_entry_kv] = 1
50
+ kvs[:arguments] = [[1,2,3], "test_arg", :ok]
51
+ kvs[:return] = true
52
+
53
+ ::Instana.tracer.log_entry(:custom_span, kvs)
54
+ ::Instana.tracer.log_info({:on_info_kv => 1})
55
+ ::Instana.tracer.log_exit(:custom_span, :on_exit_kv => 1)
56
+
57
+ # End tracing
58
+ ::Instana.tracer.log_end(:rack, {:on_trace_end => 1})
59
+ assert_equal false, ::Instana.tracer.tracing?
60
+
61
+ spans = ::Instana.processor.queued_spans
62
+ assert_equal 2, spans.length
63
+
64
+ first_span = find_first_span_by_name(spans, :rack)
65
+ second_span = find_first_span_by_name(spans, :custom_span)
66
+
67
+ assert first_span[:ts].is_a?(Integer)
68
+ assert first_span[:ts] > 0
69
+ assert first_span[:d].is_a?(Integer)
70
+ assert first_span[:d].between?(0, 5)
71
+
72
+ assert_equal :rack, first_span[:n]
73
+ assert first_span.key?(:data)
74
+ assert first_span[:data].key?(:on_trace_start)
75
+ assert_equal 1, first_span[:data][:on_trace_start]
76
+ assert first_span[:data].key?(:on_trace_end)
77
+ assert_equal 1, first_span[:data][:on_trace_end]
78
+
79
+ assert_equal :sdk, second_span[:n]
80
+ assert second_span.key?(:data)
81
+ assert second_span[:data].key?(:sdk)
82
+ assert second_span[:data][:sdk].key?(:custom)
83
+ assert second_span[:data][:sdk][:custom].key?(:tags)
84
+ assert :custom_span, second_span[:data][:sdk][:name]
85
+ assert :unknown, second_span[:data][:sdk][:type]
86
+ assert [[1, 2, 3], "test_arg", :ok], second_span[:data][:sdk][:arguments]
87
+ assert true, second_span[:data][:sdk][:return]
88
+ assert_equal 1, second_span[:data][:sdk][:custom][:tags][:on_entry_kv]
89
+ assert_equal 1, second_span[:data][:sdk][:custom][:tags][:on_info_kv]
90
+ assert_equal 1, second_span[:data][:sdk][:custom][:tags][:on_exit_kv]
91
+ end
92
+
93
+ def test_custom_tracing_with_error
94
+ clear_all!
95
+ assert_equal false, ::Instana.tracer.tracing?
96
+
97
+ # Start tracing
98
+ ::Instana.tracer.log_start_or_continue(:rack, :on_trace_start => 1)
99
+ assert_equal true, ::Instana.tracer.tracing?
100
+
101
+ begin
102
+ kvs = {}
103
+ kvs[:on_entry_kv] = 1
104
+ kvs[:arguments] = [[1,2,3], "test_arg", :ok]
105
+ kvs[:return] = true
106
+
107
+ ::Instana.tracer.log_entry(:custom_span, kvs)
108
+ raise "custom tracing error. This is only a test"
109
+ ::Instana.tracer.log_info({:on_info_kv => 1})
110
+ rescue => e
111
+ ::Instana.tracer.log_error(e)
112
+ ensure
113
+ ::Instana.tracer.log_exit(:custom_span, :on_exit_kv => 1)
114
+ end
115
+ ::Instana.tracer.log_end(:rack, {:on_trace_end => 1})
116
+ assert_equal false, ::Instana.tracer.tracing?
117
+
118
+ spans = ::Instana.processor.queued_spans
119
+ assert_equal 2, spans.length
120
+
121
+ first_span = find_first_span_by_name(spans, :rack)
122
+ second_span = find_first_span_by_name(spans, :custom_span)
123
+
124
+ assert first_span[:ts].is_a?(Integer)
125
+ assert first_span[:ts] > 0
126
+ assert first_span[:d].is_a?(Integer)
127
+ assert first_span[:d].between?(0, 5)
128
+
129
+ assert_equal :rack, first_span[:n]
130
+ assert first_span.key?(:data)
131
+ assert first_span[:data].key?(:on_trace_start)
132
+ assert_equal 1, first_span[:data][:on_trace_start]
133
+ assert first_span[:data].key?(:on_trace_end)
134
+ assert_equal 1, first_span[:data][:on_trace_end]
135
+
136
+ assert second_span[:ts].is_a?(Integer)
137
+ assert second_span[:ts] > 0
138
+ assert second_span[:d].is_a?(Integer)
139
+ assert second_span[:d].between?(0, 5)
140
+
141
+ assert_equal :sdk, second_span[:n]
142
+ assert second_span.key?(:data)
143
+ assert second_span[:data].key?(:sdk)
144
+ assert second_span[:data][:sdk].key?(:custom)
145
+ assert second_span[:data][:sdk][:custom].key?(:tags)
146
+ assert :custom_span, second_span[:data][:sdk][:name]
147
+ assert :unknown, second_span[:data][:sdk][:type]
148
+ assert [[1, 2, 3], "test_arg", :ok], second_span[:data][:sdk][:arguments]
149
+ assert true, second_span[:data][:sdk][:return]
150
+ assert_equal 1, second_span[:data][:sdk][:custom][:tags][:on_entry_kv]
151
+ assert !second_span[:data][:sdk][:custom][:tags].key?(:on_info_kv)
152
+ assert_equal 1, second_span[:data][:sdk][:custom][:tags][:on_exit_kv]
153
+
154
+ # Check the error
155
+ assert_equal true, second_span[:error]
156
+ assert_equal 1, second_span[:ec]
157
+ end
158
+ end