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,279 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module Cassandra
7
+ def extract_trace_details(op, column_family, keys, args, options = {})
8
+ report_kvs = {}
9
+
10
+ begin
11
+ report_kvs[:Op] = op.to_s
12
+ report_kvs[:Cf] = column_family.to_s if column_family
13
+ report_kvs[:Key] = keys.inspect if keys
14
+
15
+ # Open issue - how to handle multiple Cassandra servers
16
+ report_kvs[:RemoteHost], report_kvs[:RemotePort] = @servers.first.split(':')
17
+
18
+ report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:cassandra][:collect_backtraces]
19
+
20
+ if options.empty? && args.is_a?(Array)
21
+ options = args.last if args.last.is_a?(Hash)
22
+ end
23
+
24
+ unless options.empty?
25
+ [:start_key, :finish_key, :key_count, :batch_size, :columns, :count, :start,
26
+ :stop, :finish, :finished, :reversed, :consistency, :ttl].each do |k|
27
+ report_kvs[k.to_s.capitalize] = options[k] if options.key?(k)
28
+ end
29
+
30
+ if op == :get_indexed_slices
31
+ index_clause = columns_and_options[:index_clause] || {}
32
+ unless index_clause.empty?
33
+ [:column_name, :value, :comparison].each do |k|
34
+ report_kvs[k.to_s.capitalize] = index_clause[k] if index_clause.key?(k)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ rescue
40
+ end
41
+
42
+ report_kvs
43
+ end
44
+
45
+ def insert_with_traceview(column_family, key, hash, options = {})
46
+ return insert_without_traceview(column_family, key, hash, options = {}) unless TraceView.tracing?
47
+
48
+ report_kvs = extract_trace_details(:insert, column_family, key, hash, options)
49
+
50
+ TraceView::API.trace('cassandra', report_kvs) do
51
+ insert_without_traceview(column_family, key, hash, options = {})
52
+ end
53
+ end
54
+
55
+ def remove_with_traceview(column_family, key, *columns_and_options)
56
+ return send :remove_without_traceview, *args unless TraceView.tracing?
57
+
58
+ args = [column_family, key] + columns_and_options
59
+ report_kvs = extract_trace_details(:remove, column_family, key, columns_and_options)
60
+
61
+ TraceView::API.trace('cassandra', report_kvs) do
62
+ send :remove_without_traceview, *args
63
+ end
64
+ end
65
+
66
+ def count_columns_with_traceview(column_family, key, *columns_and_options)
67
+ return send :count_columns_without_traceview, *args unless TraceView.tracing?
68
+
69
+ args = [column_family, key] + columns_and_options
70
+ report_kvs = extract_trace_details(:count_columns, column_family, key, columns_and_options)
71
+
72
+ TraceView::API.trace('cassandra', report_kvs) do
73
+ send :count_columns_without_traceview, *args
74
+ end
75
+ end
76
+
77
+ def get_columns_with_traceview(column_family, key, *columns_and_options)
78
+ args = [column_family, key] + columns_and_options
79
+
80
+ if TraceView.tracing? && !TraceView.tracing_layer_op?(:multi_get_columns)
81
+ report_kvs = extract_trace_details(:get_columns, column_family, key, columns_and_options)
82
+
83
+ TraceView::API.trace('cassandra', report_kvs) do
84
+ send :get_columns_without_traceview, *args
85
+ end
86
+ else
87
+ send :get_columns_without_traceview, *args
88
+ end
89
+ end
90
+
91
+ def multi_get_columns_with_traceview(column_family, key, *columns_and_options)
92
+ return send :multi_get_columns_without_traceview, *args unless TraceView.tracing?
93
+
94
+ args = [column_family, key] + columns_and_options
95
+ report_kvs = extract_trace_details(:multi_get_columns, column_family, key, columns_and_options)
96
+
97
+ TraceView::API.trace('cassandra', report_kvs, :multi_get_columns) do
98
+ send :multi_get_columns_without_traceview, *args
99
+ end
100
+ end
101
+
102
+ def get_with_traceview(column_family, key, *columns_and_options)
103
+ return send :get_without_traceview, *args unless TraceView.tracing?
104
+
105
+ args = [column_family, key] + columns_and_options
106
+ report_kvs = extract_trace_details(:get, column_family, key, columns_and_options)
107
+
108
+ TraceView::API.trace('cassandra', report_kvs, :get) do
109
+ send :get_without_traceview, *args
110
+ end
111
+ end
112
+
113
+ def multi_get_with_traceview(column_family, key, *columns_and_options)
114
+ args = [column_family, key] + columns_and_options
115
+
116
+ if TraceView.tracing? && !TraceView.tracing_layer_op?(:get)
117
+ report_kvs = extract_trace_details(:multi_get, column_family, key, columns_and_options)
118
+
119
+ TraceView::API.trace('cassandra', report_kvs) do
120
+ send :multi_get_without_traceview, *args
121
+ end
122
+ else
123
+ send :multi_get_without_traceview, *args
124
+ end
125
+ end
126
+
127
+ def exists_with_traceview?(column_family, key, *columns_and_options)
128
+ return send :exists_without_traceview?, *args unless TraceView.tracing?
129
+
130
+ args = [column_family, key] + columns_and_options
131
+ report_kvs = extract_trace_details(:exists?, column_family, key, columns_and_options)
132
+
133
+ TraceView::API.trace('cassandra', report_kvs) do
134
+ send :exists_without_traceview?, *args
135
+ end
136
+ end
137
+
138
+ def get_range_single_with_traceview(column_family, options = {})
139
+ if TraceView.tracing? && !TraceView.tracing_layer_op?(:get_range_batch)
140
+ report_kvs = extract_trace_details(:get_range_single, column_family, nil, nil)
141
+
142
+ TraceView::API.trace('cassandra', report_kvs) do
143
+ get_range_single_without_traceview(column_family, options)
144
+ end
145
+ else
146
+ get_range_single_without_traceview(column_family, options)
147
+ end
148
+ end
149
+
150
+ def get_range_batch_with_traceview(column_family, options = {})
151
+ return get_range_batch_without_traceview(column_family, options) unless TraceView.tracing?
152
+
153
+ report_kvs = extract_trace_details(:get_range_batch, column_family, nil, nil)
154
+
155
+ TraceView::API.trace('cassandra', report_kvs, :get_range_batch) do
156
+ get_range_batch_without_traceview(column_family, options)
157
+ end
158
+ end
159
+
160
+ def get_indexed_slices_with_traceview(column_family, index_clause, *columns_and_options)
161
+ return send :get_indexed_slices_without_traceview, *args unless TraceView.tracing?
162
+
163
+ args = [column_family, index_clause] + columns_and_options
164
+ report_kvs = extract_trace_details(:get_indexed_slices, column_family, nil, columns_and_options)
165
+
166
+ TraceView::API.trace('cassandra', report_kvs) do
167
+ send :get_indexed_slices_without_traceview, *args
168
+ end
169
+ end
170
+
171
+ def create_index_with_traceview(keyspace, column_family, column_name, validation_class)
172
+ unless TraceView.tracing?
173
+ return create_index_without_traceview(keyspace, column_family, column_name, validation_class)
174
+ end
175
+
176
+ report_kvs = extract_trace_details(:create_index, column_family, nil, nil)
177
+ begin
178
+ report_kvs[:Keyspace] = keyspace.to_s
179
+ report_kvs[:Column_name] = column_name.to_s
180
+ report_kvs[:Validation_class] = validation_class.to_s
181
+ rescue
182
+ end
183
+
184
+ TraceView::API.trace('cassandra', report_kvs) do
185
+ create_index_without_traceview(keyspace, column_family, column_name, validation_class)
186
+ end
187
+ end
188
+
189
+ def drop_index_with_traceview(keyspace, column_family, column_name)
190
+ return drop_index_without_traceview(keyspace, column_family, column_name) unless TraceView.tracing?
191
+
192
+ report_kvs = extract_trace_details(:drop_index, column_family, nil, nil)
193
+ begin
194
+ report_kvs[:Keyspace] = keyspace.to_s
195
+ report_kvs[:Column_name] = column_name.to_s
196
+ rescue
197
+ end
198
+
199
+ TraceView::API.trace('cassandra', report_kvs) do
200
+ drop_index_without_traceview(keyspace, column_family, column_name)
201
+ end
202
+ end
203
+
204
+ def add_column_family_with_traceview(cf_def)
205
+ return add_column_family_without_traceview(cf_def) unless TraceView.tracing?
206
+
207
+ report_kvs = extract_trace_details(:add_column_family, nil, nil, nil)
208
+ begin
209
+ report_kvs[:Cf] = cf_def[:name] if cf_def.is_a?(Hash) && cf_def.key?(:name)
210
+ rescue
211
+ end
212
+
213
+ TraceView::API.trace('cassandra', report_kvs) do
214
+ add_column_family_without_traceview(cf_def)
215
+ end
216
+ end
217
+
218
+ def drop_column_family_with_traceview(column_family)
219
+ return drop_column_family_without_traceview(column_family) unless TraceView.tracing?
220
+
221
+ report_kvs = extract_trace_details(:drop_column_family, column_family, nil, nil)
222
+
223
+ TraceView::API.trace('cassandra', report_kvs) do
224
+ drop_column_family_without_traceview(column_family)
225
+ end
226
+ end
227
+
228
+ def add_keyspace_with_traceview(ks_def)
229
+ return add_keyspace_without_traceview(ks_def) unless TraceView.tracing?
230
+
231
+ report_kvs = extract_trace_details(:add_keyspace, nil, nil, nil)
232
+ report_kvs[:Name] = ks_def.name rescue ''
233
+
234
+ TraceView::API.trace('cassandra', report_kvs) do
235
+ add_keyspace_without_traceview(ks_def)
236
+ end
237
+ end
238
+
239
+ def drop_keyspace_with_traceview(keyspace)
240
+ return drop_keyspace_without_traceview(keyspace) unless TraceView.tracing?
241
+
242
+ report_kvs = extract_trace_details(:drop_keyspace, nil, nil, nil)
243
+ report_kvs[:Name] = keyspace.to_s rescue ''
244
+
245
+ TraceView::API.trace('cassandra', report_kvs) do
246
+ drop_keyspace_without_traceview(keyspace)
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end
252
+
253
+ if defined?(::Cassandra) && TraceView::Config[:cassandra][:enabled]
254
+ TraceView.logger.info '[traceview/loading] Instrumenting cassandra' if TraceView::Config[:verbose]
255
+
256
+ class ::Cassandra
257
+ include TraceView::Inst::Cassandra
258
+
259
+ [:insert, :remove, :count_columns, :get_columns, :multi_get_columns, :get,
260
+ :multi_get, :get_range_single, :get_range_batch, :get_indexed_slices,
261
+ :create_index, :drop_index, :add_column_family, :drop_column_family,
262
+ :add_keyspace, :drop_keyspace].each do |m|
263
+ if method_defined?(m)
264
+ class_eval "alias #{m}_without_traceview #{m}"
265
+ class_eval "alias #{m} #{m}_with_traceview"
266
+ else TraceView.logger.warn "[traceview/loading] Couldn't properly instrument Cassandra (#{m}). Partial traces may occur."
267
+ end
268
+ end
269
+
270
+ # Special case handler for question mark methods
271
+ if method_defined?(:exists?)
272
+ alias exists_without_traceview? exists?
273
+ alias exists? exists_with_traceview?
274
+ else TraceView.logger.warn '[traceview/loading] Couldn\'t properly instrument Cassandra (exists?). Partial traces may occur.'
275
+ end
276
+ end # class Cassandra
277
+ end
278
+
279
+
@@ -0,0 +1,86 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module Dalli
7
+ include TraceView::API::Memcache
8
+
9
+ def self.included(cls)
10
+ cls.class_eval do
11
+ TraceView.logger.info '[traceview/loading] Instrumenting memcache (dalli)' if TraceView::Config[:verbose]
12
+ if ::Dalli::Client.private_method_defined? :perform
13
+ alias perform_without_traceview perform
14
+ alias perform perform_with_traceview
15
+ else TraceView.logger.warn '[traceview/loading] Couldn\'t properly instrument Memcache (Dalli). Partial traces may occur.'
16
+ end
17
+
18
+ if ::Dalli::Client.method_defined? :get_multi
19
+ alias get_multi_without_traceview get_multi
20
+ alias get_multi get_multi_with_traceview
21
+ end
22
+ end
23
+ end
24
+
25
+ def perform_with_traceview(*all_args, &blk)
26
+ op, key, *args = *all_args
27
+
28
+ report_kvs = {}
29
+ report_kvs[:KVOp] = op
30
+ report_kvs[:KVKey] = key
31
+ if @servers.is_a?(Array) && !@servers.empty?
32
+ report_kvs[:RemoteHost] = @servers.join(", ")
33
+ end
34
+
35
+ if TraceView.tracing? && !TraceView.tracing_layer_op?(:get_multi)
36
+ TraceView::API.trace('memcache', report_kvs) do
37
+ result = perform_without_traceview(*all_args, &blk)
38
+
39
+ # Clear the hash for a potential info event
40
+ report_kvs.clear
41
+ report_kvs[:KVHit] = memcache_hit?(result) if op == :get && key.class == String
42
+ report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:dalli][:collect_backtraces]
43
+
44
+ TraceView::API.log('memcache', 'info', report_kvs) unless report_kvs.empty?
45
+ result
46
+ end
47
+ else
48
+ perform_without_traceview(*all_args, &blk)
49
+ end
50
+ end
51
+
52
+ def get_multi_with_traceview(*keys)
53
+ return get_multi_without_traceview(keys) unless TraceView.tracing?
54
+
55
+ info_kvs = {}
56
+
57
+ begin
58
+ info_kvs[:KVKeyCount] = keys.flatten.length
59
+ info_kvs[:KVKeyCount] = (info_kvs[:KVKeyCount] - 1) if keys.last.is_a?(Hash) || keys.last.nil?
60
+ if @servers.is_a?(Array) && !@servers.empty?
61
+ info_kvs[:RemoteHost] = @servers.join(", ")
62
+ end
63
+ rescue
64
+ TraceView.logger.debug "[traceview/debug] Error collecting info keys: #{e.message}"
65
+ TraceView.logger.debug e.backtrace
66
+ end
67
+
68
+ TraceView::API.trace('memcache', { :KVOp => :get_multi }, :get_multi) do
69
+ values = get_multi_without_traceview(keys)
70
+
71
+ info_kvs[:KVHitCount] = values.length
72
+ info_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:dalli][:collect_backtraces]
73
+ TraceView::API.log('memcache', 'info', info_kvs)
74
+
75
+ values
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ if defined?(Dalli) && TraceView::Config[:dalli][:enabled]
83
+ ::Dalli::Client.module_eval do
84
+ include TraceView::Inst::Dalli
85
+ end
86
+ end
@@ -0,0 +1,99 @@
1
+ module TraceView
2
+ module Inst
3
+ module EventMachine
4
+ module HttpConnection
5
+ def setup_request_with_traceview(*args, &block)
6
+ report_kvs = {}
7
+ context = TraceView::Context.toString
8
+ blacklisted = TraceView::API.blacklisted?(@uri)
9
+
10
+ begin
11
+ report_kvs['IsService'] = 1
12
+ report_kvs['RemoteURL'] = @uri
13
+ report_kvs['HTTPMethod'] = args[0]
14
+ report_kvs['Blacklisted'] = true if blacklisted
15
+
16
+ if TraceView::Config[:em_http_request][:collect_backtraces]
17
+ report_kvs[:Backtrace] = TraceView::API.backtrace
18
+ end
19
+ rescue => e
20
+ TraceView.logger.debug "[traceview/debug] em-http-request KV error: #{e.inspect}"
21
+ end
22
+
23
+ ::TraceView::API.log_entry('em-http-request', report_kvs)
24
+ client = setup_request_without_traceview(*args, &block)
25
+ client.req.headers['X-Trace'] = context unless blacklisted
26
+ client
27
+ end
28
+ end
29
+
30
+ module HttpClient
31
+ def parse_response_header_with_traceview(*args, &block)
32
+ report_kvs = {}
33
+ xtrace = nil
34
+ blacklisted = TraceView::API.blacklisted?(@uri)
35
+
36
+ begin
37
+ report_kvs[:HTTPStatus] = args[2]
38
+ report_kvs[:Async] = 1
39
+ rescue => e
40
+ TraceView.logger.debug "[traceview/debug] em-http-request KV error: #{e.inspect}"
41
+ end
42
+
43
+ parse_response_header_without_traceview(*args, &block)
44
+
45
+ unless blacklisted
46
+ headers = args[0]
47
+ context = TraceView::Context.toString
48
+ task_id = TraceView::XTrace.task_id(context)
49
+
50
+ if headers.is_a?(Hash) && headers.key?('X-Trace')
51
+ xtrace = headers['X-Trace']
52
+ end
53
+
54
+ if TraceView::XTrace.valid?(xtrace) && TraceView.tracing?
55
+
56
+ # Assure that we received back a valid X-Trace with the same task_id
57
+ if task_id == TraceView::XTrace.task_id(xtrace)
58
+ TraceView::Context.fromString(xtrace)
59
+ else
60
+ TraceView.logger.debug "Mismatched returned X-Trace ID : #{xtrace}"
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ ::TraceView::API.log_exit('em-http-request', report_kvs)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ if RUBY_VERSION >= '1.9'
74
+ if defined?(::EventMachine::HttpConnection) && defined?(::EventMachine::HttpClient) && TraceView::Config[:em_http_request][:enabled]
75
+ TraceView.logger.info '[traceview/loading] Instrumenting em-http-request' if TraceView::Config[:verbose]
76
+
77
+ class ::EventMachine::HttpConnection
78
+ include TraceView::Inst::EventMachine::HttpConnection
79
+
80
+ if method_defined?(:setup_request)
81
+ class_eval 'alias :setup_request_without_traceview :setup_request'
82
+ class_eval 'alias :setup_request :setup_request_with_traceview'
83
+ else
84
+ TraceView.logger.warn '[traceview/loading] Couldn\'t properly instrument em-http-request (:setup_request). Partial traces may occur.'
85
+ end
86
+ end
87
+
88
+ class ::EventMachine::HttpClient
89
+ include TraceView::Inst::EventMachine::HttpClient
90
+
91
+ if method_defined?(:parse_response_header)
92
+ class_eval 'alias :parse_response_header_without_traceview :parse_response_header'
93
+ class_eval 'alias :parse_response_header :parse_response_header_with_traceview'
94
+ else
95
+ TraceView.logger.warn '[traceview/loading] Couldn\'t properly instrument em-http-request (:parse_response_header). Partial traces may occur.'
96
+ end
97
+ end
98
+ end
99
+ end