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
@@ -1,4 +1,4 @@
1
1
  module Instana
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  VERSION_FULL = "instana-#{VERSION}"
4
4
  end
File without changes
@@ -0,0 +1,139 @@
1
+ require 'test_helper'
2
+
3
+ class AgentTest < Minitest::Test
4
+ def test_agent_host_detection
5
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/"
6
+ stub_request(:get, url)
7
+ assert_equal true, ::Instana.agent.host_agent_ready?
8
+ end
9
+
10
+ def test_successful_discovery
11
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/"
12
+ docker_url = "http://#{::Instana.agent.instance_variable_get(:@default_gateway)}:#{::Instana.config[:agent_port]}/"
13
+ stub_request(:get, url)
14
+ stub_request(:get, docker_url)
15
+ discovered = ::Instana.agent.run_discovery
16
+
17
+ assert discovered.is_a?(Hash)
18
+ assert_equal "127.0.0.1", discovered[:agent_host]
19
+ assert_equal 42699, discovered[:agent_port]
20
+ end
21
+
22
+ def test_failed_discovery
23
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/"
24
+ docker_url = "http://#{::Instana.agent.instance_variable_get(:@default_gateway)}:#{::Instana.config[:agent_port]}/"
25
+ stub_request(:get, url).to_raise(Errno::ECONNREFUSED)
26
+ stub_request(:get, docker_url).to_raise(Errno::ECONNREFUSED)
27
+ discovered = ::Instana.agent.run_discovery
28
+
29
+ assert_equal nil, discovered
30
+ end
31
+
32
+ def test_custom_configure_agent
33
+ original_host = ::Instana.config[:agent_host]
34
+ original_port = ::Instana.config[:agent_port]
35
+
36
+ # Set custom agent/port
37
+ ::Instana.config[:agent_host] = '172.0.12.100'
38
+ ::Instana.config[:agent_port] = 12829
39
+
40
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/"
41
+ stub_request(:get, url)
42
+ discovered = ::Instana.agent.run_discovery
43
+
44
+ assert discovered.is_a?(Hash)
45
+ assert_equal "172.0.12.100", discovered[:agent_host]
46
+ assert_equal 12829, discovered[:agent_port]
47
+
48
+ ::Instana.config[:agent_host] = original_host
49
+ ::Instana.config[:agent_port] = original_port
50
+ end
51
+
52
+ def test_no_host_agent
53
+ localhost_url = "http://#{::Instana::Agent::LOCALHOST}:#{::Instana.config[:agent_port]}/"
54
+ stub_request(:get, localhost_url).to_raise(Errno::ECONNREFUSED)
55
+ docker_url = "http://#{::Instana.agent.instance_variable_get(:@default_gateway)}:#{::Instana.config[:agent_port]}/"
56
+ stub_request(:get, docker_url).to_timeout
57
+ assert_equal false, ::Instana.agent.host_agent_ready?
58
+ end
59
+
60
+ def test_announce_sensor
61
+ # Fake discovery values
62
+ discovery = {}
63
+ discovery[:agent_host] = ::Instana.config[:agent_host]
64
+ discovery[:agent_port] = ::Instana.config[:agent_port]
65
+ ::Instana.agent.instance_variable_set(:@discovered, discovery)
66
+
67
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/com.instana.plugin.ruby.discovery"
68
+ json = { 'pid' => Process.pid, 'agentUuid' => 'abc' }.to_json
69
+ stub_request(:put, url).to_return(:body => json, :status => 200)
70
+
71
+ assert_equal true, ::Instana.agent.announce_sensor
72
+ end
73
+
74
+ def test_failed_announce_sensor
75
+ # Fake discovery values
76
+ discovery = {}
77
+ discovery[:agent_host] = ::Instana.config[:agent_host]
78
+ discovery[:agent_port] = ::Instana.config[:agent_port]
79
+ ::Instana.agent.instance_variable_set(:@discovered, discovery)
80
+
81
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/com.instana.plugin.ruby.discovery"
82
+ stub_request(:put, url).to_raise(Errno::ECONNREFUSED)
83
+
84
+ assert_equal false, ::Instana.agent.announce_sensor
85
+ end
86
+
87
+ def test_metric_report
88
+ # Fake discovery values
89
+ discovery = {}
90
+ discovery[:agent_host] = ::Instana.config[:agent_host]
91
+ discovery[:agent_port] = ::Instana.config[:agent_port]
92
+ ::Instana.agent.instance_variable_set(:@discovered, discovery)
93
+
94
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/com.instana.plugin.ruby.discovery"
95
+ json = { 'pid' => Process.pid, 'agentUuid' => 'abc' }.to_json
96
+ stub_request(:put, url).to_return(:body => json, :status => 200)
97
+ ::Instana.agent.announce_sensor
98
+
99
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/com.instana.plugin.ruby.#{Process.pid}"
100
+ stub_request(:post, url)
101
+
102
+ payload = { :test => 'true' }
103
+ assert_equal true, ::Instana.agent.report_metrics(payload)
104
+ end
105
+
106
+ def test_failed_metric_report
107
+ # Fake discovery values
108
+ discovery = {}
109
+ discovery[:agent_host] = ::Instana.config[:agent_host]
110
+ discovery[:agent_port] = ::Instana.config[:agent_port]
111
+ ::Instana.agent.instance_variable_set(:@discovered, discovery)
112
+
113
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/com.instana.plugin.ruby.discovery"
114
+ json = { 'pid' => Process.pid, 'agentUuid' => 'abc' }.to_json
115
+ stub_request(:put, url).to_return(:body => json, :status => 200)
116
+
117
+ ::Instana.agent.announce_sensor
118
+
119
+ url = "http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/com.instana.plugin.ruby.#{Process.pid}"
120
+ stub_request(:post, url).to_raise(Errno::ECONNREFUSED)
121
+
122
+ payload = { :test => 'true' }
123
+ assert_equal false, ::Instana.agent.report_metrics(payload)
124
+ end
125
+
126
+ def test_agent_timeout
127
+ # Fake discovery values
128
+ discovery = {}
129
+ discovery[:agent_host] = ::Instana.config[:agent_host]
130
+ discovery[:agent_port] = ::Instana.config[:agent_port]
131
+ ::Instana.agent.instance_variable_set(:@discovered, discovery)
132
+
133
+ localhost_url = "http://#{::Instana::Agent::LOCALHOST}:#{::Instana.config[:agent_port]}/"
134
+ stub_request(:get, localhost_url).to_timeout
135
+ docker_url = "http://#{::Instana.agent.instance_variable_get(:@default_gateway)}:#{::Instana.config[:agent_port]}/"
136
+ stub_request(:get, docker_url).to_timeout
137
+ assert_equal false, ::Instana.agent.host_agent_ready?
138
+ end
139
+ end
@@ -0,0 +1,15 @@
1
+ require "cuba/safe"
2
+
3
+ Cuba.plugin ::Cuba::Safe
4
+
5
+ Cuba.define do
6
+ on get do
7
+ on "hello" do
8
+ res.write "Hello Instana!"
9
+ end
10
+
11
+ on root do
12
+ res.redirect '/hello'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ class InstanaRodaApp < Roda
2
+ route do |r|
3
+ r.root do
4
+ r.redirect '/hello'
5
+ end
6
+ r.get "hello" do
7
+ "Hello Roda + Instana"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class InstanaSinatraApp < ::Sinatra::Base
2
+ get '/' do
3
+ "Hello Sinatra!"
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+
3
+ class ConfigTest < Minitest::Test
4
+ def test_that_config_exists
5
+ refute_nil ::Instana.config
6
+ assert_instance_of(::Instana::Config, ::Instana.config)
7
+ end
8
+
9
+ def test_that_it_has_defaults
10
+ assert_equal '127.0.0.1', ::Instana.config[:agent_host]
11
+ assert_equal 42699, ::Instana.config[:agent_port]
12
+
13
+ ::Instana.config[:metrics].each do |k, v|
14
+ assert_equal true, ::Instana.config[:metrics][k].key?(:enabled)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,44 @@
1
+
2
+ if defined?(::Cuba)
3
+ require 'test_helper'
4
+ require File.expand_path(File.dirname(__FILE__) + '/../apps/cuba')
5
+ require 'rack/test'
6
+
7
+ class CubaTest < Minitest::Test
8
+ include Rack::Test::Methods
9
+
10
+ def app
11
+ Cuba
12
+ end
13
+
14
+ def test_basic_get
15
+ clear_all!
16
+
17
+ r = get '/hello'
18
+ assert last_response.ok?
19
+
20
+ assert r.headers.key?("X-Instana-T")
21
+ assert r.headers.key?("X-Instana-S")
22
+
23
+ spans = ::Instana.processor.queued_spans
24
+ assert_equal 1, spans.count
25
+
26
+ first_span = spans.first
27
+ assert_equal :rack, first_span[:n]
28
+ assert first_span.key?(:data)
29
+ assert first_span[:data].key?(:http)
30
+
31
+ assert first_span[:data][:http].key?(:method)
32
+ assert_equal "GET", first_span[:data][:http][:method]
33
+
34
+ assert first_span[:data][:http].key?(:url)
35
+ assert_equal "/hello", first_span[:data][:http][:url]
36
+
37
+ assert first_span[:data][:http].key?(:status)
38
+ assert_equal 200, first_span[:data][:http][:status]
39
+
40
+ assert first_span[:data][:http].key?(:host)
41
+ assert_equal "example.org", first_span[:data][:http][:host]
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,152 @@
1
+ require 'test_helper'
2
+ require 'rack/test'
3
+ require 'rack/lobster'
4
+ require "instana/rack"
5
+
6
+ class RackTest < Minitest::Test
7
+ include Rack::Test::Methods
8
+
9
+ def app
10
+ @app = Rack::Builder.new {
11
+ use Rack::CommonLogger
12
+ use Rack::ShowExceptions
13
+ use Instana::Rack
14
+ map "/mrlobster" do
15
+ run Rack::Lobster.new
16
+ end
17
+ }
18
+ end
19
+
20
+ def test_basic_get
21
+ clear_all!
22
+ get '/mrlobster'
23
+ assert last_response.ok?
24
+
25
+ spans = ::Instana.processor.queued_spans
26
+
27
+ # Span validation
28
+ assert_equal 1, spans.count
29
+
30
+ first_span = spans.first
31
+ assert_equal :rack, first_span[:n]
32
+ assert_equal :ruby, first_span[:ta]
33
+ assert first_span.key?(:data)
34
+ assert first_span[:data].key?(:http)
35
+ assert_equal "GET", first_span[:data][:http][:method]
36
+ assert_equal "/mrlobster", first_span[:data][:http][:url]
37
+ assert_equal 200, first_span[:data][:http][:status]
38
+ assert_equal 'example.org', first_span[:data][:http][:host]
39
+ assert first_span.key?(:f)
40
+ assert first_span[:f].key?(:e)
41
+ assert first_span[:f].key?(:h)
42
+ assert_equal ::Instana.agent.agent_uuid, first_span[:f][:h]
43
+
44
+ # Backtrace fingerprint validation
45
+ assert first_span.key?(:stack)
46
+ assert_equal 2, first_span[:stack].count
47
+ refute_nil first_span[:stack].first[:f].match(/instana\/instrumentation\/rack.rb/)
48
+ end
49
+
50
+ def test_basic_post
51
+ clear_all!
52
+ post '/mrlobster'
53
+ assert last_response.ok?
54
+
55
+ spans = ::Instana.processor.queued_spans
56
+
57
+ # Span validation
58
+ assert_equal 1, spans.count
59
+ first_span = spans.first
60
+ assert_equal :rack, first_span[:n]
61
+ assert_equal :ruby, first_span[:ta]
62
+ assert first_span.key?(:data)
63
+ assert first_span[:data].key?(:http)
64
+ assert_equal "POST", first_span[:data][:http][:method]
65
+ assert_equal "/mrlobster", first_span[:data][:http][:url]
66
+ assert_equal 200, first_span[:data][:http][:status]
67
+ assert first_span.key?(:f)
68
+ assert first_span[:f].key?(:e)
69
+ assert first_span[:f].key?(:h)
70
+ assert_equal ::Instana.agent.agent_uuid, first_span[:f][:h]
71
+ end
72
+
73
+ def test_basic_put
74
+ clear_all!
75
+ put '/mrlobster'
76
+ assert last_response.ok?
77
+
78
+ spans = ::Instana.processor.queued_spans
79
+
80
+ # Span validation
81
+ assert_equal 1, spans.count
82
+ first_span = spans.first
83
+ assert_equal :rack, first_span[:n]
84
+ assert_equal :ruby, first_span[:ta]
85
+ assert first_span.key?(:data)
86
+ assert first_span[:data].key?(:http)
87
+ assert_equal "PUT", first_span[:data][:http][:method]
88
+ assert_equal "/mrlobster", first_span[:data][:http][:url]
89
+ assert_equal 200, first_span[:data][:http][:status]
90
+ assert first_span.key?(:f)
91
+ assert first_span[:f].key?(:e)
92
+ assert first_span[:f].key?(:h)
93
+ assert_equal ::Instana.agent.agent_uuid, first_span[:f][:h]
94
+ end
95
+
96
+ def test_context_continuation
97
+ clear_all!
98
+ header 'X-INSTANA-T', Instana::Util.id_to_header(1234)
99
+ header 'X-INSTANA-S', Instana::Util.id_to_header(4321)
100
+
101
+ get '/mrlobster'
102
+ assert last_response.ok?
103
+
104
+ spans = ::Instana.processor.queued_spans
105
+
106
+ # Span validation
107
+ assert_equal 1, spans.count
108
+ first_span = spans.first
109
+ assert_equal :rack, first_span[:n]
110
+ assert_equal :ruby, first_span[:ta]
111
+ assert first_span.key?(:data)
112
+ assert first_span[:data].key?(:http)
113
+ assert_equal "GET", first_span[:data][:http][:method]
114
+ assert_equal "/mrlobster", first_span[:data][:http][:url]
115
+ assert_equal 200, first_span[:data][:http][:status]
116
+ assert first_span.key?(:f)
117
+ assert first_span[:f].key?(:e)
118
+ assert first_span[:f].key?(:h)
119
+ assert_equal ::Instana.agent.agent_uuid, first_span[:f][:h]
120
+
121
+ # Context validation
122
+ # The first span should have the passed in trace ID
123
+ # and specify the passed in span ID as it's parent.
124
+ assert_equal 1234, first_span[:t]
125
+ assert_equal 4321, first_span[:p]
126
+ end
127
+
128
+ def test_instana_response_headers
129
+ clear_all!
130
+ get '/mrlobster'
131
+ assert last_response.ok?
132
+
133
+ refute_nil last_response.headers.key?("X-Instana-T")
134
+ refute_nil last_response.headers.key?("X-Instana-S")
135
+ end
136
+
137
+ def test_that_url_params_not_logged
138
+ clear_all!
139
+ get '/mrlobster?blah=2&wilma=1&betty=2;fred=3'
140
+
141
+ traces = ::Instana.processor.queued_traces
142
+ assert_equal 1, traces.count
143
+
144
+ trace = traces[0]
145
+ refute_nil trace.spans.first.key?(:data)
146
+ refute_nil trace.spans.first[:data].key?(:http)
147
+ refute_nil trace.spans.first[:data][:http].key?(:url)
148
+ assert_equal '/mrlobster', trace.spans.first[:data][:http][:url]
149
+
150
+ assert last_response.ok?
151
+ end
152
+ end
@@ -0,0 +1,123 @@
1
+ require 'test_helper'
2
+
3
+ class ActionControllerTest < Minitest::Test
4
+ def test_config_defaults
5
+ assert ::Instana.config[:action_controller].is_a?(Hash)
6
+ assert ::Instana.config[:action_controller].key?(:enabled)
7
+ assert_equal true, ::Instana.config[:action_controller][:enabled]
8
+ end
9
+
10
+ def test_controller_reporting
11
+ clear_all!
12
+
13
+ Net::HTTP.get(URI.parse('http://localhost:3205/test/world'))
14
+
15
+ traces = Instana.processor.queued_traces
16
+ assert_equal 1, traces.count
17
+ trace = traces.first
18
+
19
+ assert_equal 2, trace.spans.count
20
+ spans = trace.spans.to_a
21
+ first_span = spans[0]
22
+ second_span = spans[1]
23
+
24
+ assert_equal :rack, first_span.name
25
+
26
+ assert_equal :actioncontroller, second_span.name
27
+ assert_equal "TestController", second_span[:data][:actioncontroller][:controller]
28
+ assert_equal "world", second_span[:data][:actioncontroller][:action]
29
+ end
30
+
31
+ def test_controller_error
32
+ clear_all!
33
+
34
+ Net::HTTP.get(URI.parse('http://localhost:3205/test/error'))
35
+
36
+ traces = Instana.processor.queued_traces
37
+ assert_equal 1, traces.count
38
+ trace = traces.first
39
+
40
+ assert_equal 2, trace.spans.count
41
+ spans = trace.spans.to_a
42
+ first_span = spans[0]
43
+ second_span = spans[1]
44
+
45
+ assert_equal :rack, first_span.name
46
+
47
+ assert_equal :actioncontroller, second_span.name
48
+ assert_equal "TestController", second_span[:data][:actioncontroller][:controller]
49
+ assert_equal "error", second_span[:data][:actioncontroller][:action]
50
+ assert second_span.key?(:error)
51
+ assert second_span.key?(:stack)
52
+ assert_equal "Warning: This is a simulated Error", second_span[:data][:log][:message]
53
+ assert_equal "Exception", second_span[:data][:log][:parameters]
54
+ end
55
+
56
+ def test_api_controller_reporting
57
+ # Run only when ActionController::API is used/defined
58
+ skip unless defined?(::ActionController::API)
59
+
60
+ clear_all!
61
+
62
+ Net::HTTP.get(URI.parse('http://localhost:3205/api/world'))
63
+
64
+ traces = Instana.processor.queued_traces
65
+ assert_equal 1, traces.count
66
+ trace = traces.first
67
+
68
+ assert_equal 2, trace.spans.count
69
+ spans = trace.spans.to_a
70
+ first_span = spans[0]
71
+ second_span = spans[1]
72
+
73
+ assert_equal :rack, first_span.name
74
+
75
+ assert_equal :actioncontroller, second_span.name
76
+ assert_equal "SocketController", second_span[:data][:actioncontroller][:controller]
77
+ assert_equal "world", second_span[:data][:actioncontroller][:action]
78
+ end
79
+
80
+ def test_api_controller_error
81
+ # Run only when ActionController::API is used/defined
82
+ skip unless defined?(::ActionController::API)
83
+
84
+ clear_all!
85
+
86
+ Net::HTTP.get(URI.parse('http://localhost:3205/api/error'))
87
+
88
+ traces = Instana.processor.queued_traces
89
+ assert_equal 1, traces.count
90
+ trace = traces.first
91
+
92
+ assert_equal 2, trace.spans.count
93
+ spans = trace.spans.to_a
94
+ first_span = spans[0]
95
+ second_span = spans[1]
96
+
97
+ assert_equal :rack, first_span.name
98
+
99
+ assert_equal :actioncontroller, second_span.name
100
+ assert_equal "SocketController", second_span[:data][:actioncontroller][:controller]
101
+ assert_equal "error", second_span[:data][:actioncontroller][:action]
102
+ assert second_span.key?(:error)
103
+ assert second_span.key?(:stack)
104
+ assert_equal "Warning: This is a simulated Socket API Error", second_span[:data][:log][:message]
105
+ assert_equal "Exception", second_span[:data][:log][:parameters]
106
+ end
107
+
108
+ def test_404
109
+ clear_all!
110
+
111
+ Net::HTTP.get(URI.parse('http://localhost:3205/test/404'))
112
+
113
+ traces = Instana.processor.queued_traces
114
+ assert_equal 1, traces.count
115
+ trace = traces.first
116
+
117
+ assert_equal 1, trace.spans.count
118
+ spans = trace.spans.to_a
119
+ first_span = spans[0]
120
+
121
+ assert_equal :rack, first_span.name
122
+ end
123
+ end