instana 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +24 -2
  5. data/Gemfile +2 -22
  6. data/README.md +1 -1
  7. data/Rakefile +15 -0
  8. data/Tracing.md +29 -2
  9. data/gemfiles/libraries.gemfile +50 -0
  10. data/gemfiles/rails32.gemfile +45 -0
  11. data/gemfiles/rails42.gemfile +44 -0
  12. data/gemfiles/rails50.gemfile +44 -0
  13. data/instana.gemspec +6 -8
  14. data/lib/instana/config.rb +7 -5
  15. data/lib/instana/frameworks/instrumentation/abstract_mysql_adapter.rb +55 -0
  16. data/lib/instana/frameworks/instrumentation/action_controller.rb +105 -0
  17. data/lib/instana/frameworks/instrumentation/active_record.rb +22 -0
  18. data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +81 -0
  19. data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +56 -0
  20. data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +71 -0
  21. data/lib/instana/frameworks/rails.rb +5 -0
  22. data/lib/instana/test.rb +40 -0
  23. data/lib/instana/tracer.rb +19 -0
  24. data/lib/instana/tracing/span.rb +3 -3
  25. data/lib/instana/version.rb +1 -1
  26. data/log/.keep +0 -0
  27. data/test/agent/agent_test.rb +139 -0
  28. data/test/apps/cuba.rb +15 -0
  29. data/test/apps/roda.rb +10 -0
  30. data/test/apps/sinatra.rb +5 -0
  31. data/test/config_test.rb +17 -0
  32. data/test/frameworks/cuba_test.rb +44 -0
  33. data/test/frameworks/rack_test.rb +152 -0
  34. data/test/frameworks/rails/actioncontroller_test.rb +123 -0
  35. data/test/frameworks/rails/activerecord3_test.rb +134 -0
  36. data/test/frameworks/rails/activerecord4_test.rb +134 -0
  37. data/test/frameworks/rails/activerecord5_test.rb +90 -0
  38. data/test/frameworks/roda_test.rb +44 -0
  39. data/test/frameworks/sinatra_test.rb +44 -0
  40. data/test/instana_test.rb +27 -0
  41. data/test/instrumentation/dalli_test.rb +274 -0
  42. data/test/instrumentation/excon_test.rb +171 -0
  43. data/test/instrumentation/net-http_test.rb +140 -0
  44. data/test/instrumentation/rest-client_test.rb +61 -0
  45. data/test/models/block.rb +18 -0
  46. data/test/servers/rackapp_6511.rb +20 -0
  47. data/test/servers/rails_3205.rb +95 -0
  48. data/test/test_helper.rb +39 -0
  49. data/test/tracing/custom_test.rb +143 -0
  50. data/test/tracing/id_management_test.rb +96 -0
  51. data/test/tracing/opentracing_test.rb +377 -0
  52. data/test/tracing/trace_test.rb +50 -0
  53. data/test/tracing/tracer_async_test.rb +298 -0
  54. data/test/tracing/tracer_test.rb +202 -0
  55. metadata +114 -4
