traceview 3.0.0

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.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