traceview 3.0.0-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 (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rubocop.yml +5 -0
  4. data/.travis.yml +58 -0
  5. data/Appraisals +10 -0
  6. data/CHANGELOG.md +490 -0
  7. data/CONFIG.md +16 -0
  8. data/Gemfile +95 -0
  9. data/LICENSE +199 -0
  10. data/README.md +380 -0
  11. data/Rakefile +109 -0
  12. data/examples/DNT.md +35 -0
  13. data/examples/carrying_context.rb +225 -0
  14. data/examples/instrumenting_metal_controller.rb +8 -0
  15. data/examples/puma_on_heroku_config.rb +17 -0
  16. data/examples/tracing_async_threads.rb +125 -0
  17. data/examples/tracing_background_jobs.rb +52 -0
  18. data/examples/tracing_forked_processes.rb +100 -0
  19. data/examples/unicorn_on_heroku_config.rb +28 -0
  20. data/ext/oboe_metal/extconf.rb +61 -0
  21. data/ext/oboe_metal/noop/noop.c +7 -0
  22. data/ext/oboe_metal/src/bson/bson.h +221 -0
  23. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  24. data/ext/oboe_metal/src/oboe.h +275 -0
  25. data/ext/oboe_metal/src/oboe.hpp +352 -0
  26. data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
  27. data/ext/oboe_metal/tests/test.rb +11 -0
  28. data/gemfiles/mongo.gemfile +33 -0
  29. data/gemfiles/moped.gemfile +33 -0
  30. data/get_version.rb +5 -0
  31. data/init.rb +4 -0
  32. data/lib/joboe_metal.rb +206 -0
  33. data/lib/oboe/README +2 -0
  34. data/lib/oboe/backward_compatibility.rb +59 -0
  35. data/lib/oboe/inst/rack.rb +11 -0
  36. data/lib/oboe.rb +7 -0
  37. data/lib/oboe_metal.rb +151 -0
  38. data/lib/rails/generators/traceview/install_generator.rb +76 -0
  39. data/lib/rails/generators/traceview/templates/traceview_initializer.rb +159 -0
  40. data/lib/traceview/api/layerinit.rb +51 -0
  41. data/lib/traceview/api/logging.rb +209 -0
  42. data/lib/traceview/api/memcache.rb +31 -0
  43. data/lib/traceview/api/profiling.rb +50 -0
  44. data/lib/traceview/api/tracing.rb +135 -0
  45. data/lib/traceview/api/util.rb +121 -0
  46. data/lib/traceview/api.rb +18 -0
  47. data/lib/traceview/base.rb +225 -0
  48. data/lib/traceview/config.rb +238 -0
  49. data/lib/traceview/frameworks/grape.rb +97 -0
  50. data/lib/traceview/frameworks/padrino/templates.rb +58 -0
  51. data/lib/traceview/frameworks/padrino.rb +64 -0
  52. data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
  53. data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
  54. data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
  55. data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
  56. data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
  57. data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
  58. data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
  59. data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
  60. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  61. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  62. data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
  63. data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  64. data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
  65. data/lib/traceview/frameworks/rails.rb +145 -0
  66. data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
  67. data/lib/traceview/frameworks/sinatra.rb +95 -0
  68. data/lib/traceview/inst/cassandra.rb +279 -0
  69. data/lib/traceview/inst/dalli.rb +86 -0
  70. data/lib/traceview/inst/em-http-request.rb +99 -0
  71. data/lib/traceview/inst/excon.rb +111 -0
  72. data/lib/traceview/inst/faraday.rb +73 -0
  73. data/lib/traceview/inst/http.rb +87 -0
  74. data/lib/traceview/inst/httpclient.rb +173 -0
  75. data/lib/traceview/inst/memcache.rb +102 -0
  76. data/lib/traceview/inst/memcached.rb +94 -0
  77. data/lib/traceview/inst/mongo.rb +238 -0
  78. data/lib/traceview/inst/moped.rb +474 -0
  79. data/lib/traceview/inst/rack.rb +122 -0
  80. data/lib/traceview/inst/redis.rb +271 -0
  81. data/lib/traceview/inst/resque.rb +192 -0
  82. data/lib/traceview/inst/rest-client.rb +38 -0
  83. data/lib/traceview/inst/sequel.rb +162 -0
  84. data/lib/traceview/inst/typhoeus.rb +102 -0
  85. data/lib/traceview/instrumentation.rb +21 -0
  86. data/lib/traceview/loading.rb +94 -0
  87. data/lib/traceview/logger.rb +41 -0
  88. data/lib/traceview/method_profiling.rb +84 -0
  89. data/lib/traceview/ruby.rb +36 -0
  90. data/lib/traceview/support.rb +113 -0
  91. data/lib/traceview/thread_local.rb +26 -0
  92. data/lib/traceview/util.rb +250 -0
  93. data/lib/traceview/version.rb +16 -0
  94. data/lib/traceview/xtrace.rb +90 -0
  95. data/lib/traceview.rb +62 -0
  96. data/test/frameworks/apps/grape_nested.rb +30 -0
  97. data/test/frameworks/apps/grape_simple.rb +24 -0
  98. data/test/frameworks/apps/padrino_simple.rb +45 -0
  99. data/test/frameworks/apps/sinatra_simple.rb +24 -0
  100. data/test/frameworks/grape_test.rb +142 -0
  101. data/test/frameworks/padrino_test.rb +30 -0
  102. data/test/frameworks/sinatra_test.rb +30 -0
  103. data/test/instrumentation/cassandra_test.rb +380 -0
  104. data/test/instrumentation/dalli_test.rb +171 -0
  105. data/test/instrumentation/em_http_request_test.rb +86 -0
  106. data/test/instrumentation/excon_test.rb +207 -0
  107. data/test/instrumentation/faraday_test.rb +235 -0
  108. data/test/instrumentation/http_test.rb +140 -0
  109. data/test/instrumentation/httpclient_test.rb +296 -0
  110. data/test/instrumentation/memcache_test.rb +251 -0
  111. data/test/instrumentation/memcached_test.rb +226 -0
  112. data/test/instrumentation/mongo_test.rb +462 -0
  113. data/test/instrumentation/moped_test.rb +496 -0
  114. data/test/instrumentation/rack_test.rb +116 -0
  115. data/test/instrumentation/redis_hashes_test.rb +265 -0
  116. data/test/instrumentation/redis_keys_test.rb +318 -0
  117. data/test/instrumentation/redis_lists_test.rb +310 -0
  118. data/test/instrumentation/redis_misc_test.rb +160 -0
  119. data/test/instrumentation/redis_sets_test.rb +293 -0
  120. data/test/instrumentation/redis_sortedsets_test.rb +325 -0
  121. data/test/instrumentation/redis_strings_test.rb +333 -0
  122. data/test/instrumentation/resque_test.rb +62 -0
  123. data/test/instrumentation/rest-client_test.rb +294 -0
  124. data/test/instrumentation/sequel_mysql2_test.rb +326 -0
  125. data/test/instrumentation/sequel_mysql_test.rb +326 -0
  126. data/test/instrumentation/sequel_pg_test.rb +330 -0
  127. data/test/instrumentation/typhoeus_test.rb +285 -0
  128. data/test/minitest_helper.rb +187 -0
  129. data/test/profiling/method_test.rb +198 -0
  130. data/test/servers/rackapp_8101.rb +22 -0
  131. data/test/support/backcompat_test.rb +269 -0
  132. data/test/support/config_test.rb +128 -0
  133. data/test/support/dnt_test.rb +73 -0
  134. data/test/support/liboboe_settings_test.rb +104 -0
  135. data/test/support/xtrace_test.rb +35 -0
  136. data/traceview.gemspec +29 -0
  137. metadata +248 -0
@@ -0,0 +1,226 @@
1
+ require 'minitest_helper'
2
+
3
+ if RUBY_VERSION < '2.0' and not defined?(JRUBY_VERSION)
4
+ describe "Memcached" do
5
+ require 'memcached'
6
+ require 'memcached/rails'
7
+
8
+ before do
9
+ clear_all_traces
10
+ @mc = ::Memcached::Rails.new(:servers => ['127.0.0.1'])
11
+
12
+ # These are standard entry/exit KVs that are passed up with all mongo operations
13
+ @entry_kvs = {
14
+ 'Layer' => 'memcache',
15
+ 'Label' => 'entry' }
16
+
17
+ @info_kvs = {
18
+ 'Layer' => 'memcache',
19
+ 'Label' => 'info' }
20
+
21
+ @exit_kvs = { 'Layer' => 'memcache', 'Label' => 'exit' }
22
+ @collect_backtraces = TraceView::Config[:memcached][:collect_backtraces]
23
+ end
24
+
25
+ after do
26
+ TraceView::Config[:memcached][:collect_backtraces] = @collect_backtraces
27
+ end
28
+
29
+ it 'Stock Memcached should be loaded, defined and ready' do
30
+ defined?(::Memcached).wont_match nil
31
+ defined?(::Memcached::Rails).wont_match nil
32
+ end
33
+
34
+ it 'Memcached should have traceview methods defined' do
35
+ TraceView::API::Memcache::MEMCACHE_OPS.each do |m|
36
+ if ::Memcached.method_defined?(m)
37
+ ::Memcached.method_defined?("#{m}_with_traceview").must_equal true
38
+ end
39
+ ::Memcached::Rails.method_defined?(:get_multi_with_traceview).must_equal true
40
+ end
41
+ end
42
+
43
+ it "should trace set" do
44
+ TraceView::API.start_trace('memcached_test', '', {}) do
45
+ @mc.set('testKey', 'blah')
46
+ end
47
+
48
+ traces = get_all_traces
49
+ traces.count.must_equal 4
50
+
51
+ validate_outer_layers(traces, 'memcached_test')
52
+ validate_event_keys(traces[1], @entry_kvs)
53
+ validate_event_keys(traces[2], @exit_kvs)
54
+
55
+ traces[1]['KVOp'].must_equal "set"
56
+ traces[1]['KVKey'].must_equal "testKey"
57
+ end
58
+
59
+ it "should trace get" do
60
+ @mc.set('testKey', 'blah')
61
+
62
+ TraceView::API.start_trace('memcached_test', '', {}) do
63
+ @mc.get('testKey')
64
+ end
65
+
66
+ traces = get_all_traces
67
+ traces.count.must_equal 4
68
+
69
+ validate_outer_layers(traces, 'memcached_test')
70
+ validate_event_keys(traces[1], @entry_kvs)
71
+ validate_event_keys(traces[2], @exit_kvs)
72
+
73
+ traces[1]['KVOp'].must_equal "get"
74
+ traces[1]['KVKey'].must_equal "testKey"
75
+ end
76
+
77
+ it "should trace get_multi" do
78
+ TraceView::API.start_trace('memcached_test', '', {}) do
79
+ @mc.get_multi(['one', 'two', 'three', 'four', 'five', 'six'])
80
+ end
81
+
82
+ traces = get_all_traces
83
+ traces.count.must_equal 5
84
+
85
+ validate_outer_layers(traces, 'memcached_test')
86
+ validate_event_keys(traces[1], @entry_kvs)
87
+ validate_event_keys(traces[2], @info_kvs)
88
+ validate_event_keys(traces[3], @exit_kvs)
89
+
90
+ traces[1]['KVOp'].must_equal "get_multi"
91
+
92
+ traces[2]['KVKeyCount'].must_equal 6
93
+ traces[2].has_key?('KVHitCount').must_equal true
94
+ end
95
+
96
+ it "should trace add for existing key" do
97
+ @mc.set('testKey', 'x', 1200)
98
+
99
+ TraceView::API.start_trace('memcached_test', '', {}) do
100
+ @mc.add('testKey', 'x', 1200)
101
+ end
102
+
103
+ traces = get_all_traces
104
+ traces.count.must_equal 5
105
+
106
+ validate_outer_layers(traces, 'memcached_test')
107
+ validate_event_keys(traces[1], @entry_kvs)
108
+ validate_event_keys(traces[3], @exit_kvs)
109
+
110
+ traces[1]['KVOp'].must_equal "add"
111
+ traces[1]['KVKey'].must_equal "testKey"
112
+
113
+ traces[2]['ErrorClass'].must_equal "Memcached::NotStored"
114
+ traces[2]['ErrorMsg'].must_equal "Memcached::NotStored"
115
+ end
116
+
117
+ it "should trace append" do
118
+ @mc.set('rawKey', "Peanut Butter ", 600, :raw => true)
119
+ TraceView::API.start_trace('memcached_test', '', {}) do
120
+ @mc.append('rawKey', "Jelly")
121
+ end
122
+
123
+ traces = get_all_traces
124
+ traces.count.must_equal 4
125
+
126
+ validate_outer_layers(traces, 'memcached_test')
127
+ validate_event_keys(traces[1], @entry_kvs)
128
+ validate_event_keys(traces[2], @exit_kvs)
129
+
130
+ traces[1]['KVOp'].must_equal "append"
131
+ traces[1]['KVKey'].must_equal "rawKey"
132
+ end
133
+
134
+ it "should trace decr" do
135
+ @mc.set('some_key_counter', "100", 0, false)
136
+
137
+ TraceView::API.start_trace('memcached_test', '', {}) do
138
+ @mc.decr('some_key_counter', 1)
139
+ end
140
+
141
+ traces = get_all_traces
142
+ traces.count.must_equal 4
143
+
144
+ validate_outer_layers(traces, 'memcached_test')
145
+ validate_event_keys(traces[1], @entry_kvs)
146
+ validate_event_keys(traces[2], @exit_kvs)
147
+
148
+ traces[1]['KVOp'].must_equal "decr"
149
+ traces[1]['KVKey'].must_equal "some_key_counter"
150
+ end
151
+
152
+ it "should trace increment" do
153
+ @mc.set('some_key_counter', "100", 0, false)
154
+
155
+ TraceView::API.start_trace('memcached_test', '', {}) do
156
+ @mc.incr("some_key_counter", 1)
157
+ end
158
+
159
+ traces = get_all_traces
160
+ traces.count.must_equal 4
161
+
162
+ validate_outer_layers(traces, 'memcached_test')
163
+ validate_event_keys(traces[1], @entry_kvs)
164
+ validate_event_keys(traces[2], @exit_kvs)
165
+
166
+ traces[1]['KVOp'].must_equal "incr"
167
+ traces[1]['KVKey'].must_equal "some_key_counter"
168
+ end
169
+
170
+ it "should trace replace" do
171
+ @mc.set('some_key', 'blah')
172
+ TraceView::API.start_trace('memcached_test', '', {}) do
173
+ @mc.replace("some_key", "woop")
174
+ end
175
+
176
+ traces = get_all_traces
177
+ traces.count.must_equal 4
178
+
179
+ validate_outer_layers(traces, 'memcached_test')
180
+ validate_event_keys(traces[1], @entry_kvs)
181
+ validate_event_keys(traces[2], @exit_kvs)
182
+
183
+ traces[1]['KVOp'].must_equal "replace"
184
+ traces[1]['KVKey'].must_equal "some_key"
185
+ end
186
+
187
+ it "should trace delete" do
188
+ @mc.set('some_key', 'blah')
189
+ TraceView::API.start_trace('memcached_test', '', {}) do
190
+ @mc.delete("some_key")
191
+ end
192
+
193
+ traces = get_all_traces
194
+ traces.count.must_equal 4
195
+
196
+ validate_outer_layers(traces, 'memcached_test')
197
+ validate_event_keys(traces[1], @entry_kvs)
198
+ validate_event_keys(traces[2], @exit_kvs)
199
+
200
+ traces[1]['KVOp'].must_equal "delete"
201
+ traces[1]['KVKey'].must_equal "some_key"
202
+ end
203
+
204
+ it "should obey :collect_backtraces setting when true" do
205
+ TraceView::Config[:memcached][:collect_backtraces] = true
206
+
207
+ TraceView::API.start_trace('memcached_test', '', {}) do
208
+ @mc.set('some_key', 1)
209
+ end
210
+
211
+ traces = get_all_traces
212
+ layer_has_key(traces, 'memcache', 'Backtrace')
213
+ end
214
+
215
+ it "should obey :collect_backtraces setting when false" do
216
+ TraceView::Config[:memcached][:collect_backtraces] = false
217
+
218
+ TraceView::API.start_trace('memcached_test', '', {}) do
219
+ @mc.set('some_key', 1)
220
+ end
221
+
222
+ traces = get_all_traces
223
+ layer_doesnt_have_key(traces, 'memcache', 'Backtrace')
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,462 @@
1
+ require 'minitest_helper'
2
+
3
+ if defined?(::BSON::VERSION) and (BSON::VERSION < "2.0")
4
+ describe "Mongo" do
5
+ before do
6
+ clear_all_traces
7
+ @connection = Mongo::Connection.new("localhost", 27017, :slave_ok => true)
8
+ @db = @connection.db("test-#{ENV['RACK_ENV']}")
9
+
10
+ @collections = @db.collection_names
11
+ @db.create_collection("testCollection") unless @collections.include? "testCollection"
12
+
13
+ # These are standard entry/exit KVs that are passed up with all mongo operations
14
+ @entry_kvs = {
15
+ 'Layer' => 'mongo',
16
+ 'Label' => 'entry',
17
+ 'Flavor' => 'mongodb',
18
+ 'Database' => 'test-test',
19
+ 'RemoteHost' => 'localhost',
20
+ 'RemotePort' => '27017' }
21
+
22
+ @exit_kvs = { 'Layer' => 'mongo', 'Label' => 'exit' }
23
+ @collect_backtraces = TraceView::Config[:mongo][:collect_backtraces]
24
+ end
25
+
26
+ after do
27
+ TraceView::Config[:mongo][:collect_backtraces] = @collect_backtraces
28
+ end
29
+
30
+ it 'Stock Mongo should be loaded, defined and ready' do
31
+ defined?(::Mongo).wont_match nil
32
+ defined?(::Mongo::DB).wont_match nil
33
+ defined?(::Mongo::Cursor).wont_match nil
34
+ defined?(::Mongo::Collection).wont_match nil
35
+ end
36
+
37
+ it 'Mongo should have traceview methods defined' do
38
+ TraceView::Inst::Mongo::DB_OPS.each do |m|
39
+ ::Mongo::DB.method_defined?("#{m}_with_traceview").must_equal true
40
+ end
41
+ TraceView::Inst::Mongo::CURSOR_OPS.each do |m|
42
+ ::Mongo::Cursor.method_defined?("#{m}_with_traceview").must_equal true
43
+ end
44
+ TraceView::Inst::Mongo::COLL_WRITE_OPS.each do |m|
45
+ ::Mongo::Collection.method_defined?("#{m}_with_traceview").must_equal true
46
+ end
47
+ TraceView::Inst::Mongo::COLL_QUERY_OPS.each do |m|
48
+ ::Mongo::Collection.method_defined?("#{m}_with_traceview").must_equal true
49
+ end
50
+ TraceView::Inst::Mongo::COLL_INDEX_OPS.each do |m|
51
+ ::Mongo::Collection.method_defined?("#{m}_with_traceview").must_equal true
52
+ end
53
+ ::Mongo::Collection.method_defined?(:traceview_collect).must_equal true
54
+ end
55
+
56
+ it "should trace create_collection" do
57
+ TraceView::API.start_trace('mongo_test', '', {}) do
58
+ @db.create_collection("create_and_drop_collection_test")
59
+ end
60
+
61
+ traces = get_all_traces
62
+ traces.count.must_equal 4
63
+
64
+ validate_outer_layers(traces, 'mongo_test')
65
+ validate_event_keys(traces[1], @entry_kvs)
66
+ validate_event_keys(traces[2], @exit_kvs)
67
+
68
+ traces[1]['QueryOp'].must_equal "create_collection"
69
+ traces[1]['New_Collection_Name'].must_equal "create_and_drop_collection_test"
70
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
71
+ end
72
+
73
+ it "should trace drop_collection" do
74
+ # Create a collection so we have one to drop
75
+ @db.create_collection("create_and_drop_collection_test")
76
+
77
+ TraceView::API.start_trace('mongo_test', '', {}) do
78
+ @db.drop_collection("create_and_drop_collection_test")
79
+ end
80
+
81
+ traces = get_all_traces
82
+ traces.count.must_equal 4
83
+
84
+ validate_outer_layers(traces, 'mongo_test')
85
+ validate_event_keys(traces[1], @entry_kvs)
86
+ validate_event_keys(traces[2], @exit_kvs)
87
+
88
+ traces[1]['QueryOp'].must_equal "drop_collection"
89
+ traces[1]['Collection'].must_equal "create_and_drop_collection_test"
90
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
91
+ end
92
+
93
+ it "should trace count" do
94
+ coll = @db.collection("testCollection")
95
+
96
+ TraceView::API.start_trace('mongo_test', '', {}) do
97
+ coll.count(:query => {:name => "MyName"})
98
+ end
99
+
100
+ traces = get_all_traces
101
+ traces.count.must_equal 6
102
+
103
+ validate_outer_layers(traces, 'mongo_test')
104
+ validate_event_keys(traces[1], @entry_kvs)
105
+ validate_event_keys(traces[2], @exit_kvs)
106
+
107
+ traces[3]['QueryOp'].must_equal "count"
108
+ end
109
+
110
+ it "should trace find_and_modify" do
111
+ coll = @db.collection("testCollection")
112
+
113
+ TraceView::API.start_trace('mongo_test', '', {}) do
114
+ coll.find_and_modify({ :query => { :name => "MyName" }, :update => { :count => 203 }})
115
+ end
116
+
117
+ traces = get_all_traces
118
+ traces.count.must_equal 4
119
+
120
+ validate_outer_layers(traces, 'mongo_test')
121
+ validate_event_keys(traces[1], @entry_kvs)
122
+ validate_event_keys(traces[2], @exit_kvs)
123
+
124
+ traces[1]['Collection'].must_equal "testCollection"
125
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
126
+ traces[1]['QueryOp'].must_equal "find_and_modify"
127
+ traces[1]['Update_Document'].must_equal "{:count=>203}"
128
+ end
129
+
130
+ it "should trace insert" do
131
+ coll = @db.collection("testCollection")
132
+
133
+ TraceView::API.start_trace('mongo_test', '', {}) do
134
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
135
+ coll.insert(doc)
136
+ end
137
+
138
+ traces = get_all_traces
139
+ traces.count.must_equal 4
140
+
141
+ validate_outer_layers(traces, 'mongo_test')
142
+ validate_event_keys(traces[1], @entry_kvs)
143
+ validate_event_keys(traces[2], @exit_kvs)
144
+
145
+ traces[1]['Collection'].must_equal "testCollection"
146
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
147
+ traces[1]['QueryOp'].must_equal "insert"
148
+ # Don't test exact hash value since to_json hash ordering varies between 1.8.7 and 1.9+
149
+ traces[1].has_key?('Query').must_equal true
150
+ end
151
+
152
+ it "should trace map_reduce" do
153
+ coll = @db.collection("testCollection")
154
+
155
+ TraceView::API.start_trace('mongo_test', '', {}) do
156
+ map = "function() { emit(this.name, 1); }"
157
+ reduce = "function(k, vals) { var sum = 0; for(var i in vals) sum += vals[i]; return sum; }"
158
+ coll.map_reduce(map, reduce, { :out => "mr_results", :limit => 100, :read => :primary })
159
+ end
160
+
161
+ traces = get_all_traces
162
+ traces.count.must_equal 4
163
+
164
+ validate_outer_layers(traces, 'mongo_test')
165
+ validate_event_keys(traces[1], @entry_kvs)
166
+ validate_event_keys(traces[2], @exit_kvs)
167
+
168
+ traces[1]['Collection'].must_equal "testCollection"
169
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
170
+ traces[1]['QueryOp'].must_equal "map_reduce"
171
+ traces[1]['Map_Function'].must_equal "function() { emit(this.name, 1); }"
172
+ traces[1]['Reduce_Function'].must_equal "function(k, vals) { var sum = 0; for(var i in vals) sum += vals[i]; return sum; }"
173
+ traces[1]['Limit'].must_equal "100"
174
+ end
175
+
176
+ it "should trace remove" do
177
+ coll = @db.collection("testCollection")
178
+
179
+ TraceView::API.start_trace('mongo_test', '', {}) do
180
+ coll.remove(:name => "SaveOp")
181
+ end
182
+
183
+ traces = get_all_traces
184
+ traces.count.must_equal 4
185
+
186
+ validate_outer_layers(traces, 'mongo_test')
187
+ validate_event_keys(traces[1], @entry_kvs)
188
+ validate_event_keys(traces[2], @exit_kvs)
189
+
190
+ traces[1]['Collection'].must_equal "testCollection"
191
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
192
+ traces[1]['QueryOp'].must_equal "remove"
193
+ traces[1]['Query'].must_equal "{\"name\":\"SaveOp\"}"
194
+ end
195
+
196
+ it "should trace rename" do
197
+ coll = @db.collection("testCollection")
198
+ new_name = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join
199
+
200
+ TraceView::API.start_trace('mongo_test', '', {}) do
201
+ coll.rename(new_name)
202
+ end
203
+
204
+ traces = get_all_traces
205
+ traces.count.must_equal 4
206
+
207
+ validate_outer_layers(traces, 'mongo_test')
208
+ validate_event_keys(traces[1], @entry_kvs)
209
+ validate_event_keys(traces[2], @exit_kvs)
210
+
211
+ traces[1]['Collection'].must_equal "testCollection"
212
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
213
+ traces[1]['QueryOp'].must_equal "rename"
214
+ traces[1]['New_Collection_Name'].must_equal new_name
215
+
216
+ # Clean up after test and set collection name back to original
217
+ coll.rename("testCollection")
218
+ end
219
+
220
+ it "should trace update" do
221
+ coll = @db.collection("testCollection")
222
+
223
+ TraceView::API.start_trace('mongo_test', '', {}) do
224
+ # Two types of update calls
225
+ coll.update({"_id" => 1}, { "$set" => {"name" => "MongoDB Ruby"}}, :multi => true)
226
+
227
+ doc = {"name" => "MyOtherName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
228
+ coll.update({"_id" => 1}, doc)
229
+ end
230
+
231
+ traces = get_all_traces
232
+ traces.count.must_equal 6
233
+
234
+ validate_outer_layers(traces, 'mongo_test')
235
+ validate_event_keys(traces[1], @entry_kvs)
236
+ validate_event_keys(traces[2], @exit_kvs)
237
+
238
+ traces[1]['Collection'].must_equal "testCollection"
239
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
240
+ traces[1]['QueryOp'].must_equal "update"
241
+ traces[1]['Query'].must_equal "{\"_id\":1}"
242
+
243
+ validate_event_keys(traces[3], @entry_kvs)
244
+ validate_event_keys(traces[4], @exit_kvs)
245
+
246
+ traces[3].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
247
+ traces[3]['QueryOp'].must_equal "update"
248
+ traces[3]['Query'].must_equal "{\"_id\":1}"
249
+ end
250
+
251
+ it "should trace distinct" do
252
+ coll = @db.collection("testCollection")
253
+
254
+ TraceView::API.start_trace('mongo_test', '', {}) do
255
+ coll.distinct("count")
256
+ end
257
+
258
+ traces = get_all_traces
259
+ traces.count.must_equal 4
260
+
261
+ validate_outer_layers(traces, 'mongo_test')
262
+ validate_event_keys(traces[1], @entry_kvs)
263
+ validate_event_keys(traces[2], @exit_kvs)
264
+
265
+ traces[1]['Collection'].must_equal "testCollection"
266
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
267
+ traces[1]['QueryOp'].must_equal "distinct"
268
+ end
269
+
270
+ it "should trace find" do
271
+ coll = @db.collection("testCollection")
272
+ result = nil
273
+
274
+ # Insert a doc to assure we get a result
275
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
276
+ coll.insert(doc)
277
+
278
+ # If given an optional block +find+ will yield a Cursor to that block,
279
+ # close the cursor, and then return nil. This guarantees that partially
280
+ # evaluated cursors will be closed. If given no block +find+ returns a
281
+ # cursor.
282
+ # https://github.com/mongodb/mongo-ruby-driver/blob/1.10.1/lib/mongo/collection.rb#L178
283
+
284
+ TraceView::API.start_trace('mongo_test', '', {}) do
285
+ result = coll.find(:name => "MyName", :limit => 1)
286
+ end
287
+
288
+ traces = get_all_traces
289
+ traces.count.must_equal 4
290
+
291
+ validate_outer_layers(traces, 'mongo_test')
292
+ validate_event_keys(traces[1], @entry_kvs)
293
+ validate_event_keys(traces[2], @exit_kvs)
294
+
295
+ result.wont_match nil
296
+ result.is_a?(Mongo::Cursor).must_equal true
297
+ traces[1]['Collection'].must_equal "testCollection"
298
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
299
+ traces[1]['QueryOp'].must_equal "find"
300
+ traces[1].has_key?('Query').must_equal true
301
+ traces[1]['Limit'].must_equal "1"
302
+ end
303
+
304
+ it "should trace find (with block)" do
305
+ coll = @db.collection("testCollection")
306
+ result = []
307
+
308
+ # Insert a doc to assure we get a result
309
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
310
+ coll.insert(doc)
311
+
312
+ # If given an optional block +find+ will yield a Cursor to that block,
313
+ # close the cursor, and then return nil. This guarantees that partially
314
+ # evaluated cursors will be closed. If given no block +find+ returns a
315
+ # cursor.
316
+ # https://github.com/mongodb/mongo-ruby-driver/blob/1.10.1/lib/mongo/collection.rb#L178
317
+
318
+ TraceView::API.start_trace('mongo_test', '', {}) do
319
+ blk = lambda { |x| x }
320
+ result = coll.find(:name => "MyName", :limit => 10, &blk)
321
+ end
322
+
323
+ traces = get_all_traces
324
+ traces.count.must_equal 4
325
+
326
+ validate_outer_layers(traces, 'mongo_test')
327
+ validate_event_keys(traces[1], @entry_kvs)
328
+ validate_event_keys(traces[2], @exit_kvs)
329
+
330
+ result.must_equal nil
331
+ traces[1]['Collection'].must_equal "testCollection"
332
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
333
+ traces[1]['QueryOp'].must_equal "find"
334
+ traces[1].has_key?('Query').must_equal true
335
+ end
336
+
337
+ it "should trace group" do
338
+ coll = @db.collection("testCollection")
339
+
340
+ TraceView::API.start_trace('mongo_test', '', {}) do
341
+ coll.group( :key => :type,
342
+ :cond => { :count => 1 },
343
+ :initial => { :count => 0 },
344
+ :reduce => 'function(obj,prev) { prev.count += obj.c; }')
345
+ end
346
+
347
+ traces = get_all_traces
348
+ traces.count.must_equal 4
349
+
350
+ validate_outer_layers(traces, 'mongo_test')
351
+ validate_event_keys(traces[1], @entry_kvs)
352
+ validate_event_keys(traces[2], @exit_kvs)
353
+
354
+ traces[1]['Collection'].must_equal "testCollection"
355
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
356
+ traces[1]['QueryOp'].must_equal "group"
357
+ # Don't test exact hash value since to_json hash ordering varies between 1.8.7 and 1.9+
358
+ traces[1].has_key?('Query').must_equal true
359
+ end
360
+
361
+ it "should trace create, ensure and drop index" do
362
+ coll = @db.collection("testCollection")
363
+
364
+ TraceView::API.start_trace('mongo_test', '', {}) do
365
+ coll.create_index("i")
366
+ coll.ensure_index("i")
367
+ coll.drop_index("i_1")
368
+ end
369
+
370
+ traces = get_all_traces
371
+ traces.count.must_equal 8
372
+
373
+ validate_outer_layers(traces, 'mongo_test')
374
+ validate_event_keys(traces[1], @entry_kvs)
375
+ validate_event_keys(traces[2], @exit_kvs)
376
+
377
+ traces[1]['Collection'].must_equal "testCollection"
378
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
379
+ traces[1]['QueryOp'].must_equal "create_index"
380
+
381
+ validate_event_keys(traces[3], @entry_kvs)
382
+ validate_event_keys(traces[4], @exit_kvs)
383
+
384
+ traces[3]['Collection'].must_equal "testCollection"
385
+ traces[3].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
386
+ traces[3]['QueryOp'].must_equal "ensure_index"
387
+
388
+ validate_event_keys(traces[5], @entry_kvs)
389
+ validate_event_keys(traces[6], @exit_kvs)
390
+
391
+ traces[5]['Collection'].must_equal "testCollection"
392
+ traces[5].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
393
+ traces[5]['QueryOp'].must_equal "drop_index"
394
+ end
395
+
396
+ it "should trace drop_indexes" do
397
+ coll = @db.collection("testCollection")
398
+
399
+ TraceView::API.start_trace('mongo_test', '', {}) do
400
+ coll.drop_indexes
401
+ end
402
+
403
+ traces = get_all_traces
404
+ traces.count.must_equal 4
405
+
406
+ validate_outer_layers(traces, 'mongo_test')
407
+ validate_event_keys(traces[1], @entry_kvs)
408
+ validate_event_keys(traces[2], @exit_kvs)
409
+
410
+ traces[1]['Collection'].must_equal "testCollection"
411
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
412
+ traces[1]['QueryOp'].must_equal "drop_indexes"
413
+ end
414
+
415
+ it "should trace index_information" do
416
+ coll = @db.collection("testCollection")
417
+
418
+ TraceView::API.start_trace('mongo_test', '', {}) do
419
+ coll.index_information
420
+ end
421
+
422
+ traces = get_all_traces
423
+ traces.count.must_equal 4
424
+
425
+ validate_outer_layers(traces, 'mongo_test')
426
+ validate_event_keys(traces[1], @entry_kvs)
427
+ validate_event_keys(traces[2], @exit_kvs)
428
+
429
+ traces[1]['Collection'].must_equal "testCollection"
430
+ traces[1].has_key?('Backtrace').must_equal TraceView::Config[:mongo][:collect_backtraces]
431
+ traces[1]['QueryOp'].must_equal "index_information"
432
+ end
433
+
434
+ it "should obey :collect_backtraces setting when true" do
435
+ TraceView::Config[:mongo][:collect_backtraces] = true
436
+
437
+ coll = @db.collection("testCollection")
438
+
439
+ TraceView::API.start_trace('mongo_test', '', {}) do
440
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
441
+ coll.insert(doc)
442
+ end
443
+
444
+ traces = get_all_traces
445
+ layer_has_key(traces, 'mongo', 'Backtrace')
446
+ end
447
+
448
+ it "should obey :collect_backtraces setting when false" do
449
+ TraceView::Config[:mongo][:collect_backtraces] = false
450
+
451
+ coll = @db.collection("testCollection")
452
+
453
+ TraceView::API.start_trace('mongo_test', '', {}) do
454
+ doc = {"name" => "MyName", "type" => "MyType", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
455
+ coll.insert(doc)
456
+ end
457
+
458
+ traces = get_all_traces
459
+ layer_doesnt_have_key(traces, 'mongo', 'Backtrace')
460
+ end
461
+ end
462
+ end