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,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
+