traceview 3.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
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,474 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'json'
5
+
6
+ module TraceView
7
+ module Inst
8
+ module Moped
9
+ FLAVOR = 'mongodb'
10
+
11
+ # Moped::Database
12
+ DB_OPS = [:command, :drop]
13
+
14
+ # Moped::Indexes
15
+ INDEX_OPS = [:create, :drop]
16
+
17
+ # Moped::Query
18
+ QUERY_OPS = [:count, :sort, :limit, :distinct, :update, :update_all, :upsert,
19
+ :explain, :modify, :remove, :remove_all]
20
+
21
+ # Moped::Collection
22
+ COLLECTION_OPS = [:drop, :find, :indexes, :insert, :aggregate]
23
+ end
24
+ end
25
+ end
26
+
27
+ if defined?(::Moped) && TraceView::Config[:moped][:enabled]
28
+ TraceView.logger.info '[traceview/loading] Instrumenting moped' if TraceView::Config[:verbose]
29
+
30
+ if defined?(::Moped::Database)
31
+ module ::Moped
32
+ class Database
33
+ include TraceView::Inst::Moped
34
+
35
+ def extract_trace_details(op)
36
+ report_kvs = {}
37
+ begin
38
+ report_kvs[:Flavor] = TraceView::Inst::Moped::FLAVOR
39
+ # FIXME: We're only grabbing the first of potentially multiple servers here
40
+ if ::Moped::VERSION < '2.0.0'
41
+ report_kvs[:RemoteHost], report_kvs[:RemotePort] = session.cluster.seeds.first.split(':')
42
+ else
43
+ report_kvs[:RemoteHost] = session.cluster.seeds.first.address.host
44
+ report_kvs[:RemotePort] = session.cluster.seeds.first.address.port
45
+ end
46
+ report_kvs[:Database] = name
47
+ report_kvs[:QueryOp] = op.to_s
48
+ report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:moped][:collect_backtraces]
49
+ rescue StandardError => e
50
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
51
+ end
52
+ report_kvs
53
+ end
54
+
55
+ def command_with_traceview(command)
56
+ if TraceView.tracing? && !TraceView.layer_op && command.key?(:mapreduce)
57
+ begin
58
+ report_kvs = extract_trace_details(:map_reduce)
59
+ report_kvs[:Map_Function] = command[:map]
60
+ report_kvs[:Reduce_Function] = command[:reduce]
61
+ rescue StandardError => e
62
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
63
+ end
64
+
65
+ TraceView::API.trace('mongo', report_kvs) do
66
+ command_without_traceview(command)
67
+ end
68
+ else
69
+ command_without_traceview(command)
70
+ end
71
+ end
72
+
73
+ def drop_with_traceview
74
+ return drop_without_traceview unless TraceView.tracing?
75
+
76
+ report_kvs = extract_trace_details(:drop_database)
77
+
78
+ TraceView::API.trace('mongo', report_kvs) do
79
+ drop_without_traceview
80
+ end
81
+ end
82
+
83
+ TraceView::Inst::Moped::DB_OPS.each do |m|
84
+ if method_defined?(m)
85
+ class_eval "alias #{m}_without_traceview #{m}"
86
+ class_eval "alias #{m} #{m}_with_traceview"
87
+ else TraceView.logger.warn "[traceview/loading] Couldn't properly instrument moped (#{m}). Partial traces may occur."
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ if defined?(::Moped::Indexes)
95
+ module ::Moped
96
+ class Indexes
97
+ include TraceView::Inst::Moped
98
+
99
+ def extract_trace_details(op)
100
+ report_kvs = {}
101
+ begin
102
+ report_kvs[:Flavor] = TraceView::Inst::Moped::FLAVOR
103
+ # FIXME: We're only grabbing the first of potentially multiple servers here
104
+ if ::Moped::VERSION < '2.0.0'
105
+ report_kvs[:RemoteHost], report_kvs[:RemotePort] = database.session.cluster.seeds.first.split(':')
106
+ else
107
+ report_kvs[:RemoteHost] = database.session.cluster.seeds.first.address.host
108
+ report_kvs[:RemotePort] = database.session.cluster.seeds.first.address.port
109
+ end
110
+ report_kvs[:Database] = database.name
111
+ report_kvs[:QueryOp] = op.to_s
112
+ report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:moped][:collect_backtraces]
113
+ rescue StandardError => e
114
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
115
+ end
116
+ report_kvs
117
+ end
118
+
119
+ def create_with_traceview(key, options = {})
120
+ return create_without_traceview(key, options = {}) unless TraceView.tracing?
121
+
122
+ begin
123
+ # We report :create_index here to be consistent
124
+ # with other mongo implementations
125
+ report_kvs = extract_trace_details(:create_index)
126
+ report_kvs[:Key] = key.to_json
127
+ report_kvs[:Options] = options.to_json
128
+ rescue StandardError => e
129
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
130
+ end
131
+
132
+ TraceView::API.trace('mongo', report_kvs, :create_index) do
133
+ create_without_traceview(key, options = {})
134
+ end
135
+ end
136
+
137
+ def drop_with_traceview(key = nil)
138
+ return drop_without_traceview(key = nil) unless TraceView.tracing?
139
+
140
+ begin
141
+ # We report :drop_indexes here to be consistent
142
+ # with other mongo implementations
143
+ report_kvs = extract_trace_details(:drop_indexes)
144
+ report_kvs[:Key] = key.nil? ? 'all' : key.to_json
145
+ rescue StandardError => e
146
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
147
+ end
148
+
149
+ TraceView::API.trace('mongo', report_kvs) do
150
+ drop_without_traceview(key = nil)
151
+ end
152
+ end
153
+
154
+ TraceView::Inst::Moped::INDEX_OPS.each do |m|
155
+ if method_defined?(m)
156
+ class_eval "alias #{m}_without_traceview #{m}"
157
+ class_eval "alias #{m} #{m}_with_traceview"
158
+ else TraceView.logger.warn "[traceview/loading] Couldn't properly instrument moped (#{m}). Partial traces may occur."
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ if defined?(::Moped::Query)
166
+ module ::Moped
167
+ class Query
168
+ include TraceView::Inst::Moped
169
+
170
+ def extract_trace_details(op)
171
+ report_kvs = {}
172
+ begin
173
+ report_kvs[:Flavor] = TraceView::Inst::Moped::FLAVOR
174
+ # FIXME: We're only grabbing the first of potentially multiple servers here
175
+ if ::Moped::VERSION < '2.0.0'
176
+ report_kvs[:RemoteHost], report_kvs[:RemotePort] = collection.database.session.cluster.seeds.first.split(':')
177
+ else
178
+ report_kvs[:RemoteHost] = collection.database.session.cluster.seeds.first.address.host
179
+ report_kvs[:RemotePort] = collection.database.session.cluster.seeds.first.address.port
180
+ end
181
+ report_kvs[:Database] = collection.database.name
182
+ report_kvs[:Collection] = collection.name
183
+ report_kvs[:QueryOp] = op.to_s
184
+ report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:moped][:collect_backtraces]
185
+ rescue StandardError => e
186
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
187
+ end
188
+ report_kvs
189
+ end
190
+
191
+ def count_with_traceview
192
+ return count_without_traceview unless TraceView.tracing?
193
+
194
+ begin
195
+ report_kvs = extract_trace_details(:count)
196
+ report_kvs[:Query] = selector.empty? ? 'all' : selector.to_json
197
+ rescue StandardError => e
198
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
199
+ end
200
+
201
+ TraceView::API.trace('mongo', report_kvs) do
202
+ count_without_traceview
203
+ end
204
+ end
205
+
206
+ def sort_with_traceview(sort)
207
+ return sort_without_traceview(sort) unless TraceView.tracing?
208
+
209
+ begin
210
+ report_kvs = extract_trace_details(:sort)
211
+ report_kvs[:Query] = selector.empty? ? 'all' : selector.to_json
212
+ report_kvs[:Order] = sort.to_s
213
+ rescue StandardError => e
214
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
215
+ end
216
+
217
+ TraceView::API.trace('mongo', report_kvs) do
218
+ sort_without_traceview(sort)
219
+ end
220
+ end
221
+
222
+ def limit_with_traceview(limit)
223
+ if TraceView.tracing? && !TraceView.tracing_layer_op?(:explain)
224
+ begin
225
+ report_kvs = extract_trace_details(:limit)
226
+ report_kvs[:Query] = selector.empty? ? 'all' : selector.to_json
227
+ report_kvs[:Limit] = limit.to_s
228
+ rescue StandardError => e
229
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
230
+ end
231
+
232
+ TraceView::API.trace('mongo', report_kvs) do
233
+ limit_without_traceview(limit)
234
+ end
235
+ else
236
+ limit_without_traceview(limit)
237
+ end
238
+ end
239
+
240
+ def distinct_with_traceview(key)
241
+ return distinct_without_traceview(key) unless TraceView.tracing?
242
+
243
+ begin
244
+ report_kvs = extract_trace_details(:distinct)
245
+ report_kvs[:Query] = selector.empty? ? 'all' : selector.to_json
246
+ report_kvs[:Key] = key.to_s
247
+ rescue StandardError => e
248
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
249
+ end
250
+
251
+ TraceView::API.trace('mongo', report_kvs) do
252
+ distinct_without_traceview(key)
253
+ end
254
+ end
255
+
256
+ def update_with_traceview(change, flags = nil)
257
+ if TraceView.tracing? && !TraceView.tracing_layer_op?([:update_all, :upsert])
258
+ begin
259
+ report_kvs = extract_trace_details(:update)
260
+ report_kvs[:Flags] = flags.to_s if flags
261
+ report_kvs[:Update_Document] = change.to_json
262
+ rescue StandardError => e
263
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
264
+ end
265
+
266
+ TraceView::API.trace('mongo', report_kvs) do
267
+ update_without_traceview(change, flags = nil)
268
+ end
269
+ else
270
+ update_without_traceview(change, flags = nil)
271
+ end
272
+ end
273
+
274
+ def update_all_with_traceview(change)
275
+ return update_all_without_traceview(change) unless TraceView.tracing?
276
+
277
+ begin
278
+ report_kvs = extract_trace_details(:update_all)
279
+ report_kvs[:Update_Document] = change.to_json
280
+ rescue StandardError => e
281
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
282
+ end
283
+
284
+ TraceView::API.trace('mongo', report_kvs, :update_all) do
285
+ update_all_without_traceview(change)
286
+ end
287
+ end
288
+
289
+ def upsert_with_traceview(change)
290
+ return upsert_without_traceview(change) unless TraceView.tracing?
291
+
292
+ begin
293
+ report_kvs = extract_trace_details(:upsert)
294
+ report_kvs[:Query] = selector.to_json
295
+ report_kvs[:Update_Document] = change.to_json
296
+ rescue StandardError => e
297
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
298
+ end
299
+
300
+ TraceView::API.trace('mongo', report_kvs, :upsert) do
301
+ upsert_without_traceview(change)
302
+ end
303
+ end
304
+
305
+ def explain_with_traceview
306
+ return explain_without_traceview unless TraceView.tracing?
307
+
308
+ begin
309
+ report_kvs = extract_trace_details(:explain)
310
+ report_kvs[:Query] = selector.empty? ? 'all' : selector.to_json
311
+ rescue StandardError => e
312
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
313
+ end
314
+
315
+ TraceView::API.trace('mongo', report_kvs, :explain) do
316
+ explain_without_traceview
317
+ end
318
+ end
319
+
320
+ def modify_with_traceview(change, options = {})
321
+ return modify_without_traceview(change, options) unless TraceView.tracing?
322
+
323
+ begin
324
+ report_kvs = extract_trace_details(:modify)
325
+ report_kvs[:Update_Document] = selector.empty? ? 'all' : selector.to_json
326
+ report_kvs[:Change] = change.to_json
327
+ report_kvs[:Options] = options.to_json
328
+ rescue StandardError => e
329
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
330
+ end
331
+
332
+ TraceView::API.trace('mongo', report_kvs) do
333
+ modify_without_traceview(change, options)
334
+ end
335
+ end
336
+
337
+ def remove_with_traceview
338
+ return remove_without_traceview unless TraceView.tracing?
339
+
340
+ begin
341
+ report_kvs = extract_trace_details(:remove)
342
+ report_kvs[:Query] = selector.to_json
343
+ rescue StandardError => e
344
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
345
+ end
346
+
347
+ TraceView::API.trace('mongo', report_kvs) do
348
+ remove_without_traceview
349
+ end
350
+ end
351
+
352
+ def remove_all_with_traceview
353
+ return remove_all_without_traceview unless TraceView.tracing?
354
+
355
+ begin
356
+ report_kvs = extract_trace_details(:remove_all)
357
+ report_kvs[:Query] = selector.to_json
358
+ rescue StandardError => e
359
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
360
+ end
361
+
362
+ TraceView::API.trace('mongo', report_kvs) do
363
+ remove_all_without_traceview
364
+ end
365
+ end
366
+
367
+ TraceView::Inst::Moped::QUERY_OPS.each do |m|
368
+ if method_defined?(m)
369
+ class_eval "alias #{m}_without_traceview #{m}"
370
+ class_eval "alias #{m} #{m}_with_traceview"
371
+ else TraceView.logger.warn "[traceview/loading] Couldn't properly instrument moped (#{m}). Partial traces may occur."
372
+ end
373
+ end
374
+ end
375
+ end
376
+ end # ::Moped::Query
377
+
378
+ if defined?(::Moped::Collection)
379
+ module ::Moped
380
+ class Collection
381
+ include TraceView::Inst::Moped
382
+
383
+ def extract_trace_details(op)
384
+ report_kvs = {}
385
+ begin
386
+ report_kvs[:Flavor] = TraceView::Inst::Moped::FLAVOR
387
+ # FIXME: We're only grabbing the first of potentially multiple servers here
388
+ if ::Moped::VERSION < '2.0.0'
389
+ report_kvs[:RemoteHost], report_kvs[:RemotePort] = database.session.cluster.seeds.first.split(':')
390
+ else
391
+ report_kvs[:RemoteHost] = database.session.cluster.seeds.first.address.host
392
+ report_kvs[:RemotePort] = database.session.cluster.seeds.first.address.port
393
+ end
394
+ report_kvs[:Database] = database.name
395
+ report_kvs[:Collection] = name
396
+ report_kvs[:QueryOp] = op.to_s
397
+ report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:moped][:collect_backtraces]
398
+ rescue StandardError => e
399
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
400
+ end
401
+ report_kvs
402
+ end
403
+
404
+ def drop_with_traceview
405
+ return drop_without_traceview unless TraceView.tracing?
406
+
407
+ # We report :drop_collection here to be consistent
408
+ # with other mongo implementations
409
+ report_kvs = extract_trace_details(:drop_collection)
410
+
411
+ TraceView::API.trace('mongo', report_kvs) do
412
+ drop_without_traceview
413
+ end
414
+ end
415
+
416
+ def find_with_traceview(selector = {})
417
+ return find_without_traceview(selector) unless TraceView.tracing?
418
+
419
+ begin
420
+ report_kvs = extract_trace_details(:find)
421
+ report_kvs[:Query] = selector.empty? ? 'all' : selector.to_json
422
+ rescue StandardError => e
423
+ TraceView.logger.debug "[traceview/debug] Moped KV collection error: #{e.inspect}"
424
+ end
425
+
426
+ TraceView::API.trace('mongo', report_kvs) do
427
+ find_without_traceview(selector)
428
+ end
429
+ end
430
+
431
+ def indexes_with_traceview
432
+ return indexes_without_traceview unless TraceView.tracing?
433
+
434
+ report_kvs = extract_trace_details(:indexes)
435
+
436
+ TraceView::API.trace('mongo', report_kvs) do
437
+ indexes_without_traceview
438
+ end
439
+ end
440
+
441
+ def insert_with_traceview(documents, flags = nil)
442
+ if TraceView.tracing? && !TraceView.tracing_layer_op?(:create_index)
443
+ report_kvs = extract_trace_details(:insert)
444
+
445
+ TraceView::API.trace('mongo', report_kvs) do
446
+ insert_without_traceview(documents, flags)
447
+ end
448
+ else
449
+ insert_without_traceview(documents, flags)
450
+ end
451
+ end
452
+
453
+ def aggregate_with_traceview(*pipeline)
454
+ return aggregate_without_traceview(pipeline) unless TraceView.tracing?
455
+
456
+ report_kvs = extract_trace_details(:aggregate)
457
+ report_kvs[:Query] = pipeline
458
+
459
+ TraceView::API.trace('mongo', report_kvs) do
460
+ aggregate_without_traceview(pipeline)
461
+ end
462
+ end
463
+
464
+ TraceView::Inst::Moped::COLLECTION_OPS.each do |m|
465
+ if method_defined?(m)
466
+ class_eval "alias #{m}_without_traceview #{m}"
467
+ class_eval "alias #{m} #{m}_with_traceview"
468
+ else TraceView.logger.warn "[traceview/loading] Couldn't properly instrument moped (#{m}). Partial traces may occur."
469
+ end
470
+ end
471
+ end
472
+ end
473
+ end # ::Moped::Collection
474
+ end
@@ -0,0 +1,122 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'uri'
5
+ require 'cgi'
6
+
7
+ module TraceView
8
+ class Rack
9
+ attr_reader :app
10
+
11
+ def initialize(app)
12
+ @app = app
13
+ end
14
+
15
+ def collect(req, env)
16
+ report_kvs = {}
17
+
18
+ begin
19
+ report_kvs['HTTP-Host'] = req.host
20
+ report_kvs['Port'] = req.port
21
+ report_kvs['Proto'] = req.scheme
22
+ report_kvs[:Method] = req.request_method
23
+ report_kvs['AJAX'] = true if req.xhr?
24
+ report_kvs['ClientIP'] = req.ip
25
+
26
+ if TraceView::Config[:rack][:log_args]
27
+ report_kvs['Query-String'] = ::CGI.unescape(req.query_string) unless req.query_string.empty?
28
+ end
29
+
30
+ report_kvs['X-TV-Meta'] = env['HTTP_X_TV_META'] if env.key?('HTTP_X_TV_META')
31
+
32
+ # Report any request queue'ing headers. Report as 'Request-Start' or the summed Queue-Time
33
+ report_kvs['Request-Start'] = env['HTTP_X_REQUEST_START'] if env.key?('HTTP_X_REQUEST_START')
34
+ report_kvs['Request-Start'] = env['HTTP_X_QUEUE_START'] if env.key?('HTTP_X_QUEUE_START')
35
+ report_kvs['Queue-Time'] = env['HTTP_X_QUEUE_TIME'] if env.key?('HTTP_X_QUEUE_TIME')
36
+
37
+ report_kvs['Forwarded-For'] = env['HTTP_X_FORWARDED_FOR'] if env.key?('HTTP_X_FORWARDED_FOR')
38
+ report_kvs['Forwarded-Host'] = env['HTTP_X_FORWARDED_HOST'] if env.key?('HTTP_X_FORWARDED_HOST')
39
+ report_kvs['Forwarded-Proto'] = env['HTTP_X_FORWARDED_PROTO'] if env.key?('HTTP_X_FORWARDED_PROTO')
40
+ report_kvs['Forwarded-Port'] = env['HTTP_X_FORWARDED_PORT'] if env.key?('HTTP_X_FORWARDED_PORT')
41
+
42
+ report_kvs['Ruby.TraceView.Version'] = ::TraceView::Version::STRING
43
+ report_kvs['ProcessID'] = Process.pid
44
+ report_kvs['ThreadID'] = Thread.current.to_s[/0x\w*/]
45
+ rescue StandardError => e
46
+ # Discard any potential exceptions. Debug log and report whatever we can.
47
+ TraceView.logger.debug "[traceview/debug] Rack KV collection error: #{e.inspect}"
48
+ end
49
+ report_kvs
50
+ end
51
+
52
+ def call(env)
53
+ rack_skipped = false
54
+
55
+ # In the case of nested Ruby apps such as Grape inside of Rails
56
+ # or Grape inside of Grape, each app has it's own instance
57
+ # of rack middleware. We avoid tracing rack more than once and
58
+ # instead start instrumenting from the first rack pass.
59
+
60
+ # If we're already tracing a rack layer, dont't start another one.
61
+ if TraceView.tracing? && TraceView.layer == 'rack'
62
+ rack_skipped = true
63
+ TraceView.logger.debug "[traceview/rack] Rack skipped!"
64
+ return @app.call(env)
65
+ end
66
+
67
+ req = ::Rack::Request.new(env)
68
+ report_kvs = {}
69
+
70
+ if TraceView::Config[:rack][:log_args]
71
+ report_kvs[:URL] = ::CGI.unescape(req.fullpath)
72
+ else
73
+ report_kvs[:URL] = ::CGI.unescape(req.path)
74
+ end
75
+
76
+ # Check for and validate X-Trace request header to pick up tracing context
77
+ xtrace = env.is_a?(Hash) ? env['HTTP_X_TRACE'] : nil
78
+ xtrace_header = xtrace if xtrace && TraceView::XTrace.valid?(xtrace)
79
+
80
+ # Under JRuby, JTraceView may have already started a trace. Make note of this
81
+ # if so and don't clear context on log_end (see traceview/api/logging.rb)
82
+ TraceView.has_incoming_context = TraceView.tracing?
83
+ TraceView.has_xtrace_header = xtrace_header
84
+ TraceView.is_continued_trace = TraceView.has_incoming_context or TraceView.has_xtrace_header
85
+
86
+ TraceView::API.log_start('rack', xtrace_header, report_kvs)
87
+
88
+ # We only trace a subset of requests based off of sample rate so if
89
+ # TraceView::API.log_start really did start a trace, we act accordingly here.
90
+ if TraceView.tracing?
91
+ report_kvs = collect(req, env)
92
+
93
+ # We log an info event with the HTTP KVs found in TraceView::Rack.collect
94
+ # This is done here so in the case of stacks that try/catch/abort
95
+ # (looking at you Grape) we're sure the KVs get reported now as
96
+ # this code may not be returned to later.
97
+ TraceView::API.log_info('rack', report_kvs)
98
+
99
+ status, headers, response = @app.call(env)
100
+
101
+ xtrace = TraceView::API.log_end('rack', :Status => status)
102
+ else
103
+ status, headers, response = @app.call(env)
104
+ end
105
+
106
+ [status, headers, response]
107
+ rescue Exception => e
108
+ unless rack_skipped
109
+ TraceView::API.log_exception('rack', e)
110
+ xtrace = TraceView::API.log_end('rack', :Status => 500)
111
+ end
112
+ raise
113
+ ensure
114
+ if !rack_skipped && headers && TraceView::XTrace.valid?(xtrace)
115
+ unless defined?(JRUBY_VERSION) && TraceView.is_continued_trace?
116
+ headers['X-Trace'] = xtrace if headers.is_a?(Hash)
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+