traceview 3.0.0-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 (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/README +2 -0
  34. data/lib/oboe/backward_compatibility.rb +59 -0
  35. data/lib/oboe/inst/rack.rb +11 -0
  36. data/lib/oboe.rb +7 -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/api/layerinit.rb +51 -0
  41. data/lib/traceview/api/logging.rb +209 -0
  42. data/lib/traceview/api/memcache.rb +31 -0
  43. data/lib/traceview/api/profiling.rb +50 -0
  44. data/lib/traceview/api/tracing.rb +135 -0
  45. data/lib/traceview/api/util.rb +121 -0
  46. data/lib/traceview/api.rb +18 -0
  47. data/lib/traceview/base.rb +225 -0
  48. data/lib/traceview/config.rb +238 -0
  49. data/lib/traceview/frameworks/grape.rb +97 -0
  50. data/lib/traceview/frameworks/padrino/templates.rb +58 -0
  51. data/lib/traceview/frameworks/padrino.rb +64 -0
  52. data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
  53. data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
  54. data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
  55. data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
  56. data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
  57. data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
  58. data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
  59. data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
  60. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  61. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  62. data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
  63. data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  64. data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
  65. data/lib/traceview/frameworks/rails.rb +145 -0
  66. data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
  67. data/lib/traceview/frameworks/sinatra.rb +95 -0
  68. data/lib/traceview/inst/cassandra.rb +279 -0
  69. data/lib/traceview/inst/dalli.rb +86 -0
  70. data/lib/traceview/inst/em-http-request.rb +99 -0
  71. data/lib/traceview/inst/excon.rb +111 -0
  72. data/lib/traceview/inst/faraday.rb +73 -0
  73. data/lib/traceview/inst/http.rb +87 -0
  74. data/lib/traceview/inst/httpclient.rb +173 -0
  75. data/lib/traceview/inst/memcache.rb +102 -0
  76. data/lib/traceview/inst/memcached.rb +94 -0
  77. data/lib/traceview/inst/mongo.rb +238 -0
  78. data/lib/traceview/inst/moped.rb +474 -0
  79. data/lib/traceview/inst/rack.rb +122 -0
  80. data/lib/traceview/inst/redis.rb +271 -0
  81. data/lib/traceview/inst/resque.rb +192 -0
  82. data/lib/traceview/inst/rest-client.rb +38 -0
  83. data/lib/traceview/inst/sequel.rb +162 -0
  84. data/lib/traceview/inst/typhoeus.rb +102 -0
  85. data/lib/traceview/instrumentation.rb +21 -0
  86. data/lib/traceview/loading.rb +94 -0
  87. data/lib/traceview/logger.rb +41 -0
  88. data/lib/traceview/method_profiling.rb +84 -0
  89. data/lib/traceview/ruby.rb +36 -0
  90. data/lib/traceview/support.rb +113 -0
  91. data/lib/traceview/thread_local.rb +26 -0
  92. data/lib/traceview/util.rb +250 -0
  93. data/lib/traceview/version.rb +16 -0
  94. data/lib/traceview/xtrace.rb +90 -0
  95. data/lib/traceview.rb +62 -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 +248 -0
@@ -0,0 +1,159 @@
1
+ # AppNeta TraceView Initializer (the oboe gem)
2
+ # http://www.appneta.com/products/traceview/
3
+ #
4
+ # More information on instrumenting Ruby applications can be found here:
5
+ # https://support.appneta.com/cloud/installing-ruby-instrumentation
6
+
7
+ if defined?(TraceView::Config)
8
+ # Tracing Mode determines when traces should be initiated for incoming requests. Valid
9
+ # options are always, through (when using an instrumented Apache or Nginx) and never.
10
+ #
11
+ # If you're not using an instrumented Apache or Nginx, set this directive to always in
12
+ # order to initiate tracing from Ruby.
13
+ TraceView::Config[:tracing_mode] = '<%= @tracing_mode %>'
14
+
15
+ # Verbose output of instrumentation initialization
16
+ # TraceView::Config[:verbose] = <%= @verbose %>
17
+
18
+ # Logging of outgoing HTTP query args
19
+ #
20
+ # This optionally disables the logging of query args of outgoing
21
+ # HTTP clients such as Net::HTTP, excon, typhoeus and others.
22
+ #
23
+ # This flag is global to all HTTP client instrumentation.
24
+ #
25
+ # To configure this on a per instrumentation basis, set this
26
+ # option to true and instead disable the instrumenstation specific
27
+ # option <tt>log_args</tt>:
28
+ #
29
+ # TraceView::Config[:nethttp][:log_args] = false
30
+ # TraceView::Config[:excon][:log_args] = false
31
+ # TraceView::Config[:typhoeus][:log_args] = true
32
+ #
33
+ TraceView::Config[:include_url_query_params] = true
34
+
35
+ # Logging of incoming HTTP query args
36
+ #
37
+ # This optionally disables the logging of incoming URL request
38
+ # query args.
39
+ #
40
+ # This flag is global and currently only affects the Rack
41
+ # instrumentation which reports incoming request URLs and
42
+ # query args by default.
43
+ TraceView::Config[:include_remote_url_params] = true
44
+
45
+ # The oboe Ruby client has the ability to sanitize query literals
46
+ # from SQL statements. By default this is disabled. Enable to
47
+ # avoid collecting and reporting query literals to TraceView.
48
+ # TraceView::Config[:sanitize_sql] = false
49
+
50
+ # Do Not Trace
51
+ # These two values allow you to configure specific URL patterns to
52
+ # never be traced. By default, this is set to common static file
53
+ # extensions but you may want to customize this list for your needs.
54
+ #
55
+ # dnt_regexp and dnt_opts is passed to Regexp.new to create
56
+ # a regular expression object. That is then used to match against
57
+ # the incoming request path.
58
+ #
59
+ # The path string originates from the rack layer and is retrieved
60
+ # as follows:
61
+ #
62
+ # req = ::Rack::Request.new(env)
63
+ # path = URI.unescape(req.path)
64
+ #
65
+ # Usage:
66
+ # TraceView::Config[:dnt_regexp] = "lobster$"
67
+ # TraceView::Config[:dnt_opts] = Regexp::IGNORECASE
68
+ #
69
+ # This will ignore all requests that end with the string lobster
70
+ # regardless of case
71
+ #
72
+ # Requests with positive matches (non nil) will not be traced.
73
+ # See lib/oboe/util.rb: TraceView::Util.static_asset?
74
+ #
75
+ # TraceView::Config[:dnt_regexp] = "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|svg|less)$"
76
+ # TraceView::Config[:dnt_opts] = Regexp::IGNORECASE
77
+
78
+ #
79
+ # Rails Exception Logging
80
+ #
81
+ # In Rails, raised exceptions with rescue handlers via
82
+ # <tt>rescue_from</tt> are not reported to the TraceView
83
+ # dashboard by default. Setting this value to true will
84
+ # report all raised exception regardless.
85
+ #
86
+ # TraceView::Config[:report_rescued_errors] = false
87
+ #
88
+
89
+ #
90
+ # Enabling/Disabling Instrumentation
91
+ #
92
+ # If you're having trouble with one of the instrumentation libraries, they
93
+ # can be individually disabled here by setting the :enabled
94
+ # value to false:
95
+ #
96
+ # TraceView::Config[:action_controller][:enabled] = true
97
+ # TraceView::Config[:active_record][:enabled] = true
98
+ # TraceView::Config[:action_view][:enabled] = true
99
+ # TraceView::Config[:cassandra][:enabled] = true
100
+ # TraceView::Config[:dalli][:enabled] = true
101
+ # TraceView::Config[:excon][:enabled] = true
102
+ # TraceView::Config[:em_http_request][:enabled] = true
103
+ # TraceView::Config[:faraday][:enabled] = true
104
+ # TraceView::Config[:httpclient][:enabled] = true
105
+ # TraceView::Config[:memcache][:enabled] = true
106
+ # TraceView::Config[:memcached][:enabled] = true
107
+ # TraceView::Config[:mongo][:enabled] = true
108
+ # TraceView::Config[:moped][:enabled] = true
109
+ # TraceView::Config[:nethttp][:enabled] = true
110
+ # TraceView::Config[:redis][:enabled] = true
111
+ # TraceView::Config[:resque][:enabled] = true
112
+ # TraceView::Config[:rest_client][:enabled] = true
113
+ # TraceView::Config[:sequel][:enabled] = true
114
+ # TraceView::Config[:typhoeus][:enabled] = true
115
+ #
116
+
117
+ #
118
+ # Enabling/Disabling Backtrace Collection
119
+ #
120
+ # Instrumentation can optionally collect backtraces as they collect
121
+ # performance metrics. Note that this has a negative impact on
122
+ # performance but can be useful when trying to locate the source of
123
+ # a certain call or operation.
124
+ #
125
+ # TraceView::Config[:action_controller][:collect_backtraces] = true
126
+ # TraceView::Config[:active_record][:collect_backtraces] = true
127
+ # TraceView::Config[:action_view][:collect_backtraces] = true
128
+ # TraceView::Config[:cassandra][:collect_backtraces] = true
129
+ # TraceView::Config[:dalli][:collect_backtraces] = false
130
+ # TraceView::Config[:excon][:collect_backtraces] = false
131
+ # TraceView::Config[:em_http_request][:collect_backtraces] = true
132
+ # TraceView::Config[:faraday][:collect_backtraces] = false
133
+ # TraceView::Config[:httpclient][:collect_backtraces] = false
134
+ # TraceView::Config[:memcache][:collect_backtraces] = false
135
+ # TraceView::Config[:memcached][:collect_backtraces] = false
136
+ # TraceView::Config[:mongo][:collect_backtraces] = true
137
+ # TraceView::Config[:moped][:collect_backtraces] = true
138
+ # TraceView::Config[:nethttp][:collect_backtraces] = true
139
+ # TraceView::Config[:redis][:collect_backtraces] = false
140
+ # TraceView::Config[:resque][:collect_backtraces] = true
141
+ # TraceView::Config[:rest_client][:collect_backtraces] = true
142
+ # TraceView::Config[:sequel][:collect_backtraces] = true
143
+ # TraceView::Config[:typhoeus][:collect_backtraces] = false
144
+ #
145
+
146
+ #
147
+ # Resque Options
148
+ #
149
+ # :link_workers - associates Resque enqueue operations with the jobs they queue by piggybacking
150
+ # an additional argument on the Redis queue that is stripped prior to job
151
+ # processing
152
+ # !!! Note: Make sure both the enqueue side and the Resque workers are instrumented
153
+ # before enabling this or jobs will fail !!!
154
+ # (Default: false)
155
+ # TraceView::Config[:resque][:link_workers] = false
156
+ #
157
+ # Set to true to disable Resque argument logging (Default: false)
158
+ # TraceView::Config[:resque][:log_args] = false
159
+ end
@@ -0,0 +1,51 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module API
6
+ ##
7
+ # Provides methods related to layer initialization and reporting
8
+ module LayerInit
9
+ # Internal: Report that instrumentation for the given layer has been
10
+ # installed, as well as the version of instrumentation and version of
11
+ # layer.
12
+ #
13
+ def report_init(layer = 'rack')
14
+ # Don't send __Init in development or test
15
+ return if %w(development test).include? ENV['RACK_ENV']
16
+
17
+ # Don't send __Init if the c-extension hasn't loaded
18
+ return unless TraceView.loaded
19
+
20
+ platform_info = TraceView::Util.build_init_report
21
+
22
+ # If already tracing, save and clear the context. Restore it after
23
+ # the __Init is sent
24
+ context = nil
25
+
26
+ if TraceView.tracing?
27
+ context = TraceView::Context.toString
28
+ TraceView::Context.clear
29
+ end
30
+
31
+ start_trace(layer, nil, platform_info.merge('Force' => true)) {}
32
+
33
+ TraceView::Context.fromString(context) if context
34
+ end
35
+
36
+ ##
37
+ # force_trace has been deprecated and will be removed in a subsequent version.
38
+ #
39
+ def force_trace
40
+ TraceView.logger.warn 'TraceView::API::LayerInit.force_trace has been deprecated and will be ' \
41
+ 'removed in a subsequent version.'
42
+
43
+ saved_mode = TraceView::Config[:tracing_mode]
44
+ TraceView::Config[:tracing_mode] = 'always'
45
+ yield
46
+ ensure
47
+ TraceView::Config[:tracing_mode] = saved_mode
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,209 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module API
6
+ ##
7
+ # This modules provides the X-Trace logging facilities.
8
+ module Logging
9
+ # Public: Report an event in an active trace.
10
+ #
11
+ # layer - The layer the reported event belongs to
12
+ # label - The label for the reported event. See API documentation for
13
+ # reserved labels and usage.
14
+ # opts - A hash containing key/value pairs that will be reported along
15
+ # with this event (optional).
16
+ #
17
+ # Example
18
+ #
19
+ # log('logical_layer', 'entry')
20
+ # log('logical_layer', 'info', { :list_length => 20 })
21
+ # log('logical_layer', 'exit')
22
+ #
23
+ # Returns nothing.
24
+ def log(layer, label, opts = {})
25
+ if TraceView.loaded
26
+ log_event(layer, label, TraceView::Context.createEvent, opts)
27
+ end
28
+ end
29
+
30
+ # Public: Report an exception.
31
+ #
32
+ # layer - The layer the reported event belongs to
33
+ # exn - The exception to report
34
+ #
35
+ # Example
36
+ #
37
+ # begin
38
+ # function_without_traceview()
39
+ # rescue Exception => e
40
+ # log_exception('rails', e)
41
+ # raise
42
+ # end
43
+ #
44
+ # Returns nothing.
45
+ def log_exception(layer, exn)
46
+ return if !TraceView.loaded || exn.instance_variable_get(:@oboe_logged)
47
+
48
+ kvs = { :ErrorClass => exn.class.name,
49
+ :ErrorMsg => exn.message,
50
+ :Backtrace => exn.backtrace.join("\r\n") }
51
+
52
+ exn.instance_variable_set(:@oboe_logged, true)
53
+ log(layer, 'error', kvs)
54
+ end
55
+
56
+ # Public: Decide whether or not to start a trace, and report an event
57
+ # appropriately.
58
+ #
59
+ # layer - The layer the reported event belongs to
60
+ # xtrace - An xtrace metadata string, or nil.
61
+ # opts - A hash containing key/value pairs that will be reported along
62
+ # with this event (optional).
63
+ #
64
+ # Returns nothing.
65
+ def log_start(layer, xtrace = nil, opts = {})
66
+ return if !TraceView.loaded || TraceView.never? ||
67
+ (opts.key?(:URL) && ::TraceView::Util.static_asset?(opts[:URL]))
68
+
69
+ TraceView::Context.fromString(xtrace) if TraceView.pickup_context?(xtrace)
70
+
71
+ if TraceView.tracing?
72
+ # Pre-existing context. Either we inherited context from an
73
+ # incoming X-Trace request header or under JRuby, Joboe started
74
+ # tracing before the JRuby code was called (e.g. Tomcat)
75
+ TraceView.is_continued_trace = true
76
+
77
+ if TraceView.has_xtrace_header
78
+ opts[:TraceOrigin] = :continued_header
79
+ elsif TraceView.has_incoming_context
80
+ opts[:TraceOrigin] = :continued_context
81
+ else
82
+ opts[:TraceOrigin] = :continued
83
+ end
84
+
85
+ log_entry(layer, opts)
86
+
87
+ elsif opts.key?('Force')
88
+ # Forced tracing: used by __Init reporting
89
+ opts[:TraceOrigin] = :forced
90
+ log_event(layer, 'entry', TraceView::Context.startTrace, opts)
91
+
92
+ elsif TraceView.sample?(opts.merge(:layer => layer, :xtrace => xtrace))
93
+ # Probablistic tracing of a subset of requests based off of
94
+ # sample rate and sample source
95
+ opts[:SampleRate] = TraceView.sample_rate
96
+ opts[:SampleSource] = TraceView.sample_source
97
+ opts[:TraceOrigin] = :always_sampled
98
+
99
+ log_event(layer, 'entry', TraceView::Context.startTrace, opts)
100
+ end
101
+ end
102
+
103
+ # Public: Report an exit event.
104
+ #
105
+ # layer - The layer the reported event belongs to
106
+ #
107
+ # Returns an xtrace metadata string
108
+ def log_end(layer, opts = {})
109
+ if TraceView.loaded
110
+ log_event(layer, 'exit', TraceView::Context.createEvent, opts)
111
+ xtrace = TraceView::Context.toString
112
+ TraceView::Context.clear unless TraceView.has_incoming_context?
113
+ xtrace
114
+ end
115
+ end
116
+
117
+ ##
118
+ # Public: Log an entry event
119
+ #
120
+ # A helper method to create and log an
121
+ # entry event
122
+ #
123
+ # Returns an xtrace metadata string
124
+ def log_entry(layer, kvs = {}, op = nil)
125
+ if TraceView.loaded
126
+ TraceView.layer_op = op if op
127
+ log_event(layer, 'entry', TraceView::Context.createEvent, kvs)
128
+ end
129
+ end
130
+
131
+ ##
132
+ # Public: Log an info event
133
+ #
134
+ # A helper method to create and log an
135
+ # info event
136
+ #
137
+ # Returns an xtrace metadata string
138
+ def log_info(layer, kvs = {})
139
+ if TraceView.loaded
140
+ log_event(layer, 'info', TraceView::Context.createEvent, kvs)
141
+ end
142
+ end
143
+
144
+ ##
145
+ # Public: Log an exit event
146
+ #
147
+ # A helper method to create and log an
148
+ # exit event
149
+ #
150
+ # Returns an xtrace metadata string
151
+ def log_exit(layer, kvs = {}, op = nil)
152
+ if TraceView.loaded
153
+ TraceView.layer_op = nil if op
154
+ log_event(layer, 'exit', TraceView::Context.createEvent, kvs)
155
+ end
156
+ end
157
+
158
+ # Internal: Report an event.
159
+ #
160
+ # layer - The layer the reported event belongs to
161
+ # label - The label for the reported event. See API documentation for
162
+ # reserved labels and usage.
163
+ # opts - A hash containing key/value pairs that will be reported along
164
+ # with this event (optional).
165
+ #
166
+ # Examples
167
+ #
168
+ # entry = TraceView::Context.createEvent
169
+ # log_event('rails', 'entry', exit, { :controller => 'user', :action => 'index' })
170
+ # exit = TraceView::Context.createEvent
171
+ # exit.addEdge(entry.getMetadata)
172
+ # log_event('rails', 'exit', exit)
173
+ #
174
+ # Returns nothing.
175
+ def log_event(layer, label, event, opts = {})
176
+ if TraceView.loaded
177
+ event.addInfo('Layer', layer.to_s) if layer
178
+ event.addInfo('Label', label.to_s)
179
+
180
+ TraceView.layer = layer if label == 'entry'
181
+ TraceView.layer = nil if label == 'exit'
182
+
183
+ opts.each do |k, v|
184
+ value = nil
185
+
186
+ if valid_key? k
187
+ if [Integer, Float, Fixnum, NilClass, String].include?(v.class)
188
+ value = v
189
+ elsif v.class == Set
190
+ value = v.to_a.to_s
191
+ else
192
+ value = v.to_s if v.respond_to?(:to_s)
193
+ end
194
+
195
+ begin
196
+ event.addInfo(k.to_s, value)
197
+ rescue ArgumentError => e
198
+ TraceView.logger.debug "[TraceView/debug] Couldn't add event KV: #{k.to_s} => #{v.class}"
199
+ TraceView.logger.debug "[TraceView/debug] #{e.message}"
200
+ end
201
+ end
202
+ end if !opts.nil? && opts.any?
203
+
204
+ TraceView::Reporter.sendReport(event)
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,31 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module API
6
+ ##
7
+ # Utility methods for the Memcache instrumentation
8
+ module Memcache
9
+ MEMCACHE_OPS = %w(add append cas decr decrement delete fetch get incr increment prepend replace set)
10
+
11
+ def memcache_hit?(result)
12
+ result.nil? ? 0 : 1
13
+ end
14
+
15
+ def remote_host(key)
16
+ return unless defined?(Lib.memcached_server_by_key) \
17
+ && defined?(@struct) && defined?(is_unix_socket?)
18
+
19
+ server_as_array = Lib.memcached_server_by_key(@struct, key.to_s)
20
+ if server_as_array.is_a?(Array)
21
+ server = server_as_array.first
22
+ if is_unix_socket?(server)
23
+ return 'localhost'
24
+ elsif defined?(server.hostname)
25
+ return server.hostname
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module API
6
+ ##
7
+ # Module that provides profiling of arbitrary blocks of code
8
+ module Profiling
9
+ ##
10
+ # Public: Profile a given block of code. Detect any exceptions thrown by
11
+ # the block and report errors.
12
+ #
13
+ # profile_name - A name used to identify the block being profiled.
14
+ # report_kvs - A hash containing key/value pairs that will be reported along
15
+ # with the event of this profile (optional).
16
+ # with_backtrace - Boolean to indicate whether a backtrace should
17
+ # be collected with this trace event.
18
+ #
19
+ # Example
20
+ #
21
+ # def computation(n)
22
+ # TraceView::API.profile('fib', { :n => n }) do
23
+ # fib(n)
24
+ # end
25
+ # end
26
+ #
27
+ # Returns the result of the block.
28
+ def profile(profile_name, report_kvs = {}, with_backtrace = false)
29
+ report_kvs[:Language] ||= :ruby
30
+ report_kvs[:ProfileName] ||= profile_name
31
+ report_kvs[:Backtrace] = TraceView::API.backtrace if with_backtrace
32
+
33
+ TraceView::API.log(nil, 'profile_entry', report_kvs)
34
+
35
+ begin
36
+ yield
37
+ rescue => 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
+ TraceView::API.log(nil, 'profile_exit', exit_kvs)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,135 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module API
6
+ ##
7
+ # Provides the higher-level tracing interface for the API.
8
+ module Tracing
9
+ # Public: Trace a given block of code. Detect any exceptions thrown by
10
+ # the block and report errors.
11
+ #
12
+ # layer - The layer the block of code belongs to.
13
+ # opts - A hash containing key/value pairs that will be reported along
14
+ # with the first event of this layer (optional).
15
+ # protect_op - specify the operation being traced. Used to avoid
16
+ # double tracing between operations that call each other
17
+ #
18
+ # Example
19
+ #
20
+ # def computation(n)
21
+ # fib(n)
22
+ # raise Exception.new
23
+ # end
24
+ #
25
+ # def computation_with_oboe(n)
26
+ # trace('fib', { :number => n }) do
27
+ # computation(n)
28
+ # end
29
+ # end
30
+ #
31
+ # result = computation_with_oboe(1000)
32
+ #
33
+ # Returns the result of the block.
34
+ def trace(layer, opts = {}, protect_op = nil)
35
+ log_entry(layer, opts, protect_op)
36
+ begin
37
+ yield
38
+ rescue Exception => e
39
+ log_exception(layer, e)
40
+ raise
41
+ ensure
42
+ log_exit(layer, {}, protect_op)
43
+ end
44
+ end
45
+
46
+ # Public: Trace a given block of code which can start a trace depending
47
+ # on configuration and probability. Detect any exceptions thrown by the
48
+ # block and report errors.
49
+ #
50
+ # When start_trace returns control to the calling context, the oboe
51
+ # context will be cleared.
52
+ #
53
+ # layer - The layer the block of code belongs to.
54
+ # opts - A hash containing key/value pairs that will be reported along
55
+ # with the first event of this layer (optional).
56
+ #
57
+ # Example
58
+ #
59
+ # def handle_request(request, response)
60
+ # # ... code that modifies request and response ...
61
+ # end
62
+ #
63
+ # def handle_request_with_oboe(request, response)
64
+ # result, xtrace = start_trace('rails', request['X-Trace']) do
65
+ # handle_request(request, response)
66
+ # end
67
+ # result
68
+ # rescue Exception => e
69
+ # xtrace = e.xtrace
70
+ # ensure
71
+ # response['X-trace'] = xtrace
72
+ # end
73
+ #
74
+ # Returns a list of length two, the first element of which is the result
75
+ # of the block, and the second element of which is the oboe context that
76
+ # was set when the block completed execution.
77
+ def start_trace(layer, xtrace = nil, opts = {})
78
+ log_start(layer, xtrace, opts)
79
+ begin
80
+ result = yield
81
+ rescue Exception => e
82
+ log_exception(layer, e)
83
+ e.instance_variable_set(:@xtrace, log_end(layer))
84
+ raise
85
+ end
86
+ xtrace = log_end(layer)
87
+
88
+ [result, xtrace]
89
+ end
90
+
91
+ # Public: Trace a given block of code which can start a trace depending
92
+ # on configuration and probability. Detect any exceptions thrown by the
93
+ # block and report errors. Insert the oboe metadata into the provided for
94
+ # later user.
95
+ #
96
+ # The motivating use case for this is HTTP streaming in rails3. We need
97
+ # access to the exit event's trace id so we can set the header before any
98
+ # work is done, and before any headers are sent back to the client.
99
+ #
100
+ # layer - The layer the block of code belongs to.
101
+ # target - The target object in which to place the oboe metadata.
102
+ # opts - A hash containing key/value pairs that will be reported along
103
+ # with the first event of this layer (optional).
104
+ #
105
+ # Example:
106
+ #
107
+ # def handle_request(request, response)
108
+ # # ... code that does something with request and response ...
109
+ # end
110
+ #
111
+ # def handle_request_with_oboe(request, response)
112
+ # start_trace_with_target('rails', request['X-Trace'], response) do
113
+ # handle_request(request, response)
114
+ # end
115
+ # end
116
+ #
117
+ # Returns the result of the block.
118
+ def start_trace_with_target(layer, xtrace, target, opts = {})
119
+ log_start(layer, xtrace, opts)
120
+ exit_evt = TraceView::Context.createEvent
121
+ begin
122
+ target['X-Trace'] = TraceView::Event.metadataString(exit_evt) if TraceView.tracing?
123
+ yield
124
+ rescue Exception => e
125
+ log_exception(layer, e)
126
+ raise
127
+ ensure
128
+ exit_evt.addEdge(TraceView::Context.get)
129
+ log_event(layer, 'exit', exit_evt)
130
+ TraceView::Context.clear
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end