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,48 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ if defined?(ActionView::Base) && TraceView::Config[:action_view][:enabled]
5
+
6
+ if Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR == 0
7
+
8
+ ActionView::Partials::PartialRenderer.class_eval do
9
+ alias :render_partial_without_traceview :render_partial
10
+ def render_partial(object = @object)
11
+ entry_kvs = {}
12
+ begin
13
+ name = TraceView::Util.prettify(@options[:partial]) if @options.is_a?(Hash)
14
+ entry_kvs[:FunctionName] = :render_partial
15
+ entry_kvs[:Class] = :PartialRenderer
16
+ entry_kvs[:Module] = 'ActionView::Partials'
17
+ entry_kvs[:File] = __FILE__
18
+ entry_kvs[:LineNumber] = __LINE__
19
+ rescue
20
+ end
21
+
22
+ TraceView::API.profile(name, entry_kvs, TraceView::Config[:action_view][:collect_backtraces]) do
23
+ render_partial_without_traceview(object)
24
+ end
25
+ end
26
+
27
+ alias :render_collection_without_traceview :render_collection
28
+ def render_collection
29
+ entry_kvs = {}
30
+ begin
31
+ name = TraceView::Util.prettify(@path)
32
+ entry_kvs[:FunctionName] = :render_collection
33
+ entry_kvs[:Class] = :PartialRenderer
34
+ entry_kvs[:Module] = 'ActionView::Partials'
35
+ entry_kvs[:File] = __FILE__
36
+ entry_kvs[:LineNumber] = __LINE__
37
+ rescue
38
+ end
39
+
40
+ TraceView::API.profile(name, entry_kvs, TraceView::Config[:action_view][:collect_backtraces]) do
41
+ render_collection_without_traceview
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ # vim:set expandtab:tabstop=2
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'traceview/frameworks/rails/inst/connection_adapters/utils'
5
+ require 'traceview/frameworks/rails/inst/connection_adapters/mysql'
6
+ require 'traceview/frameworks/rails/inst/connection_adapters/mysql2'
7
+ require 'traceview/frameworks/rails/inst/connection_adapters/postgresql'
8
+ require 'traceview/frameworks/rails/inst/connection_adapters/oracle'
9
+
10
+ if TraceView::Config[:active_record][:enabled] && !defined?(JRUBY_VERSION)
11
+ begin
12
+ adapter = ActiveRecord::Base.connection.adapter_name.downcase
13
+
14
+ TraceView::Inst::ConnectionAdapters::FlavorInitializers.mysql if adapter == 'mysql'
15
+ TraceView::Inst::ConnectionAdapters::FlavorInitializers.mysql2 if adapter == 'mysql2'
16
+ TraceView::Inst::ConnectionAdapters::FlavorInitializers.postgresql if adapter == 'postgresql'
17
+ TraceView::Inst::ConnectionAdapters::FlavorInitializers.oracle if adapter == 'oracleenhanced'
18
+
19
+ rescue StandardError => e
20
+ TraceView.logger.error "[traceview/error] TraceView/ActiveRecord error: #{e.inspect}"
21
+ TraceView.logger.debug e.backtrace.join("\n")
22
+ end
23
+ end
24
+ # vim:set expandtab:tabstop=2
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module ConnectionAdapters
7
+ module FlavorInitializers
8
+ def self.mysql
9
+ TraceView.logger.info '[traceview/loading] Instrumenting activerecord mysqladapter' if TraceView::Config[:verbose]
10
+
11
+ # ActiveRecord 3.2 and higher
12
+ if (::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR >= 2) ||
13
+ ::ActiveRecord::VERSION::MAJOR == 4
14
+
15
+ # AbstractMysqlAdapter
16
+ TraceView::Util.send_include(::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter,
17
+ ::TraceView::Inst::ConnectionAdapters::Utils)
18
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, :execute)
19
+
20
+ # MysqlAdapter
21
+ TraceView::Util.send_include(::ActiveRecord::ConnectionAdapters::MysqlAdapter,
22
+ ::TraceView::Inst::ConnectionAdapters::Utils)
23
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::MysqlAdapter, :exec_query)
24
+
25
+ else
26
+ # ActiveRecord 3.1 and below
27
+
28
+ # MysqlAdapter
29
+ TraceView::Util.send_include(::ActiveRecord::ConnectionAdapters::MysqlAdapter,
30
+ ::TraceView::Inst::ConnectionAdapters::Utils)
31
+
32
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::MysqlAdapter, :execute)
33
+
34
+ if ::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR == 1
35
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::MysqlAdapter, :begin_db_transaction)
36
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::MysqlAdapter, :exec_delete)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module ConnectionAdapters
7
+ module FlavorInitializers
8
+ def self.mysql2
9
+ TraceView.logger.info '[traceview/loading] Instrumenting activerecord mysql2adapter' if TraceView::Config[:verbose]
10
+
11
+ TraceView::Util.send_include(::ActiveRecord::ConnectionAdapters::Mysql2Adapter,
12
+ ::TraceView::Inst::ConnectionAdapters::Utils)
13
+
14
+ if (::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR == 0) ||
15
+ ::ActiveRecord::VERSION::MAJOR == 2
16
+ # ActiveRecord 3.0 and prior
17
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :execute)
18
+ else
19
+ # ActiveRecord 3.1 and above
20
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_insert)
21
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_query)
22
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_delete)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module ConnectionAdapters
7
+ module FlavorInitializers
8
+ def self.oracle
9
+ TraceView.logger.info '[traceview/loading] Instrumenting activerecord oracleenhancedadapter' if TraceView::Config[:verbose]
10
+ ::ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.module_eval do
11
+ include TraceView::Inst::ConnectionAdapters
12
+ end if defined?(::ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module ConnectionAdapters
7
+ module FlavorInitializers
8
+ def self.postgresql
9
+
10
+ TraceView.logger.info '[traceview/loading] Instrumenting activerecord postgresqladapter' if TraceView::Config[:verbose]
11
+
12
+ TraceView::Util.send_include(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter,
13
+ ::TraceView::Inst::ConnectionAdapters::Utils)
14
+
15
+ if (::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR > 0) ||
16
+ ::ActiveRecord::VERSION::MAJOR == 4
17
+
18
+ # ActiveRecord 3.1 and up
19
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_query)
20
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_delete)
21
+
22
+ else
23
+ # ActiveRecord 3.0 and prior
24
+ TraceView::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :execute)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,117 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Inst
6
+ module ConnectionAdapters
7
+ module Utils
8
+
9
+ def extract_trace_details(sql, name = nil, binds = [])
10
+ opts = {}
11
+
12
+ begin
13
+ if TraceView::Config[:sanitize_sql]
14
+ # Sanitize SQL and don't report binds
15
+ opts[:Query] = sql.gsub(/\'[\s\S][^\']*\'/, '?')
16
+ else
17
+ # Report raw SQL and any binds if they exist
18
+ opts[:Query] = sql.to_s
19
+ opts[:QueryArgs] = binds.map { |col, val| type_cast(val, col) } unless binds.empty?
20
+ end
21
+
22
+ opts[:Name] = name.to_s if name
23
+ opts[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:active_record][:collect_backtraces]
24
+
25
+ if ::Rails::VERSION::MAJOR == 2
26
+ config = ::Rails.configuration.database_configuration[::Rails.env]
27
+ else
28
+ config = ::Rails.application.config.database_configuration[::Rails.env]
29
+ end
30
+
31
+ opts[:Database] = config['database'] if config.key?('database')
32
+ opts[:RemoteHost] = config['host'] if config.key?('host')
33
+ opts[:Flavor] = config['adapter'] if config.key?('adapter')
34
+ rescue StandardError => e
35
+ TraceView.logger.debug "Exception raised capturing ActiveRecord KVs: #{e.inspect}"
36
+ TraceView.logger.debug e.backtrace.join('\n')
37
+ end
38
+
39
+ return opts || {}
40
+ end
41
+
42
+ # We don't want to trace framework caches. Only instrument SQL that
43
+ # directly hits the database.
44
+ def ignore_payload?(name)
45
+ %w(SCHEMA EXPLAIN CACHE).include?(name.to_s) ||
46
+ (name && name.to_sym == :skip_logging) ||
47
+ name == 'ActiveRecord::SchemaMigration Load'
48
+ end
49
+
50
+ # def cfg
51
+ # @config
52
+ # end
53
+
54
+ def execute_with_traceview(sql, name = nil)
55
+ if TraceView.tracing? && !ignore_payload?(name)
56
+
57
+ opts = extract_trace_details(sql, name)
58
+ TraceView::API.trace('activerecord', opts || {}) do
59
+ execute_without_traceview(sql, name)
60
+ end
61
+ else
62
+ execute_without_traceview(sql, name)
63
+ end
64
+ end
65
+
66
+ def exec_query_with_traceview(sql, name = nil, binds = [])
67
+ if TraceView.tracing? && !ignore_payload?(name)
68
+
69
+ opts = extract_trace_details(sql, name, binds)
70
+ TraceView::API.trace('activerecord', opts || {}) do
71
+ exec_query_without_traceview(sql, name, binds)
72
+ end
73
+ else
74
+ exec_query_without_traceview(sql, name, binds)
75
+ end
76
+ end
77
+
78
+ def exec_delete_with_traceview(sql, name = nil, binds = [])
79
+ if TraceView.tracing? && !ignore_payload?(name)
80
+
81
+ opts = extract_trace_details(sql, name, binds)
82
+ TraceView::API.trace('activerecord', opts || {}) do
83
+ exec_delete_without_traceview(sql, name, binds)
84
+ end
85
+ else
86
+ exec_delete_without_traceview(sql, name, binds)
87
+ end
88
+ end
89
+
90
+ def exec_insert_with_traceview(sql, name = nil, binds = [], *args)
91
+ if TraceView.tracing? && !ignore_payload?(name)
92
+
93
+ opts = extract_trace_details(sql, name, binds)
94
+ TraceView::API.trace('activerecord', opts || {}) do
95
+ exec_insert_without_traceview(sql, name, binds, *args)
96
+ end
97
+ else
98
+ exec_insert_without_traceview(sql, name, binds, *args)
99
+ end
100
+ end
101
+
102
+ def begin_db_transaction_with_traceview
103
+ if TraceView.tracing?
104
+ opts = {}
105
+
106
+ opts[:Query] = 'BEGIN'
107
+ TraceView::API.trace('activerecord', opts || {}) do
108
+ begin_db_transaction_without_traceview
109
+ end
110
+ else
111
+ begin_db_transaction_without_traceview
112
+ end
113
+ end
114
+ end # Utils
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,95 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Sinatra
6
+ module Base
7
+ def self.included(klass)
8
+ ::TraceView::Util.method_alias(klass, :dispatch!, ::Sinatra::Base)
9
+ ::TraceView::Util.method_alias(klass, :handle_exception!, ::Sinatra::Base)
10
+ end
11
+
12
+ def dispatch_with_traceview
13
+ if TraceView.tracing?
14
+ report_kvs = {}
15
+
16
+ report_kvs[:Controller] = self.class
17
+ report_kvs[:Action] = env['PATH_INFO']
18
+
19
+ # Fall back to the raw tracing API so we can pass KVs
20
+ # back on exit (a limitation of the TraceView::API.trace
21
+ # block method) This removes the need for an info
22
+ # event to send additonal KVs
23
+ ::TraceView::API.log_entry('sinatra', {})
24
+
25
+ begin
26
+ dispatch_without_traceview
27
+ ensure
28
+ ::TraceView::API.log_exit('sinatra', report_kvs)
29
+ end
30
+ else
31
+ dispatch_without_traceview
32
+ end
33
+ end
34
+
35
+ def handle_exception_with_traceview(boom)
36
+ TraceView::API.log_exception(nil, boom) if TraceView.tracing?
37
+ handle_exception_without_traceview(boom)
38
+ end
39
+
40
+ @@rum_xhr_tmpl = File.read(File.dirname(__FILE__) + '/rails/helpers/rum/rum_ajax_header.js.erb')
41
+ @@rum_hdr_tmpl = File.read(File.dirname(__FILE__) + '/rails/helpers/rum/rum_header.js.erb')
42
+ @@rum_ftr_tmpl = File.read(File.dirname(__FILE__) + '/rails/helpers/rum/rum_footer.js.erb')
43
+
44
+ def traceview_rum_header
45
+ return unless TraceView::Config.rum_id
46
+ if TraceView.tracing?
47
+ if request.xhr?
48
+ return ERB.new(@@rum_xhr_tmpl).result
49
+ else
50
+ return ERB.new(@@rum_hdr_tmpl).result
51
+ end
52
+ end
53
+ rescue StandardError => e
54
+ TraceView.logger.warn "traceview_rum_header: #{e.message}."
55
+ return ''
56
+ end
57
+
58
+ def traceview_rum_footer
59
+ return unless TraceView::Config.rum_id
60
+ if TraceView.tracing?
61
+ # Even though the footer template is named xxxx.erb, there are no ERB tags in it so we'll
62
+ # skip that step for now
63
+ return @@rum_ftr_tmpl
64
+ end
65
+ rescue StandardError => e
66
+ TraceView.logger.warn "traceview_rum_footer: #{e.message}."
67
+ return ''
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ if defined?(::Sinatra)
74
+ require 'traceview/inst/rack'
75
+ require 'traceview/frameworks/sinatra/templates'
76
+
77
+ TraceView.logger.info '[traceview/loading] Instrumenting Sinatra' if TraceView::Config[:verbose]
78
+
79
+ TraceView::Loading.load_access_key
80
+ TraceView::Inst.load_instrumentation
81
+
82
+ ::Sinatra::Base.use TraceView::Rack
83
+
84
+ # When in the gem TEST environment, we load this instrumentation regardless.
85
+ # Otherwise, only when Padrino isn't around.
86
+ unless defined?(::Padrino) and not (ENV.key?('TRACEVIEW_GEM_TEST'))
87
+ # Padrino has 'enhanced' routes and rendering so the Sinatra
88
+ # instrumentation won't work anyways. Only load for pure Sinatra apps.
89
+ ::TraceView::Util.send_include(::Sinatra::Base, ::TraceView::Sinatra::Base)
90
+ ::TraceView::Util.send_include(::Sinatra::Templates, ::TraceView::Sinatra::Templates)
91
+
92
+ # Report __Init after fork when in Heroku
93
+ TraceView::API.report_init unless TraceView.heroku?
94
+ end
95
+ end
@@ -0,0 +1,56 @@
1
+ # Copyright (c) 2013 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ module TraceView
5
+ module Sinatra
6
+ module Templates
7
+ def self.included(klass)
8
+ ::TraceView::Util.method_alias(klass, :render, ::Sinatra::Templates)
9
+ end
10
+
11
+ def render_with_traceview(engine, data, options = {}, locals = {}, &block)
12
+ if TraceView.tracing?
13
+ report_kvs = {}
14
+
15
+ report_kvs[:engine] = engine
16
+ report_kvs[:template] = data
17
+
18
+ if TraceView.tracing_layer_op?('render')
19
+ # For recursive calls to :render (for sub-partials and layouts),
20
+ # use method profiling.
21
+ begin
22
+ name = data
23
+ report_kvs[:FunctionName] = :render
24
+ report_kvs[:Class] = :Templates
25
+ report_kvs[:Module] = 'Sinatra::Templates'
26
+ report_kvs[:File] = __FILE__
27
+ report_kvs[:LineNumber] = __LINE__
28
+ rescue StandardError => e
29
+ ::TraceView.logger.debug e.message
30
+ ::TraceView.logger.debug e.backtrace.join(", ")
31
+ end
32
+
33
+ TraceView::API.profile(name, report_kvs, false) do
34
+ render_without_traceview(engine, data, options, locals, &block)
35
+ end
36
+
37
+ else
38
+ # Fall back to the raw tracing API so we can pass KVs
39
+ # back on exit (a limitation of the TraceView::API.trace
40
+ # block method) This removes the need for an info
41
+ # event to send additonal KVs
42
+ ::TraceView::API.log_entry('render', {}, 'render')
43
+
44
+ begin
45
+ render_without_traceview(engine, data, options, locals, &block)
46
+ ensure
47
+ ::TraceView::API.log_exit('render', report_kvs)
48
+ end
49
+ end
50
+ else
51
+ render_without_traceview(engine, data, options, locals, &block)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end