@@ -0,0 +1,140 @@
1
+ require 'test_helper'
2
+
3
+ class NetHTTPTest < Minitest::Test
4
+ def test_config_defaults
5
+ assert ::Instana.config[:nethttp].is_a?(Hash)
6
+ assert ::Instana.config[:nethttp].key?(:enabled)
7
+ assert_equal true, ::Instana.config[:nethttp][:enabled]
8
+ end
9
+
10
+ def test_block_request
11
+ clear_all!
12
+ WebMock.allow_net_connect!
13
+ url = "http://127.0.0.1:6511/"
14
+
15
+ uri = URI.parse(url)
16
+ req = Net::HTTP::Get.new(uri)
17
+
18
+ response = nil
19
+ Instana.tracer.start_or_continue_trace('net-http-test') do
20
+ Net::HTTP.start(req.uri.hostname, req.uri.port, :open_timeout => 1, :read_timeout => 1) do |http|
21
+ response = http.request(req)
22
+ end
23
+ end
24
+
25
+ assert_equal 2, ::Instana.processor.queue_count
26
+
27
+ traces = Instana.processor.queued_traces
28
+ rs_trace = traces[0]
29
+ http_trace = traces[1]
30
+
31
+ # Net::HTTP trace validation
32
+ assert_equal 2, http_trace.spans.count
33
+ spans = http_trace.spans.to_a
34
+ first_span = spans[0]
35
+ second_span = spans[1]
36
+
37
+ # Span name validation
38
+ assert_equal :sdk, first_span[:n]
39
+ assert_equal :'net-http', second_span[:n]
40
+
41
+ # first_span is the parent of second_span
42
+ assert_equal first_span.id, second_span[:p]
43
+
44
+ # data keys/values
45
+ refute_nil second_span.key?(:data)
46
+ refute_nil second_span[:data].key?(:http)
47
+ assert_equal "http://127.0.0.1:6511/", second_span[:data][:http][:url]
48
+ assert_equal "200", second_span[:data][:http][:status]
49
+ assert second_span.key?(:stack)
50
+
51
+ # Rack server trace validation
52
+ assert_equal 1, rs_trace.spans.count
53
+ rs_span = rs_trace.spans.to_a[0]
54
+
55
+ # Rack server trace should have the same trace ID
56
+ assert_equal http_trace.id, rs_span[:t].to_i
57
+ # Rack server trace should have net-http has parent span
58
+ assert_equal second_span.id, rs_span[:p].to_i
59
+
60
+ WebMock.disable_net_connect!
61
+ end
62
+
63
+ def test_basic_post_without_uri
64
+ clear_all!
65
+ WebMock.allow_net_connect!
66
+
67
+ response = nil
68
+ Instana.tracer.start_or_continue_trace('net-http-test') do
69
+ http = Net::HTTP.new("127.0.0.1", 6511)
70
+ response = http.request(Net::HTTP::Post.new("/"))
71
+ end
72
+
73
+ assert_equal 2, ::Instana.processor.queue_count
74
+
75
+ traces = Instana.processor.queued_traces
76
+ rs_trace = traces[0]
77
+ http_trace = traces[1]
78
+
79
+ # Net::HTTP trace validation
80
+ assert_equal 2, http_trace.spans.count
81
+ spans = http_trace.spans.to_a
82
+ first_span = spans[0]
83
+ second_span = spans[1]
84
+
85
+ # Span name validation
86
+ assert_equal :sdk, first_span[:n]
87
+ assert_equal :'net-http', second_span[:n]
88
+
89
+ # first_span is the parent of second_span
90
+ assert_equal first_span.id, second_span[:p]
91
+
92
+ # data keys/values
93
+ refute_nil second_span.key?(:data)
94
+ refute_nil second_span[:data].key?(:http)
95
+ assert_equal "http://127.0.0.1:6511/", second_span[:data][:http][:url]
96
+ assert_equal "200", second_span[:data][:http][:status]
97
+ assert second_span.key?(:stack)
98
+
99
+ # Rack server trace validation
100
+ assert_equal 1, rs_trace.spans.count
101
+ rs_span = rs_trace.spans.to_a[0]
102
+
103
+ # Rack server trace should have the same trace ID
104
+ assert_equal http_trace.id, rs_span[:t].to_i
105
+ # Rack server trace should have net-http has parent span
106
+ assert_equal second_span.id, rs_span[:p].to_i
107
+
108
+ WebMock.disable_net_connect!
109
+ end
110
+
111
+ def test_request_with_dns_error
112
+ clear_all!
113
+ WebMock.allow_net_connect!
114
+
115
+ begin
116
+ Instana.tracer.start_or_continue_trace('net-http-error-test') do
117
+ http = Net::HTTP.new("asdfasdf.asdfsadf", 80)
118
+ http.request(Net::HTTP::Get.new("/blah"))
119
+ end
120
+ rescue Exception
121
+ nil
122
+ end
123
+
124
+ traces = Instana.processor.queued_traces
125
+ assert_equal 1, traces.count
126
+ t = traces[0]
127
+ assert_equal 1, t.spans.count
128
+ assert t.has_error?
129
+ spans = t.spans.to_a
130
+ first_span = spans[0]
131
+
132
+ assert_equal :'net-http-error-test', first_span.name
133
+ assert first_span.custom?
134
+ assert first_span[:data][:sdk][:custom].key?(:log)
135
+ assert first_span[:data][:sdk][:custom][:log].key?(:message)
136
+ assert first_span[:data][:sdk][:custom][:log].key?(:parameters)
137
+
138
+ WebMock.disable_net_connect!
139
+ end
140
+ end
@@ -0,0 +1,61 @@
1
+ require 'test_helper'
2
+
3
+ class RestClientTest < Minitest::Test
4
+ def test_config_defaults
5
+ assert ::Instana.config[:'rest-client'].is_a?(Hash)
6
+ assert ::Instana.config[:'rest-client'].key?(:enabled)
7
+ assert_equal true, ::Instana.config[:'rest-client'][:enabled]
8
+ end
9
+
10
+ def test_basic_get
11
+ clear_all!
12
+ WebMock.allow_net_connect!
13
+
14
+ url = "http://127.0.0.1:6511/"
15
+
16
+ Instana.tracer.start_or_continue_trace('restclient-test') do
17
+ RestClient.get url
18
+ end
19
+
20
+ assert_equal 2, ::Instana.processor.queue_count
21
+
22
+ traces = Instana.processor.queued_traces
23
+ rs_trace = traces[0]
24
+ http_trace = traces[1]
25
+
26
+ # RestClient trace validation
27
+ assert_equal 3, http_trace.spans.count
28
+ spans = http_trace.spans.to_a
29
+ first_span = spans[0]
30
+ second_span = spans[1]
31
+ third_span = spans[2]
32
+
33
+ # Span name validation
34
+ assert first_span.custom?
35
+ assert_equal :"restclient-test", first_span.name
36
+ assert_equal :"rest-client", second_span.name
37
+ assert_equal :"net-http", third_span.name
38
+
39
+ # first_span is the parent of second_span
40
+ assert_equal first_span.id, second_span[:p]
41
+ # second_span is parent of third_span
42
+ assert_equal second_span.id, third_span[:p]
43
+
44
+ # data keys/values
45
+ refute_nil third_span.key?(:data)
46
+ refute_nil third_span[:data].key?(:http)
47
+ assert_equal "http://127.0.0.1:6511/", third_span[:data][:http][:url]
48
+ assert_equal "200", third_span[:data][:http][:status]
49
+
50
+ # Rack server trace validation
51
+ assert_equal 1, rs_trace.spans.count
52
+ rs_span = rs_trace.spans.to_a[0]
53
+
54
+ # Rack server trace should have the same trace ID
55
+ assert_equal http_trace.id, rs_span[:t].to_i
56
+ # Rack server trace should have net-http has parent span
57
+ assert_equal third_span.id, rs_span[:p].to_i
58
+
59
+ WebMock.disable_net_connect!
60
+ end
61
+ end
@@ -0,0 +1,18 @@
1
+ class Block < ActiveRecord::Base
2
+ def do_work(*args)
3
+ block = Block.first
4
+ block.name = "Charlie"
5
+ block.color = "Black"
6
+ block.save
7
+ end
8
+ end
9
+
10
+ class CreateBlocks < ActiveRecord::Migration
11
+ def change
12
+ create_table :blocks do |t|
13
+ t.string :name
14
+ t.string :color
15
+ t.timestamps
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ require 'rack/handler/puma'
2
+ require 'rack/builder'
3
+ require 'instana/rack'
4
+
5
+ ::Instana.logger.info "Booting instrumented background Rackapp on port 6511 for tests."
6
+
7
+ Thread.new do
8
+ app = Rack::Builder.new {
9
+ use ::Instana::Rack
10
+ map "/" do
11
+ run Proc.new { |env|
12
+ [200, {"Content-Type" => "application/json"}, ["[\"Stan\",\"is\",\"on\",\"the\",\"scene!\"]"]]
13
+ }
14
+ end
15
+ }
16
+
17
+ Rack::Handler::Puma.run(app, {:Host => '127.0.0.1', :Port => 6511})
18
+ end
19
+
20
+ sleep(2)
@@ -0,0 +1,95 @@
1
+
2
+ ::Instana.logger.warn "Starting background Ruby on Rails application on port 3205"
3
+
4
+ require "rails/all"
5
+ require "action_controller/railtie" # require more if needed
6
+ require 'rack/handler/puma'
7
+ require File.expand_path(File.dirname(__FILE__) + '/../models/block')
8
+
9
+ ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
10
+
11
+ unless ActiveRecord::Base.connection.table_exists? 'blocks'
12
+ if Rails::VERSION::STRING < '4.0'
13
+ CreateBlocks.migrate(:up)
14
+ else
15
+ ActiveRecord::Migration.run(CreateBlocks)
16
+ end
17
+ end
18
+
19
+ class RailsTestApp < Rails::Application
20
+ routes.append do
21
+ get "/test/world" => "test#world"
22
+ get "/test/db" => "test#db"
23
+ get "/test/error" => "test#error"
24
+
25
+ get "/api/world" => "socket#world"
26
+ get "/api/error" => "socket#error"
27
+ end
28
+
29
+ # Enable cache classes. Production style.
30
+ config.cache_classes = true
31
+ config.eager_load = false
32
+
33
+ # uncomment below to display errors
34
+ # config.consider_all_requests_local = true
35
+
36
+ config.active_support.deprecation = :stderr
37
+
38
+ config.middleware.delete Rack::Lock
39
+ config.middleware.delete ActionDispatch::Flash
40
+
41
+ # We need a secret token for session, cookies, etc.
42
+ config.secret_token = "doesntneedtobesecurefortests"
43
+ config.secret_key_base = "blueredaquarossoseven"
44
+ end
45
+
46
+ class TestController < ActionController::Base
47
+ def world
48
+ if ::Rails::VERSION::MAJOR > 4
49
+ render :plain => "Hello test world!"
50
+ else
51
+ render :text => "Hello test world!"
52
+ end
53
+ end
54
+
55
+ def db
56
+ white_block = Block.new(:name => 'Part #28349', :color => 'White')
57
+ white_block.save
58
+ found = Block.where(:name => 'Part #28349').first
59
+ found.delete
60
+
61
+ if ::Rails::VERSION::MAJOR > 4
62
+ render :plain => "Hello test db!"
63
+ else
64
+ render :text => "Hello test db!"
65
+ end
66
+ end
67
+
68
+ def error
69
+ raise Exception.new("Warning: This is a simulated Error")
70
+ end
71
+ end
72
+
73
+ if ::Rails::VERSION::MAJOR > 4
74
+ class SocketController < ActionController::API
75
+ def world
76
+ if ::Rails::VERSION::MAJOR > 4
77
+ render :plain => "Hello api world!"
78
+ else
79
+ render :text => "Hello api world!"
80
+ end
81
+ end
82
+
83
+ def error
84
+ raise Exception.new("Warning: This is a simulated Socket API Error")
85
+ end
86
+ end
87
+ end
88
+
89
+ RailsTestApp.initialize!
90
+
91
+ Thread.new do
92
+ Rack::Handler::Puma.run(RailsTestApp.to_app, {:Host => '127.0.0.1', :Port => 3205})
93
+ end
94
+
95
+ sleep(1)
@@ -0,0 +1,39 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ ENV['INSTANA_GEM_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 'webmock/minitest'
12
+ ::WebMock.disable_net_connect!(allow_localhost: true)
13
+
14
+ require "instana/test"
15
+ ::Instana::Test.setup_environment
16
+
17
+ # Boot background webservers to test against.
18
+ require "./test/servers/rackapp_6511"
19
+
20
+ case File.basename(ENV['BUNDLE_GEMFILE'])
21
+ when /rails50|rails42|rails32/
22
+ require './test/servers/rails_3205'
23
+ end
24
+
25
+ WebMock.disable_net_connect!(allow_localhost: true)
26
+
27
+ Minitest::Reporters.use! MiniTest::Reporters::SpecReporter.new
28
+
29
+ # Set this (or a subset) if you want increased debug output
30
+ #::Instana.logger.debug_level = [ :agent, :agent_comm, :trace ]
31
+
32
+ # Used to reset the gem to boot state. It clears out any queued and/or staged
33
+ # traces and resets the tracer to no active trace.
34
+ #
35
+ def clear_all!
36
+ ::Instana.processor.clear!
37
+ ::Instana.tracer.clear!
38
+ nil
39
+ end
@@ -0,0 +1,143 @@
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(:rack, {:close_one => 1})
14
+ assert_equal false, ::Instana.tracer.tracing?
15
+
16
+ traces = ::Instana.processor.queued_traces
17
+ assert_equal 1, traces.count
18
+ t = traces.first
19
+ assert_equal 1, t.spans.size
20
+ assert t.valid?
21
+
22
+ first_span = t.spans.first
23
+ assert_equal :sdk, first_span[:n]
24
+
25
+ assert first_span.key?(:data)
26
+ assert first_span[:data].key?(:sdk)
27
+ assert first_span[:data][:sdk].key?(:custom)
28
+ assert_equal :custom_trace, first_span[:data][:sdk][:name]
29
+ assert_equal 1, first_span[:data][:sdk][:custom][:one]
30
+ assert_equal :ruby, first_span[:ta]
31
+
32
+ assert first_span.key?(:f)
33
+ assert first_span[:f].key?(:e)
34
+ assert first_span[:f].key?(:h)
35
+ assert_equal ::Instana.agent.agent_uuid, first_span[:f][:h]
36
+ end
37
+
38
+ def test_custom_tracing_with_args
39
+ clear_all!
40
+ assert_equal false, ::Instana.tracer.tracing?
41
+
42
+ # Start tracing
43
+ ::Instana.tracer.log_start_or_continue(:rack, :on_trace_start => 1)
44
+ assert_equal true, ::Instana.tracer.tracing?
45
+
46
+ kvs = {}
47
+ kvs[:on_entry_kv] = 1
48
+ kvs[:arguments] = [[1,2,3], "test_arg", :ok]
49
+ kvs[:return] = true
50
+
51
+ ::Instana.tracer.log_entry(:custom_span, kvs)
52
+ ::Instana.tracer.log_info({:on_info_kv => 1})
53
+ ::Instana.tracer.log_exit(:custom_span, :on_exit_kv => 1)
54
+
55
+ # End tracing
56
+ ::Instana.tracer.log_end(:rack, {:on_trace_end => 1})
57
+ assert_equal false, ::Instana.tracer.tracing?
58
+
59
+ traces = ::Instana.processor.queued_traces
60
+ assert_equal 1, traces.count
61
+ t = traces.first
62
+ assert_equal 2, t.spans.size
63
+ assert t.valid?
64
+
65
+ first_span, second_span = t.spans.to_a
66
+
67
+ assert_equal :rack, first_span[:n]
68
+ assert first_span.key?(:data)
69
+ assert first_span[:data].key?(:on_trace_start)
70
+ assert_equal 1, first_span[:data][:on_trace_start]
71
+ assert first_span[:data].key?(:on_trace_end)
72
+ assert_equal 1, first_span[:data][:on_trace_end]
73
+
74
+ assert_equal :sdk, second_span[:n]
75
+ assert second_span.key?(:data)
76
+ assert second_span[:data].key?(:sdk)
77
+ assert second_span[:data][:sdk].key?(:custom)
78
+ assert :custom_span, second_span[:data][:sdk][:name]
79
+ assert :unknown, second_span[:data][:sdk][:type]
80
+ assert [[1, 2, 3], "test_arg", :ok], second_span[:data][:sdk][:arguments]
81
+ assert true, second_span[:data][:sdk][:return]
82
+ assert_equal 1, second_span[:data][:sdk][:custom][:on_entry_kv]
83
+ assert_equal 1, second_span[:data][:sdk][:custom][:on_info_kv]
84
+ assert_equal 1, second_span[:data][:sdk][:custom][:on_exit_kv]
85
+ end
86
+
87
+ def test_custom_tracing_with_error
88
+ clear_all!
89
+ assert_equal false, ::Instana.tracer.tracing?
90
+
91
+ # Start tracing
92
+ ::Instana.tracer.log_start_or_continue(:rack, :on_trace_start => 1)
93
+ assert_equal true, ::Instana.tracer.tracing?
94
+
95
+ begin
96
+ kvs = {}
97
+ kvs[:on_entry_kv] = 1
98
+ kvs[:arguments] = [[1,2,3], "test_arg", :ok]
99
+ kvs[:return] = true
100
+
101
+ ::Instana.tracer.log_entry(:custom_span, kvs)
102
+ raise "custom tracing error. This is only a test"
103
+ ::Instana.tracer.log_info({:on_info_kv => 1})
104
+ rescue => e
105
+ ::Instana.tracer.log_error(e)
106
+ ensure
107
+ ::Instana.tracer.log_exit(:custom_span, :on_exit_kv => 1)
108
+ end
109
+ ::Instana.tracer.log_end(:rack, {:on_trace_end => 1})
110
+ assert_equal false, ::Instana.tracer.tracing?
111
+
112
+ traces = ::Instana.processor.queued_traces
113
+ assert_equal 1, traces.count
114
+ t = traces.first
115
+ assert_equal 2, t.spans.size
116
+ assert t.valid?
117
+
118
+ first_span, second_span = t.spans.to_a
119
+
120
+ assert_equal :rack, first_span[:n]
121
+ assert first_span.key?(:data)
122
+ assert first_span[:data].key?(:on_trace_start)
123
+ assert_equal 1, first_span[:data][:on_trace_start]
124
+ assert first_span[:data].key?(:on_trace_end)
125
+ assert_equal 1, first_span[:data][:on_trace_end]
126
+
127
+ assert_equal :sdk, second_span[:n]
128
+ assert second_span.key?(:data)
129
+ assert second_span[:data].key?(:sdk)
130
+ assert second_span[:data][:sdk].key?(:custom)
131
+ assert :custom_span, second_span[:data][:sdk][:name]
132
+ assert :unknown, second_span[:data][:sdk][:type]
133
+ assert [[1, 2, 3], "test_arg", :ok], second_span[:data][:sdk][:arguments]
134
+ assert true, second_span[:data][:sdk][:return]
135
+ assert_equal 1, second_span[:data][:sdk][:custom][:on_entry_kv]
136
+ assert !second_span[:data][:sdk][:custom].key?(:on_info_kv)
137
+ assert_equal 1, second_span[:data][:sdk][:custom][:on_exit_kv]
138
+
139
+ # Check the error
140
+ assert_equal true, second_span[:error]
141
+ assert_equal 1, second_span[:ec]
142
+ end
143
+ end