traceview 3.0.0

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.rb +7 -0
  34. data/lib/oboe/README +2 -0
  35. data/lib/oboe/backward_compatibility.rb +59 -0
  36. data/lib/oboe/inst/rack.rb +11 -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.rb +62 -0
  41. data/lib/traceview/api.rb +18 -0
  42. data/lib/traceview/api/layerinit.rb +51 -0
  43. data/lib/traceview/api/logging.rb +209 -0
  44. data/lib/traceview/api/memcache.rb +31 -0
  45. data/lib/traceview/api/profiling.rb +50 -0
  46. data/lib/traceview/api/tracing.rb +135 -0
  47. data/lib/traceview/api/util.rb +121 -0
  48. data/lib/traceview/base.rb +225 -0
  49. data/lib/traceview/config.rb +238 -0
  50. data/lib/traceview/frameworks/grape.rb +97 -0
  51. data/lib/traceview/frameworks/padrino.rb +64 -0
  52. data/lib/traceview/frameworks/padrino/templates.rb +58 -0
  53. data/lib/traceview/frameworks/rails.rb +145 -0
  54. data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
  55. data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
  56. data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
  57. data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
  58. data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
  59. data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
  60. data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
  61. data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
  62. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  63. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  64. data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
  65. data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  66. data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
  67. data/lib/traceview/frameworks/sinatra.rb +95 -0
  68. data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
  69. data/lib/traceview/inst/cassandra.rb +279 -0
  70. data/lib/traceview/inst/dalli.rb +86 -0
  71. data/lib/traceview/inst/em-http-request.rb +99 -0
  72. data/lib/traceview/inst/excon.rb +111 -0
  73. data/lib/traceview/inst/faraday.rb +73 -0
  74. data/lib/traceview/inst/http.rb +87 -0
  75. data/lib/traceview/inst/httpclient.rb +173 -0
  76. data/lib/traceview/inst/memcache.rb +102 -0
  77. data/lib/traceview/inst/memcached.rb +94 -0
  78. data/lib/traceview/inst/mongo.rb +238 -0
  79. data/lib/traceview/inst/moped.rb +474 -0
  80. data/lib/traceview/inst/rack.rb +122 -0
  81. data/lib/traceview/inst/redis.rb +271 -0
  82. data/lib/traceview/inst/resque.rb +192 -0
  83. data/lib/traceview/inst/rest-client.rb +38 -0
  84. data/lib/traceview/inst/sequel.rb +162 -0
  85. data/lib/traceview/inst/typhoeus.rb +102 -0
  86. data/lib/traceview/instrumentation.rb +21 -0
  87. data/lib/traceview/loading.rb +94 -0
  88. data/lib/traceview/logger.rb +41 -0
  89. data/lib/traceview/method_profiling.rb +84 -0
  90. data/lib/traceview/ruby.rb +36 -0
  91. data/lib/traceview/support.rb +113 -0
  92. data/lib/traceview/thread_local.rb +26 -0
  93. data/lib/traceview/util.rb +250 -0
  94. data/lib/traceview/version.rb +16 -0
  95. data/lib/traceview/xtrace.rb +90 -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 +250 -0
