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
data/Rakefile ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'rake/testtask'
6
+ require 'appraisal'
7
+
8
+ Rake::TestTask.new do |t|
9
+ t.libs << "test"
10
+ t.test_files = FileList['test/**/*_test.rb']
11
+ t.verbose = true
12
+ t.ruby_opts = []
13
+ # t.ruby_opts << ['-w']
14
+ if defined?(JRUBY_VERSION)
15
+ t.ruby_opts << ["-J-javaagent:/usr/local/tracelytics/tracelyticsagent.jar"]
16
+ end
17
+ end
18
+
19
+ if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
20
+ task :default => :appraisal
21
+ else
22
+ task :default => :test
23
+ end
24
+
25
+ desc "Build the gem's c extension"
26
+ task :compile do
27
+ unless defined?(JRUBY_VERSION)
28
+ puts "== Building the c extension against Ruby #{RUBY_VERSION}"
29
+
30
+ pwd = Dir.pwd
31
+ ext_dir = File.expand_path('ext/oboe_metal')
32
+ lib_dir = File.expand_path('lib')
33
+ symlink = File.expand_path('lib/oboe_metal.so')
34
+ so_file = File.expand_path('ext/oboe_metal/oboe_metal.so')
35
+
36
+ Dir.chdir ext_dir
37
+ cmd = [ Gem.ruby, 'extconf.rb']
38
+ sh cmd.join(' ')
39
+ sh '/usr/bin/env make'
40
+ File.delete symlink if File.exist? symlink
41
+
42
+ if File.exists? so_file
43
+ File.symlink so_file, symlink
44
+ Dir.chdir pwd
45
+ puts "== Extension built and symlink'd to #{symlink}"
46
+ else
47
+ Dir.chdir pwd
48
+ puts "!! Extension failed to build (see above). Are the base TraceView packages installed?"
49
+ puts "!! See https://support.appneta.com/cloud/installing-traceview"
50
+ end
51
+ else
52
+ puts "== Nothing to do under JRuby."
53
+ end
54
+ end
55
+
56
+ desc "Clean up extension build files"
57
+ task :clean do
58
+ unless defined?(JRUBY_VERSION)
59
+ pwd = Dir.pwd
60
+ ext_dir = File.expand_path('ext/oboe_metal')
61
+ lib_dir = File.expand_path('lib')
62
+ symlink = File.expand_path('lib/oboe_metal.so')
63
+ so_file = File.expand_path('ext/oboe_metal/oboe_metal.so')
64
+
65
+ Dir.chdir ext_dir
66
+ sh '/usr/bin/env make clean'
67
+
68
+ Dir.chdir pwd
69
+ else
70
+ puts "== Nothing to do under JRuby."
71
+ end
72
+ end
73
+
74
+ desc "Remove all built files and extensions"
75
+ task :distclean do
76
+ unless defined?(JRUBY_VERSION)
77
+ pwd = Dir.pwd
78
+ ext_dir = File.expand_path('ext/oboe_metal')
79
+ lib_dir = File.expand_path('lib')
80
+ symlink = File.expand_path('lib/oboe_metal.so')
81
+ so_file = File.expand_path('ext/oboe_metal/oboe_metal.so')
82
+ mkmf_log = File.expand_path('ext/oboe_metal/mkmf.log')
83
+
84
+ if File.exists? mkmf_log
85
+ Dir.chdir ext_dir
86
+ File.delete symlink if File.exist? symlink
87
+ sh '/usr/bin/env make distclean'
88
+
89
+ Dir.chdir pwd
90
+ else
91
+ puts "Nothing to distclean. (nothing built yet?)"
92
+ end
93
+ else
94
+ puts "== Nothing to do under JRuby."
95
+ end
96
+ end
97
+
98
+ desc "Rebuild the gem's c extension"
99
+ task :recompile => [ :distclean, :compile ]
100
+
101
+ task :console do
102
+ ENV['TRACEVIEW_GEM_VERBOSE'] = 'true'
103
+ Bundler.require(:default, :development)
104
+ TraceView::Config[:tracing_mode] = :always
105
+ ARGV.clear
106
+ Pry.start
107
+ end
108
+
109
+
data/examples/DNT.md ADDED
@@ -0,0 +1,35 @@
1
+ By default, the TraceView oboe gem will not trace routes with extensions
2
+ for common static files. Examples of such files may be images,
3
+ javascript, pdfs and text files.
4
+
5
+ This is done by using the regular expression stored in
6
+ `Oboe::Config[:dnt_regexp]`:
7
+
8
+ .(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|svg|less)$
9
+
10
+ This string is used as a regular expression and is tested against
11
+ candidate URLs to be instrumented.
12
+
13
+ To replace the pattern in use, you can update this regular expression
14
+ string. Here are some examples.
15
+
16
+ If you prefer that you want your javascript and CSS files instrumented,
17
+ you can update `Oboe::Config[:dnt_regexp]` with an updated regexp
18
+ pattern (without the "js" and "css" entries):
19
+
20
+ .(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|flv|swf|ttf|woff|svg|less)$
21
+
22
+ If you prefer to not instrument all javascript files except for one
23
+ named `show.js`, you could put this assignment into your initializer,
24
+ rackup file or application.rb (note that this example uses a standard
25
+ regexp [negative
26
+ look-behind](http://www.regular-expressions.info/lookaround.html) that
27
+ isn't supported in Ruby 1.8):
28
+
29
+ Oboe::Config[:dnt_regexp] = "(\.js$)(?<!show.js)"
30
+
31
+ Since this pattern is used with the standard Ruby Regexp class, you can
32
+ use any Regexp supported pattern. See the documentation on Ruby Regexp
33
+ [here](https://www.omniref.com/ruby/2.2.0/symbols/Regexp?d=380181456&n=0#doc_uncollapsed=true&d=380181456&n=0)
34
+ or you can also view the oboe gem [source code documentation for this
35
+ feature](https://github.com/appneta/oboe-ruby/blob/master/lib/oboe/config.rb#L74).
@@ -0,0 +1,225 @@
1
+ ###############################################################
2
+ # A brief overview of TraceView tracing context
3
+ ###############################################################
4
+ #
5
+ # Tracing context is the state held when TraceView is instrumenting a
6
+ # transaction, block, request etc.. This context is advanced as
7
+ # new blocks are instrumented and this chain of context is used
8
+ # by TraceView to later reassemble performance data to be displayed
9
+ # in the TraceView dashboard.
10
+ #
11
+ # Tracing context is non-existent until established by calling
12
+ # `Oboe::API.start_trace` or `Oboe::API.log_start`. Those methods
13
+ # are part of the high-level and low-level API respectively.
14
+ #
15
+ # After a tracing context is established, that context can be
16
+ # continued by calling `Oboe::API.trace` or `Oboe::API.log_entry`.
17
+ # These methods will advance an existing context but not start
18
+ # new one.
19
+ #
20
+ # For example, when a web request comes into a stack, a tracing
21
+ # context is established using `Oboe::API.log_start` as the request
22
+ # enters through the rack middleware via `::Oboe::Rack`.
23
+ #
24
+ # That tracing context is then continued using `Oboe::API.trace` or
25
+ # `Oboe::API.log_entry` for each subsequent layer such as Rails,
26
+ # ActiveRecord, Redis, Memcache, ActionView, Mongo (etc...) until
27
+ # finally request processing is complete and the tracing context
28
+ # is cleared (Oboe::Context.clear)
29
+ #
30
+
31
+ ###############################################################
32
+ # Carrying Context
33
+ ###############################################################
34
+ #
35
+ # The tracing context exists in the form of an X-Trace string and
36
+ # can be retrieved using 'Oboe::Context.toString'
37
+ #
38
+ # xtrace = Oboe::Context.toString
39
+ #
40
+ # => "1B4EDAB9E028CA3C81BCD57CC4644B4C4AE239C7B713F0BCB9FAD6D562"
41
+ #
42
+ # Tracing context can also be picked up from a pre-existing
43
+ # X-Trace string:
44
+ #
45
+ # xtrace = "1B4EDAB9E028CA3C81BCD57CC4644B4C4AE239C7B713F0BCB9FAD6D562"
46
+ #
47
+ # Oboe::Context.fromString(xtrace)
48
+ #
49
+ # With these two methods, context can be passed across threads,
50
+ # processes (via fork) and in requests (such as external HTTP
51
+ # requests where the X-Trace is inserted in request headers).
52
+ #
53
+ #
54
+
55
+ ###############################################################
56
+ # Two Options for Spawned Tracing
57
+ ###############################################################
58
+ #
59
+ # When your application needs to instrument code that forks,
60
+ # spawns a thread or does something in-parallel, you have the
61
+ # option to either link those child traces to the parent or
62
+ # trace them as individuals (but with identifying information).
63
+ #
64
+ # Linking parent and child has it's benefits as in the
65
+ # TraceView dashboard, you will see how a process may spawn
66
+ # a task in parallel and in a single view see the performance
67
+ # of both.
68
+ #
69
+ # The limitation of this is that this is only useful if your
70
+ # parent process spawns only a limited number of child traces.
71
+ #
72
+ # If your parent process is spawning many child tasks (e.g.
73
+ # twenty, hundreds, thousands or more) it's best to trace those
74
+ # child tasks as individuals and pass in identifier Key-Values
75
+ # (such as task ID, job ID etc..)
76
+ #
77
+ # In the examples below, I show implementations of both linked
78
+ # asynchronous traces and separated independent traces.
79
+
80
+ ###############################################################
81
+ # Thread - with separated traces
82
+ ###############################################################
83
+
84
+ Oboe::API.log_start('parent')
85
+
86
+ # Get the work to be done
87
+ job = get_work
88
+
89
+ Thread.new do
90
+ # This is a new thread so there is no pre-existing context so
91
+ # we'll call `Oboe::API.log_start` to start a new trace context.
92
+ Oboe::API.log_start('worker_thread', { :job_id => job.id })
93
+
94
+ # Do the work
95
+ do_the_work(job)
96
+
97
+ Oboe::API.log_end('worker_thread')
98
+ end
99
+
100
+ Oboe::API.log_end('parent')
101
+
102
+
103
+
104
+ ###############################################################
105
+ #
106
+ # This will generate two independent traces with the following
107
+ # topology.
108
+ #
109
+ # 'parent'
110
+ # ------------------------------------------------------------
111
+ #
112
+ # 'worker_thread'
113
+ # ------------------------------------------------------------
114
+ #
115
+
116
+ ###############################################################
117
+ # Thread - with linked asynchronous traces
118
+ ###############################################################
119
+
120
+ # Since the following example spawns a thread without waiting
121
+ # for it to return, we carry over the context and we mark the
122
+ # trace generated in that thread to be asynchronous using
123
+ # the `Async` flag.
124
+
125
+ Oboe::API.log_start('parent')
126
+
127
+ # Save the context to be imported in spawned thread
128
+ tracing_context = Oboe::Context.toString
129
+
130
+ # Get the work to be done
131
+ job = get_work
132
+
133
+ Thread.new do
134
+ # Restore context
135
+ Oboe::Context.fromString(tracing_context)
136
+
137
+ Oboe::API.log_entry('worker_thread')
138
+
139
+ # Do the work
140
+ do_the_work(job)
141
+
142
+ Oboe::API.log_exit('worker_thread', { 'Async' => 1 })
143
+ end
144
+
145
+ Oboe::API.log_end('parent')
146
+
147
+ ###############################################################
148
+ #
149
+ # This will generate a single trace with an asynchronous
150
+ # branch like the following
151
+ #
152
+ # 'parent'
153
+ # ------------------------------------------------------------
154
+ # \
155
+ # \
156
+ # ------------------------------------------------------
157
+ # 'worker_thread'
158
+ #
159
+
160
+ ###############################################################
161
+ # Process via fork - with separated traces
162
+ ###############################################################
163
+
164
+ Oboe::API.start_trace('parent_process') do
165
+
166
+ # Get some work to process
167
+ job = get_job
168
+
169
+ # fork process to handle work
170
+ fork do
171
+ # Since fork does a complete process copy, the tracing_context still exists
172
+ # so we have to clear it and start again.
173
+ Oboe::Context.clear
174
+
175
+ Oboe::API.start_trace('worker_process', nil, { :job_id => job.id }) do
176
+ do_work(job)
177
+ end
178
+ end
179
+
180
+ end
181
+
182
+ ###############################################################
183
+ #
184
+ # This will generate two independent traces:
185
+ #
186
+ # 'parent_process'
187
+ # ------------------------------------------------------------
188
+ #
189
+ # 'worker_process'
190
+ # ------------------------------------------------------------
191
+ #
192
+ ###############################################################
193
+ # Process via fork - with linked asynchronous traces
194
+ ###############################################################
195
+
196
+ Oboe::API.start_trace('parent_process') do
197
+
198
+ # Get some work to process
199
+ job = get_job
200
+
201
+ # fork process to handle work
202
+ fork do
203
+ # Since fork does a complete process copy, the tracing_context still exists
204
+ # although we'll have to mark these traces as asynchronous to denote
205
+ # that it has split off from the main program flow
206
+
207
+ Oboe::API.trace('worker_process', { 'Async' => 1 }) do
208
+ do_work(job)
209
+ end
210
+ end
211
+
212
+ end
213
+
214
+ ###############################################################
215
+ #
216
+ # This will generate a single trace with an asynchronous
217
+ # branch like the following
218
+ #
219
+ # 'parent_process'
220
+ # ------------------------------------------------------------
221
+ # \
222
+ # \
223
+ # ------------------------------------------------------
224
+ # 'worker_process'
225
+ #
@@ -0,0 +1,8 @@
1
+ class MetalController < ActionController::Metal
2
+ def index
3
+ self.response_body = 'Hello Metal!'
4
+ end
5
+
6
+ include OboeMethodProfiling
7
+ profile_method :index, 'metal-index'
8
+ end
@@ -0,0 +1,17 @@
1
+ workers Integer(ENV['WEB_CONCURRENCY'] || 2)
2
+ threads_count = Integer(ENV['MAX_THREADS'] || 5)
3
+ threads threads_count, threads_count
4
+
5
+ preload_app!
6
+
7
+ rackup DefaultRackup
8
+ port ENV['PORT'] || 3000
9
+ environment ENV['RACK_ENV'] || 'development'
10
+
11
+ on_worker_boot do
12
+ ::Oboe.reconnect! if defined?(::Oboe)
13
+ end
14
+
15
+ on_worker_shutdown do
16
+ ::Oboe.disconnect! if defined?(::Oboe)
17
+ end
@@ -0,0 +1,125 @@
1
+ #
2
+ # This sample demonstrates how to instrument a main loop that
3
+ # retrieves work and spawn threads that do the actual work
4
+ #
5
+
6
+ require 'math'
7
+ require 'oboe'
8
+
9
+ Oboe::Config[:tracing_mode] = :always
10
+ Oboe::Config[:verbose] = true
11
+
12
+ # The parent process/loop which collects data
13
+ while true do
14
+
15
+ # For each loop, we instrument the work retrieval. These traces
16
+ # will show up as layer 'get_the_work'.
17
+ Oboe::API.start_trace('get_the_work') do
18
+
19
+ work = get_the_work
20
+
21
+ # Loop through work and pass to `do_the_work` method
22
+ # that spawns a thread each time
23
+ work.each do |j|
24
+
25
+ # In the new Thread block, the Oboe tracing context isn't there
26
+ # so we carry it over manually and pass it to the `start_trace`
27
+ # method.
28
+
29
+ # In the TraceView dashboard, this will show up as parent traces
30
+ # (layer 'get_the_work') with child traces (layer 'do_the_work').
31
+
32
+ tracing_context = Oboe::Context.toString
33
+
34
+ Thread.new do
35
+ result = nil
36
+
37
+ Oboe::API.start_trace('do_the_work', tracing_context, { 'Async' => 1 }) do
38
+ result = do_the_work(j)
39
+ end
40
+
41
+ result
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+
48
+ ##
49
+ # get_the_work
50
+ #
51
+ # Method to retrieve work to do
52
+ #
53
+ def get_the_work
54
+ # We'll just return random integers as a
55
+ # fake work load
56
+ w = []
57
+ w << rand(25)
58
+ w << rand(25)
59
+ w << rand(25)
60
+ end
61
+
62
+ ##
63
+ # do_the_work
64
+ #
65
+ # The work-horse method
66
+ #
67
+ def do_the_work(job_to_do)
68
+ i = job_to_do
69
+ i * Math::PI
70
+ end
71
+
72
+ ####################################################
73
+ # Notes
74
+ ####################################################
75
+
76
+ # The above code generates a trace for each loop of the parent data collection process.
77
+ # Those traces have the layer name of `get_the_work` and will show up in the TraceView
78
+ # dashboard as such.
79
+ #
80
+ # Then as threads are spawned to process individual bits of work, we carry over the
81
+ # `tracing_context` and start a new asynchronous trace using `start_trace`. (An
82
+ # asynchronous trace is noted by passing the `Async` Hash key with a value of `1`).
83
+ #
84
+ # In the TraceView dashboard, the two traces (parent and child; or one to many) will
85
+ # be linked and displayed together as a single trace.
86
+
87
+ ####################################################
88
+ # Caveats
89
+ ####################################################
90
+
91
+ # If the main loop is retrieving many jobs (work) to process on each loop then
92
+ # linking the traces may not be the best strategy as such large relationships
93
+ # are difficult to display correctly in the TraceView dashboard and provide little
94
+ # added value.
95
+ #
96
+ # If there are more than 8 - 12 threads spawned from each loop, then you may want to consider
97
+ # NOT carrying over tracing context into the spawned threads.
98
+ #
99
+ # In this case, you can simply omit `tracing_context` and passing it to `start_trace` in
100
+ # the `Thread.new` block. (lines 32 + 37). Also remove the `{ Async => 1 }` Hash!
101
+ #
102
+ # This will produce two sets of traces with two the layer names 'get_the_work' +
103
+ # 'do_the_work'.
104
+ #
105
+ # In the TraceView dashboard, you can then separate or unify these traces into
106
+ # independent applications. e.g. job processor, data retrieval, thread worker etc...
107
+ #
108
+ # An implementation of the work loop without carrying over tracing context would look
109
+ # like the following:
110
+ #
111
+ # work.each do |j|
112
+ # Thread.new do
113
+ # result = nil
114
+ #
115
+ # Oboe::API.start_trace('do_the_work') do
116
+ # result = do_the_work(j)
117
+ # end
118
+ #
119
+ # result
120
+ # end
121
+ # end
122
+ #
123
+ # If anything isn't clear, please don't hesitate to reach us at support (traceviewsupport@appneta.com)
124
+ # or on IRC #appneta @ freenode.
125
+ #