oboe 2.7.0.3-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +51 -0
  4. data/Appraisals +10 -0
  5. data/CHANGELOG.md +223 -0
  6. data/Gemfile +49 -0
  7. data/LICENSE +199 -0
  8. data/README.md +380 -0
  9. data/Rakefile +106 -0
  10. data/ext/oboe_metal/extconf.rb +61 -0
  11. data/ext/oboe_metal/noop/noop.c +7 -0
  12. data/ext/oboe_metal/src/bson/bson.h +221 -0
  13. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  14. data/ext/oboe_metal/src/oboe.h +275 -0
  15. data/ext/oboe_metal/src/oboe.hpp +352 -0
  16. data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
  17. data/ext/oboe_metal/tests/test.rb +11 -0
  18. data/gemfiles/mongo.gemfile +33 -0
  19. data/gemfiles/moped.gemfile +33 -0
  20. data/get_version.rb +5 -0
  21. data/init.rb +4 -0
  22. data/lib/base.rb +99 -0
  23. data/lib/joboe_metal.rb +185 -0
  24. data/lib/method_profiling.rb +70 -0
  25. data/lib/oboe.rb +50 -0
  26. data/lib/oboe/api.rb +14 -0
  27. data/lib/oboe/api/layerinit.rb +99 -0
  28. data/lib/oboe/api/logging.rb +129 -0
  29. data/lib/oboe/api/memcache.rb +29 -0
  30. data/lib/oboe/api/profiling.rb +50 -0
  31. data/lib/oboe/api/tracing.rb +134 -0
  32. data/lib/oboe/api/util.rb +117 -0
  33. data/lib/oboe/config.rb +140 -0
  34. data/lib/oboe/frameworks/grape.rb +74 -0
  35. data/lib/oboe/frameworks/padrino.rb +66 -0
  36. data/lib/oboe/frameworks/padrino/templates.rb +59 -0
  37. data/lib/oboe/frameworks/rails.rb +139 -0
  38. data/lib/oboe/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
  39. data/lib/oboe/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
  40. data/lib/oboe/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
  41. data/lib/oboe/frameworks/rails/inst/action_controller.rb +123 -0
  42. data/lib/oboe/frameworks/rails/inst/action_view.rb +56 -0
  43. data/lib/oboe/frameworks/rails/inst/action_view_2x.rb +54 -0
  44. data/lib/oboe/frameworks/rails/inst/action_view_30.rb +48 -0
  45. data/lib/oboe/frameworks/rails/inst/active_record.rb +24 -0
  46. data/lib/oboe/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  47. data/lib/oboe/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  48. data/lib/oboe/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
  49. data/lib/oboe/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  50. data/lib/oboe/frameworks/rails/inst/connection_adapters/utils.rb +118 -0
  51. data/lib/oboe/frameworks/sinatra.rb +96 -0
  52. data/lib/oboe/frameworks/sinatra/templates.rb +56 -0
  53. data/lib/oboe/inst/cassandra.rb +281 -0
  54. data/lib/oboe/inst/dalli.rb +75 -0
  55. data/lib/oboe/inst/http.rb +72 -0
  56. data/lib/oboe/inst/memcache.rb +105 -0
  57. data/lib/oboe/inst/memcached.rb +96 -0
  58. data/lib/oboe/inst/mongo.rb +240 -0
  59. data/lib/oboe/inst/moped.rb +474 -0
  60. data/lib/oboe/inst/rack.rb +81 -0
  61. data/lib/oboe/inst/redis.rb +273 -0
  62. data/lib/oboe/inst/resque.rb +193 -0
  63. data/lib/oboe/instrumentation.rb +18 -0
  64. data/lib/oboe/loading.rb +98 -0
  65. data/lib/oboe/logger.rb +41 -0
  66. data/lib/oboe/ruby.rb +11 -0
  67. data/lib/oboe/util.rb +129 -0
  68. data/lib/oboe/version.rb +13 -0
  69. data/lib/oboe/xtrace.rb +52 -0
  70. data/lib/oboe_metal.rb +140 -0
  71. data/lib/rails/generators/oboe/install_generator.rb +76 -0
  72. data/lib/rails/generators/oboe/templates/oboe_initializer.rb +94 -0
  73. data/oboe.gemspec +29 -0
  74. data/release.sh +65 -0
  75. data/test/frameworks/apps/grape_simple.rb +10 -0
  76. data/test/frameworks/apps/padrino_simple.rb +41 -0
  77. data/test/frameworks/apps/sinatra_simple.rb +20 -0
  78. data/test/frameworks/grape_test.rb +27 -0
  79. data/test/frameworks/padrino_test.rb +25 -0
  80. data/test/frameworks/sinatra_test.rb +25 -0
  81. data/test/instrumentation/cassandra_test.rb +381 -0
  82. data/test/instrumentation/dalli_test.rb +164 -0
  83. data/test/instrumentation/http_test.rb +97 -0
  84. data/test/instrumentation/memcache_test.rb +251 -0
  85. data/test/instrumentation/memcached_test.rb +226 -0
  86. data/test/instrumentation/mongo_test.rb +462 -0
  87. data/test/instrumentation/moped_test.rb +473 -0
  88. data/test/instrumentation/rack_test.rb +73 -0
  89. data/test/instrumentation/redis_hashes_test.rb +265 -0
  90. data/test/instrumentation/redis_keys_test.rb +318 -0
  91. data/test/instrumentation/redis_lists_test.rb +310 -0
  92. data/test/instrumentation/redis_misc_test.rb +160 -0
  93. data/test/instrumentation/redis_sets_test.rb +293 -0
  94. data/test/instrumentation/redis_sortedsets_test.rb +325 -0
  95. data/test/instrumentation/redis_strings_test.rb +333 -0
  96. data/test/instrumentation/resque_test.rb +62 -0
  97. data/test/minitest_helper.rb +148 -0
  98. data/test/profiling/method_test.rb +198 -0
  99. data/test/support/config_test.rb +39 -0
  100. data/test/support/liboboe_settings_test.rb +46 -0
  101. data/test/support/xtrace_test.rb +35 -0
  102. metadata +200 -0
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ begin
5
+ require 'oboe/version'
6
+ require 'oboe/logger'
7
+ require 'oboe/util'
8
+ require 'oboe/xtrace'
9
+
10
+ # If Oboe_metal is already defined then we are in a PaaS environment
11
+ # with an alternate metal (such as Heroku: see the oboe-heroku gem)
12
+ unless defined?(Oboe_metal)
13
+ begin
14
+ if RUBY_PLATFORM == 'java'
15
+ require '/usr/local/tracelytics/tracelyticsagent.jar'
16
+ require 'joboe_metal'
17
+ else
18
+ require 'oboe_metal.so'
19
+ require 'oboe_metal'
20
+ end
21
+ rescue LoadError
22
+ Oboe.loaded = false
23
+
24
+ unless ENV['RAILS_GROUP'] == 'assets'
25
+ $stderr.puts "=============================================================="
26
+ $stderr.puts "Missing TraceView libraries. Tracing disabled."
27
+ $stderr.puts "See: https://support.tv.appneta.com/solution/articles/137973"
28
+ $stderr.puts "=============================================================="
29
+ end
30
+ end
31
+ end
32
+
33
+ require 'oboe/config'
34
+ require 'oboe/loading'
35
+ require 'method_profiling'
36
+ require 'oboe/instrumentation'
37
+ require 'oboe/ruby'
38
+
39
+ # Frameworks
40
+ if Oboe.loaded
41
+ require 'oboe/frameworks/rails' if defined?(::Rails)
42
+ require 'oboe/frameworks/sinatra' if defined?(::Sinatra)
43
+ require 'oboe/frameworks/padrino' if defined?(::Padrino)
44
+ require 'oboe/frameworks/grape' if defined?(::Grape)
45
+ end
46
+ rescue Exception => e
47
+ $stderr.puts "[oboe/error] Problem loading: #{e.inspect}"
48
+ $stderr.puts e.backtrace
49
+ end
50
+
@@ -0,0 +1,14 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ def self.extend_with_tracing
7
+ extend Oboe::API::Logging
8
+ extend Oboe::API::Tracing
9
+ extend Oboe::API::Profiling
10
+ extend Oboe::API::LayerInit
11
+ end
12
+ extend Oboe::API::Util
13
+ end
14
+ end
@@ -0,0 +1,99 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ module LayerInit
7
+ # Internal: Report that instrumentation for the given layer has been
8
+ # installed, as well as the version of instrumentation and version of
9
+ # layer.
10
+ #
11
+ def report_init(layer = 'rack')
12
+ # Don't send __Init in development or test
13
+ return if ["development", "test"].include? ENV['RACK_ENV']
14
+
15
+ # Don't send __Init if the c-extension hasn't loaded
16
+ return unless Oboe.loaded
17
+
18
+ platform_info = { '__Init' => 1 }
19
+
20
+ begin
21
+ platform_info['Force'] = true
22
+ platform_info['Ruby.Platform.Version'] = RUBY_PLATFORM
23
+ platform_info['Ruby.Version'] = RUBY_VERSION
24
+ platform_info['Ruby.Oboe.Version'] = ::Oboe::Version::STRING
25
+ platform_info['RubyHeroku.Oboe.Version'] = ::OboeHeroku::Version::STRING if defined?(::OboeHeroku)
26
+
27
+ # Report the framework in use
28
+ platform_info['Ruby.Rails.Version'] = "Rails-#{::Rails.version}" if defined?(::Rails)
29
+ platform_info['Ruby.Grape.Version'] = "Grape-#{::Grape::VERSION}" if defined?(::Grape)
30
+ platform_info['Ruby.Cramp.Version'] = "Cramp-#{::Cramp::VERSION}" if defined?(::Cramp)
31
+
32
+ if defined?(::Padrino)
33
+ platform_info['Ruby.Padrino.Version'] = "Padrino-#{::Padrino::VERSION}"
34
+ elsif defined?(::Sinatra)
35
+ platform_info['Ruby.Sinatra.Version'] = "Sinatra-#{::Sinatra::VERSION}"
36
+ end
37
+
38
+ # Report the instrumented libraries
39
+ platform_info['Ruby.Cassandra.Version'] = "Cassandra-#{::Cassandra.VERSION}" if defined?(::Cassandra)
40
+ platform_info['Ruby.Dalli.Version'] = "Dalli-#{::Dalli::VERSION}" if defined?(::Dalli)
41
+ platform_info['Ruby.MemCache.Version'] = "MemCache-#{::MemCache::VERSION}" if defined?(::MemCache)
42
+ platform_info['Ruby.Moped.Version'] = "Moped-#{::Moped::VERSION}" if defined?(::Moped)
43
+ platform_info['Ruby.Redis.Version'] = "Redis-#{::Redis::VERSION}" if defined?(::Redis)
44
+ platform_info['Ruby.Resque.Version'] = "Resque-#{::Resque::VERSION}" if defined?(::Resque)
45
+
46
+ # Special case since the Mongo 1.x driver doesn't embed the version number in the gem directly
47
+ if ::Gem.loaded_specs.has_key?('mongo')
48
+ platform_info['Ruby.Mongo.Version'] = "Mongo-#{::Gem.loaded_specs['mongo'].version.to_s}"
49
+ end
50
+
51
+ # Report the server in use (if possible)
52
+ if defined?(::Unicorn)
53
+ platform_info['Ruby.AppContainer.Version'] = "Unicorn-#{::Unicorn::Const::UNICORN_VERSION}"
54
+ elsif defined?(::Puma)
55
+ platform_info['Ruby.AppContainer.Version'] = "Puma-#{::Puma::Const::PUMA_VERSION} (#{::Puma::Const::CODE_NAME})"
56
+ elsif defined?(::PhusionPassenger)
57
+ platform_info['Ruby.AppContainer.Version'] = "#{::PhusionPassenger::PACKAGE_NAME}-#{::PhusionPassenger::VERSION_STRING}"
58
+ elsif defined?(::Thin)
59
+ platform_info['Ruby.AppContainer.Version'] = "Thin-#{::Thin::VERSION::STRING} (#{::Thin::VERSION::CODENAME})"
60
+ elsif defined?(::Mongrel)
61
+ platform_info['Ruby.AppContainer.Version'] = "Mongrel-#{::Mongrel::Const::MONGREL_VERSION}"
62
+ elsif defined?(::Mongrel2)
63
+ platform_info['Ruby.AppContainer.Version'] = "Mongrel2-#{::Mongrel2::VERSION}"
64
+ elsif defined?(::Trinidad)
65
+ platform_info['Ruby.AppContainer.Version'] = "Trinidad-#{::Trinidad::VERSION}"
66
+ elsif defined?(::WEBrick)
67
+ platform_info['Ruby.AppContainer.Version'] = "WEBrick-#{::WEBrick::VERSION}"
68
+ else
69
+ platform_info['Ruby.AppContainer.Version'] = File.basename($0)
70
+ end
71
+
72
+ rescue StandardError, ScriptError => e
73
+ # Also rescue ScriptError (aka SyntaxError) in case one of the expected
74
+ # version defines don't exist
75
+
76
+ platform_info['Error'] = "Error in layerinit: #{e.message}"
77
+
78
+ Oboe.logger.debug "Error in layerinit: #{e.message}"
79
+ Oboe.logger.debug e.backtrace
80
+ end
81
+
82
+ start_trace(layer, nil, platform_info.merge('Force' => true)) { }
83
+ end
84
+
85
+ ##
86
+ # force_trace has been deprecated and will be removed in a subsequent version.
87
+ #
88
+ def force_trace
89
+ Oboe.logger.warn "Oboe::API::LayerInit.force_trace has been deprecated and will be removed in a subsequent version."
90
+
91
+ saved_mode = Oboe::Config[:tracing_mode]
92
+ Oboe::Config[:tracing_mode] = 'always'
93
+ yield
94
+ ensure
95
+ Oboe::Config[:tracing_mode] = saved_mode
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,129 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ module Logging
7
+
8
+ # Public: Report an event in an active trace.
9
+ #
10
+ # layer - The layer the reported event belongs to
11
+ # label - The label for the reported event. See API documentation for
12
+ # reserved labels and usage.
13
+ # opts - A hash containing key/value pairs that will be reported along
14
+ # with this event (optional).
15
+ #
16
+ # Example
17
+ #
18
+ # log('logical_layer', 'entry')
19
+ # log('logical_layer', 'info', { :list_length => 20 })
20
+ # log('logical_layer', 'exit')
21
+ #
22
+ # Returns nothing.
23
+ def log(layer, label, opts={})
24
+ log_event(layer, label, Oboe::Context.createEvent, opts)
25
+ end
26
+
27
+ # Public: Report an exception.
28
+ #
29
+ # layer - The layer the reported event belongs to
30
+ # exn - The exception to report
31
+ #
32
+ # Example
33
+ #
34
+ # begin
35
+ # function_without_oboe()
36
+ # rescue Exception => e
37
+ # log_exception('rails', e)
38
+ # raise
39
+ # end
40
+ #
41
+ # Returns nothing.
42
+ def log_exception(layer, exn)
43
+ unless exn.instance_variable_get(:@oboe_logged)
44
+ log(layer, 'error', {
45
+ :ErrorClass => exn.class.name,
46
+ :Message => exn.message,
47
+ :Backtrace => exn.backtrace.join("\r\n")
48
+ })
49
+ exn.instance_variable_set(:@oboe_logged, true)
50
+ end
51
+ end
52
+
53
+ # Public: Decide whether or not to start a trace, and report an event
54
+ # appropriately.
55
+ #
56
+ # layer - The layer the reported event belongs to
57
+ # xtrace - An xtrace metadata string, or nil.
58
+ # opts - A hash containing key/value pairs that will be reported along
59
+ # with this event (optional).
60
+ #
61
+ # Returns nothing.
62
+ def log_start(layer, xtrace, opts={})
63
+ return if Oboe.never? or (opts.has_key?(:URL) and ::Oboe::Util.static_asset?(opts[:URL]))
64
+
65
+ if xtrace and not xtrace.to_s.empty?
66
+ Oboe::Context.fromString(xtrace)
67
+ end
68
+
69
+ if Oboe.tracing?
70
+ log_entry(layer, opts)
71
+ elsif opts.has_key?('Force') or Oboe.sample?(opts.merge(:layer => layer, :xtrace => xtrace))
72
+ log_event(layer, 'entry', Oboe::Context.startTrace, opts)
73
+ end
74
+ end
75
+
76
+ # Public: Report an exit event.
77
+ #
78
+ # layer - The layer the reported event belongs to
79
+ #
80
+ # Returns an xtrace metadata string
81
+ def log_end(layer, opts={})
82
+ log_event(layer, 'exit', Oboe::Context.createEvent, opts)
83
+ xtrace = Oboe::Context.toString
84
+ Oboe::Context.clear
85
+ xtrace
86
+ end
87
+
88
+ def log_entry(layer, opts={}, protect_op=nil)
89
+ Oboe.layer_op = protect_op if protect_op
90
+ log_event(layer, 'entry', Oboe::Context.createEvent, opts)
91
+ end
92
+
93
+ def log_exit(layer, opts={}, protect_op=nil)
94
+ Oboe.layer_op = nil if protect_op
95
+ log_event(layer, 'exit', Oboe::Context.createEvent, opts)
96
+ end
97
+
98
+ # Internal: Report an event.
99
+ #
100
+ # layer - The layer the reported event belongs to
101
+ # label - The label for the reported event. See API documentation for
102
+ # reserved labels and usage.
103
+ # opts - A hash containing key/value pairs that will be reported along
104
+ # with this event (optional).
105
+ #
106
+ # Examples
107
+ #
108
+ # entry = Oboe::Context.createEvent
109
+ # log_event('rails', 'entry', exit, { :controller => 'user', :action => 'index' })
110
+ # exit = Oboe::Context.createEvent
111
+ # exit.addEdge(entry.getMetadata)
112
+ # log_event('rails', 'exit', exit)
113
+ #
114
+ # Returns nothing.
115
+ def log_event(layer, label, event, opts={})
116
+ if layer
117
+ event.addInfo('Layer', layer.to_s)
118
+ end
119
+ event.addInfo('Label', label.to_s)
120
+
121
+ opts.each do |k, v|
122
+ event.addInfo(k.to_s, v.to_s) if valid_key? k
123
+ end if !opts.nil? and opts.any?
124
+
125
+ Oboe::Reporter.sendReport(event) if Oboe.loaded
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ module Memcache
7
+ MEMCACHE_OPS = %w{add append cas decr decrement delete fetch get incr increment prepend replace set}
8
+
9
+ def memcache_hit?(result)
10
+ result.nil? ? 0 : 1
11
+ end
12
+
13
+ def remote_host(key)
14
+ return unless defined?(Lib.memcached_server_by_key)\
15
+ and defined?(@struct) and defined?(is_unix_socket?)
16
+
17
+ server_as_array = Lib.memcached_server_by_key(@struct, args[0].to_s)
18
+ if server_as_array.is_a?(Array)
19
+ server = server_as_array.first
20
+ if is_unix_socket?(server)
21
+ return "localhost"
22
+ elsif defined?(server.hostname)
23
+ return server.hostname
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ module Profiling
7
+
8
+ ##
9
+ # Public: Profile a given block of code. Detect any exceptions thrown by
10
+ # the block and report errors.
11
+ #
12
+ # profile_name - A name used to identify the block being profiled.
13
+ # report_kvs - A hash containing key/value pairs that will be reported along
14
+ # with the event of this profile (optional).
15
+ # with_backtrace - Boolean to indicate whether a backtrace should
16
+ # be collected with this trace event.
17
+ #
18
+ # Example
19
+ #
20
+ # def computation(n)
21
+ # Oboe::API.profile('fib', { :n => n }) do
22
+ # fib(n)
23
+ # end
24
+ # end
25
+ #
26
+ # Returns the result of the block.
27
+ def profile(profile_name, report_kvs={}, with_backtrace=false)
28
+
29
+ report_kvs[:Language] ||= :ruby
30
+ report_kvs[:ProfileName] ||= profile_name
31
+ report_kvs[:Backtrace] = Oboe::API.backtrace if with_backtrace
32
+
33
+ Oboe::API.log(nil, 'profile_entry', report_kvs)
34
+
35
+ begin
36
+ yield
37
+ rescue Exception => e
38
+ log_exception(nil, e)
39
+ raise
40
+ ensure
41
+ exit_kvs = {}
42
+ exit_kvs[:Language] = :ruby
43
+ exit_kvs[:ProfileName] = report_kvs[:ProfileName]
44
+
45
+ Oboe::API.log(nil, 'profile_exit', exit_kvs)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,134 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module Oboe
5
+ module API
6
+ module Tracing
7
+
8
+ # Public: Trace a given block of code. Detect any exceptions thrown by
9
+ # the block and report errors.
10
+ #
11
+ # layer - The layer the block of code belongs to.
12
+ # opts - A hash containing key/value pairs that will be reported along
13
+ # with the first event of this layer (optional).
14
+ # protect_op - specify the operation being traced. Used to avoid
15
+ # double tracing between operations that call each other
16
+ #
17
+ # Example
18
+ #
19
+ # def computation(n)
20
+ # fib(n)
21
+ # raise Exception.new
22
+ # end
23
+ #
24
+ # def computation_with_oboe(n)
25
+ # trace('fib', { :number => n }) do
26
+ # computation(n)
27
+ # end
28
+ # end
29
+ #
30
+ # result = computation_with_oboe(1000)
31
+ #
32
+ # Returns the result of the block.
33
+ def trace(layer, opts={}, protect_op=nil)
34
+ log_entry(layer, opts, protect_op)
35
+ begin
36
+ yield
37
+ rescue Exception => e
38
+ log_exception(layer, e)
39
+ raise
40
+ ensure
41
+ log_exit(layer, {}, protect_op)
42
+ end
43
+ end
44
+
45
+ # Public: Trace a given block of code which can start a trace depending
46
+ # on configuration and probability. Detect any exceptions thrown by the
47
+ # block and report errors.
48
+ #
49
+ # When start_trace returns control to the calling context, the oboe
50
+ # context will be cleared.
51
+ #
52
+ # layer - The layer the block of code belongs to.
53
+ # opts - A hash containing key/value pairs that will be reported along
54
+ # with the first event of this layer (optional).
55
+ #
56
+ # Example
57
+ #
58
+ # def handle_request(request, response)
59
+ # # ... code that modifies request and response ...
60
+ # end
61
+ #
62
+ # def handle_request_with_oboe(request, response)
63
+ # result, xtrace = start_trace('rails', request['X-Trace']) do
64
+ # handle_request(request, response)
65
+ # end
66
+ # result
67
+ # rescue Exception => e
68
+ # xtrace = e.xtrace
69
+ # ensure
70
+ # response['X-trace'] = xtrace
71
+ # end
72
+ #
73
+ # Returns a list of length two, the first element of which is the result
74
+ # of the block, and the second element of which is the oboe context that
75
+ # was set when the block completed execution.
76
+ def start_trace(layer, xtrace=nil, opts={})
77
+ log_start(layer, xtrace, opts)
78
+ begin
79
+ result = yield
80
+ rescue Exception => e
81
+ log_exception(layer, e)
82
+ e.instance_variable_set(:@xtrace, log_end(layer))
83
+ raise
84
+ end
85
+ xtrace = log_end(layer)
86
+
87
+ [result, xtrace]
88
+ end
89
+
90
+ # Public: Trace a given block of code which can start a trace depending
91
+ # on configuration and probability. Detect any exceptions thrown by the
92
+ # block and report errors. Insert the oboe metadata into the provided for
93
+ # later user.
94
+ #
95
+ # The motivating use case for this is HTTP streaming in rails3. We need
96
+ # access to the exit event's trace id so we can set the header before any
97
+ # work is done, and before any headers are sent back to the client.
98
+ #
99
+ # layer - The layer the block of code belongs to.
100
+ # target - The target object in which to place the oboe metadata.
101
+ # opts - A hash containing key/value pairs that will be reported along
102
+ # with the first event of this layer (optional).
103
+ #
104
+ # Example:
105
+ #
106
+ # def handle_request(request, response)
107
+ # # ... code that does something with request and response ...
108
+ # end
109
+ #
110
+ # def handle_request_with_oboe(request, response)
111
+ # start_trace_with_target('rails', request['X-Trace'], response) do
112
+ # handle_request(request, response)
113
+ # end
114
+ # end
115
+ #
116
+ # Returns the result of the block.
117
+ def start_trace_with_target(layer, xtrace, target, opts={})
118
+ log_start(layer, xtrace, opts)
119
+ exit_evt = Oboe::Context.createEvent
120
+ begin
121
+ target['X-Trace'] = Oboe::Event.metadataString(exit_evt) if Oboe.tracing?
122
+ yield
123
+ rescue Exception => e
124
+ log_exception(layer, e)
125
+ raise
126
+ ensure
127
+ exit_evt.addEdge(Oboe::Context.get())
128
+ log_event(layer, 'exit', exit_evt)
129
+ Oboe::Context.clear
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end