@@ -0,0 +1,94 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module Memcached
7
+ include TraceView::API::Memcache
8
+
9
+ def self.included(cls)
10
+ TraceView.logger.info '[traceview/loading] Instrumenting memcached' if TraceView::Config[:verbose]
11
+
12
+ cls.class_eval do
13
+ MEMCACHE_OPS.reject { |m| !method_defined?(m) }.each do |m|
14
+ define_method("#{m}_with_traceview") do |*args|
15
+ opts = { :KVOp => m }
16
+
17
+ if args.length && !args[0].is_a?(Array)
18
+ opts[:KVKey] = args[0].to_s
19
+ rhost = remote_host(args[0].to_s)
20
+ opts[:RemoteHost] = rhost if rhost
21
+ end
22
+
23
+ TraceView::API.trace('memcache', opts) do
24
+ result = send("#{m}_without_traceview", *args)
25
+
26
+ info_kvs = {}
27
+ info_kvs[:KVHit] = memcache_hit?(result) if m == :get && args.length && args[0].class == String
28
+ info_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:memcached][:collect_backtraces]
29
+
30
+ TraceView::API.log('memcache', 'info', info_kvs) unless info_kvs.empty?
31
+ result
32
+ end
33
+ end
34
+
35
+ class_eval "alias #{m}_without_traceview #{m}"
36
+ class_eval "alias #{m} #{m}_with_traceview"
37
+ end
38
+ end
39
+ end
40
+
41
+ end # module Memcached
42
+
43
+ module MemcachedRails
44
+ def self.included(cls)
45
+ cls.class_eval do
46
+ if ::Memcached::Rails.method_defined? :get_multi
47
+ alias get_multi_without_traceview get_multi
48
+ alias get_multi get_multi_with_traceview
49
+ elsif TraceView::Config[:verbose]
50
+ TraceView.logger.warn '[traceview/loading] Couldn\'t properly instrument Memcached. Partial traces may occur.'
51
+ end
52
+ end
53
+ end
54
+
55
+ def get_multi_with_traceview(keys, raw = false)
56
+ if TraceView.tracing?
57
+ layer_kvs = {}
58
+ layer_kvs[:KVOp] = :get_multi
59
+
60
+ TraceView::API.trace('memcache', layer_kvs || {}, :get_multi) do
61
+ begin
62
+ info_kvs = {}
63
+ info_kvs[:KVKeyCount] = keys.flatten.length
64
+
65
+ values = get_multi_without_traceview(keys, raw)
66
+
67
+ info_kvs[:KVHitCount] = values.length
68
+ info_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:memcached][:collect_backtraces]
69
+
70
+ TraceView::API.log('memcache', 'info', info_kvs)
71
+ rescue
72
+ values = get_multi_without_traceview(keys, raw)
73
+ end
74
+ values
75
+ end
76
+ else
77
+ get_multi_without_traceview(keys, raw)
78
+ end
79
+ end
80
+ end # module MemcachedRails
81
+ end # module Inst
82
+ end # module TraceView
83
+
84
+ if defined?(::Memcached) && TraceView::Config[:memcached][:enabled]
85
+ ::Memcached.class_eval do
86
+ include TraceView::Inst::Memcached
87
+ end
88
+
89
+ if defined?(::Memcached::Rails)
90
+ ::Memcached::Rails.class_eval do
91
+ include TraceView::Inst::MemcachedRails
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,238 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'json'
5
+
6
+ module TraceView
7
+ module Inst
8
+ module Mongo
9
+ FLAVOR = 'mongodb'
10
+
11
+ # Operations for Mongo::DB
12
+ DB_OPS = [:create_collection, :drop_collection]
13
+
14
+ # Operations for Mongo::Cursor
15
+ CURSOR_OPS = [:count]
16
+
17
+ # Operations for Mongo::Collection
18
+ COLL_WRITE_OPS = [:find_and_modify, :insert, :map_reduce, :remove, :rename, :update]
19
+ COLL_QUERY_OPS = [:distinct, :find, :group]
20
+ COLL_INDEX_OPS = [:create_index, :drop_index, :drop_indexes, :ensure_index, :index_information]
21
+ end
22
+ end
23
+ end
24
+
25
+ if defined?(::Mongo) && TraceView::Config[:mongo][:enabled]
26
+ TraceView.logger.info '[traceview/loading] Instrumenting mongo' if TraceView::Config[:verbose]
27
+
28
+ if defined?(::Mongo::DB)
29
+ module ::Mongo
30
+ class DB
31
+ include TraceView::Inst::Mongo
32
+
33
+ # Instrument DB operations
34
+ TraceView::Inst::Mongo::DB_OPS.reject { |m| !method_defined?(m) }.each do |m|
35
+ define_method("#{m}_with_traceview") do |*args|
36
+ report_kvs = {}
37
+
38
+ begin
39
+ report_kvs[:Flavor] = TraceView::Inst::Mongo::FLAVOR
40
+
41
+ report_kvs[:Database] = @name
42
+
43
+ # Mongo >= 1.10 uses @client instead of @connection
44
+ # Avoid the nil
45
+ if @connection
46
+ report_kvs[:RemoteHost] = @connection.host
47
+ report_kvs[:RemotePort] = @connection.port
48
+ elsif @client
49
+ report_kvs[:RemoteHost] = @client.host
50
+ report_kvs[:RemotePort] = @client.port
51
+ end
52
+
53
+ report_kvs[:QueryOp] = m
54
+
55
+ report_kvs[:New_Collection_Name] = args[0] if m == :create_collection
56
+ report_kvs[:Collection] = args[0] if m == :drop_collection
57
+
58
+ report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:mongo][:collect_backtraces]
59
+ rescue
60
+ end
61
+
62
+ TraceView::API.trace('mongo', report_kvs) do
63
+ send("#{m}_without_traceview", *args)
64
+ end
65
+ end
66
+
67
+ class_eval "alias #{m}_without_traceview #{m}"
68
+ class_eval "alias #{m} #{m}_with_traceview"
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ if defined?(::Mongo::Cursor)
75
+ module ::Mongo
76
+ class Cursor
77
+ include TraceView::Inst::Mongo
78
+
79
+ # Instrument DB cursor operations
80
+ TraceView::Inst::Mongo::CURSOR_OPS.reject { |m| !method_defined?(m) }.each do |m|
81
+ define_method("#{m}_with_traceview") do |*args|
82
+ report_kvs = {}
83
+
84
+ begin
85
+ report_kvs[:Flavor] = TraceView::Inst::Mongo::FLAVOR
86
+
87
+ report_kvs[:Database] = @db.name
88
+ report_kvs[:RemoteHost] = @connection.host
89
+ report_kvs[:RemotePort] = @connection.port
90
+
91
+ report_kvs[:QueryOp] = m
92
+ if m == :count
93
+ unless @selector.empty?
94
+ report_kvs[:Query] = @selector.to_json
95
+ else
96
+ report_kvs[:Query] = 'all'
97
+ end
98
+ report_kvs[:Limit] = @limit if @limit != 0
99
+ end
100
+ rescue
101
+ end
102
+
103
+ TraceView::API.trace('mongo', report_kvs) do
104
+ send("#{m}_without_traceview", *args)
105
+ end
106
+ end
107
+
108
+ class_eval "alias #{m}_without_traceview #{m}"
109
+ class_eval "alias #{m} #{m}_with_traceview"
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ if defined?(::Mongo::Collection)
116
+ module ::Mongo
117
+ class Collection
118
+ include TraceView::Inst::Mongo
119
+
120
+ def traceview_collect(m, args)
121
+ begin
122
+ report_kvs = {}
123
+ report_kvs[:Flavor] = TraceView::Inst::Mongo::FLAVOR
124
+
125
+ report_kvs[:Database] = @db.name
126
+ report_kvs[:RemoteHost] = @db.connection.host
127
+ report_kvs[:RemotePort] = @db.connection.port
128
+ report_kvs[:Collection] = @name
129
+
130
+ report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:mongo][:collect_backtraces]
131
+
132
+ report_kvs[:QueryOp] = m
133
+ report_kvs[:Query] = args[0].to_json if args && !args.empty? && args[0].class == Hash
134
+ rescue StandardError => e
135
+ TraceView.logger.debug "[traceview/debug] Exception in traceview_collect KV collection: #{e.inspect}"
136
+ end
137
+ report_kvs
138
+ end
139
+
140
+ # Instrument Collection write operations
141
+ TraceView::Inst::Mongo::COLL_WRITE_OPS.reject { |m| !method_defined?(m) }.each do |m|
142
+ define_method("#{m}_with_traceview") do |*args|
143
+ report_kvs = traceview_collect(m, args)
144
+ args_length = args.length
145
+
146
+ begin
147
+ if m == :find_and_modify && args[0] && args[0].key?(:update)
148
+ report_kvs[:Update_Document] = args[0][:update].inspect
149
+ end
150
+
151
+ if m == :map_reduce
152
+ report_kvs[:Map_Function] = args[0]
153
+ report_kvs[:Reduce_Function] = args[1]
154
+ report_kvs[:Limit] = args[2][:limit] if args[2] && args[2].key?(:limit)
155
+ end
156
+
157
+ report_kvs[:New_Collection_Name] = args[0] if m == :rename
158
+
159
+ if m == :update
160
+ if args_length >= 3
161
+ report_kvs[:Update_Document] = args[1].to_json
162
+ report_kvs[:Multi] = args[2][:multi] if args[2] && args[2].key?(:multi)
163
+ end
164
+ end
165
+ rescue
166
+ end
167
+
168
+ TraceView::API.trace('mongo', report_kvs) do
169
+ send("#{m}_without_traceview", *args)
170
+ end
171
+ end
172
+
173
+ class_eval "alias #{m}_without_traceview #{m}"
174
+ class_eval "alias #{m} #{m}_with_traceview"
175
+ end
176
+
177
+ # Instrument Collection query operations
178
+ TraceView::Inst::Mongo::COLL_QUERY_OPS.reject { |m| !method_defined?(m) }.each do |m|
179
+ define_method("#{m}_with_traceview") do |*args, &blk|
180
+ begin
181
+ report_kvs = traceview_collect(m, args)
182
+ args_length = args.length
183
+
184
+ if m == :distinct && args_length >= 2
185
+ report_kvs[:Key] = args[0]
186
+ report_kvs[:Query] = args[1].to_json if args[1] && args[1].class == Hash
187
+ end
188
+
189
+ if m == :find && args_length > 0
190
+ report_kvs[:Limit] = args[0][:limit] if !args[0].nil? && args[0].key?(:limit)
191
+ end
192
+
193
+ if m == :group
194
+ unless args.empty?
195
+ if args[0].is_a?(Hash)
196
+ report_kvs[:Group_Key] = args[0][:key].to_json if args[0].key?(:key)
197
+ report_kvs[:Group_Condition] = args[0][:cond].to_json if args[0].key?(:cond)
198
+ report_kvs[:Group_Initial] = args[0][:initial].to_json if args[0].key?(:initial)
199
+ report_kvs[:Group_Reduce] = args[0][:reduce] if args[0].key?(:reduce)
200
+ end
201
+ end
202
+ end
203
+ rescue
204
+ end
205
+
206
+ TraceView::API.trace('mongo', report_kvs) do
207
+ send("#{m}_without_traceview", *args, &blk)
208
+ end
209
+ end
210
+
211
+ class_eval "alias #{m}_without_traceview #{m}"
212
+ class_eval "alias #{m} #{m}_with_traceview"
213
+ end
214
+
215
+ # Instrument Collection index operations
216
+ TraceView::Inst::Mongo::COLL_INDEX_OPS.reject { |m| !method_defined?(m) }.each do |m|
217
+ define_method("#{m}_with_traceview") do |*args|
218
+ report_kvs = traceview_collect(m, args)
219
+
220
+ begin
221
+ if [:create_index, :ensure_index, :drop_index].include?(m) && !args.empty?
222
+ report_kvs[:Index] = args[0].to_json
223
+ end
224
+ rescue
225
+ end
226
+
227
+ TraceView::API.trace('mongo', report_kvs) do
228
+ send("#{m}_without_traceview", *args)
229
+ end
230
+ end
231
+
232
+ class_eval "alias #{m}_without_traceview #{m}"
233
+ class_eval "alias #{m} #{m}_with_traceview"
234
+ end
235
+ end
236
+ end
237
+ end
238
+ end
@@ -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