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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +58 -0
- data/Appraisals +10 -0
- data/CHANGELOG.md +490 -0
- data/CONFIG.md +16 -0
- data/Gemfile +95 -0
- data/LICENSE +199 -0
- data/README.md +380 -0
- data/Rakefile +109 -0
- data/examples/DNT.md +35 -0
- data/examples/carrying_context.rb +225 -0
- data/examples/instrumenting_metal_controller.rb +8 -0
- data/examples/puma_on_heroku_config.rb +17 -0
- data/examples/tracing_async_threads.rb +125 -0
- data/examples/tracing_background_jobs.rb +52 -0
- data/examples/tracing_forked_processes.rb +100 -0
- data/examples/unicorn_on_heroku_config.rb +28 -0
- data/ext/oboe_metal/extconf.rb +61 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/bson/bson.h +221 -0
- data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
- data/ext/oboe_metal/src/oboe.h +275 -0
- data/ext/oboe_metal/src/oboe.hpp +352 -0
- data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
- data/ext/oboe_metal/tests/test.rb +11 -0
- data/gemfiles/mongo.gemfile +33 -0
- data/gemfiles/moped.gemfile +33 -0
- data/get_version.rb +5 -0
- data/init.rb +4 -0
- data/lib/joboe_metal.rb +206 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +59 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe_metal.rb +151 -0
- data/lib/rails/generators/traceview/install_generator.rb +76 -0
- data/lib/rails/generators/traceview/templates/traceview_initializer.rb +159 -0
- data/lib/traceview/api/layerinit.rb +51 -0
- data/lib/traceview/api/logging.rb +209 -0
- data/lib/traceview/api/memcache.rb +31 -0
- data/lib/traceview/api/profiling.rb +50 -0
- data/lib/traceview/api/tracing.rb +135 -0
- data/lib/traceview/api/util.rb +121 -0
- data/lib/traceview/api.rb +18 -0
- data/lib/traceview/base.rb +225 -0
- data/lib/traceview/config.rb +238 -0
- data/lib/traceview/frameworks/grape.rb +97 -0
- data/lib/traceview/frameworks/padrino/templates.rb +58 -0
- data/lib/traceview/frameworks/padrino.rb +64 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
- data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
- data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
- data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
- data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
- data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
- data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
- data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
- data/lib/traceview/frameworks/rails.rb +145 -0
- data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
- data/lib/traceview/frameworks/sinatra.rb +95 -0
- data/lib/traceview/inst/cassandra.rb +279 -0
- data/lib/traceview/inst/dalli.rb +86 -0
- data/lib/traceview/inst/em-http-request.rb +99 -0
- data/lib/traceview/inst/excon.rb +111 -0
- data/lib/traceview/inst/faraday.rb +73 -0
- data/lib/traceview/inst/http.rb +87 -0
- data/lib/traceview/inst/httpclient.rb +173 -0
- data/lib/traceview/inst/memcache.rb +102 -0
- data/lib/traceview/inst/memcached.rb +94 -0
- data/lib/traceview/inst/mongo.rb +238 -0
- data/lib/traceview/inst/moped.rb +474 -0
- data/lib/traceview/inst/rack.rb +122 -0
- data/lib/traceview/inst/redis.rb +271 -0
- data/lib/traceview/inst/resque.rb +192 -0
- data/lib/traceview/inst/rest-client.rb +38 -0
- data/lib/traceview/inst/sequel.rb +162 -0
- data/lib/traceview/inst/typhoeus.rb +102 -0
- data/lib/traceview/instrumentation.rb +21 -0
- data/lib/traceview/loading.rb +94 -0
- data/lib/traceview/logger.rb +41 -0
- data/lib/traceview/method_profiling.rb +84 -0
- data/lib/traceview/ruby.rb +36 -0
- data/lib/traceview/support.rb +113 -0
- data/lib/traceview/thread_local.rb +26 -0
- data/lib/traceview/util.rb +250 -0
- data/lib/traceview/version.rb +16 -0
- data/lib/traceview/xtrace.rb +90 -0
- data/lib/traceview.rb +62 -0
- data/test/frameworks/apps/grape_nested.rb +30 -0
- data/test/frameworks/apps/grape_simple.rb +24 -0
- data/test/frameworks/apps/padrino_simple.rb +45 -0
- data/test/frameworks/apps/sinatra_simple.rb +24 -0
- data/test/frameworks/grape_test.rb +142 -0
- data/test/frameworks/padrino_test.rb +30 -0
- data/test/frameworks/sinatra_test.rb +30 -0
- data/test/instrumentation/cassandra_test.rb +380 -0
- data/test/instrumentation/dalli_test.rb +171 -0
- data/test/instrumentation/em_http_request_test.rb +86 -0
- data/test/instrumentation/excon_test.rb +207 -0
- data/test/instrumentation/faraday_test.rb +235 -0
- data/test/instrumentation/http_test.rb +140 -0
- data/test/instrumentation/httpclient_test.rb +296 -0
- data/test/instrumentation/memcache_test.rb +251 -0
- data/test/instrumentation/memcached_test.rb +226 -0
- data/test/instrumentation/mongo_test.rb +462 -0
- data/test/instrumentation/moped_test.rb +496 -0
- data/test/instrumentation/rack_test.rb +116 -0
- data/test/instrumentation/redis_hashes_test.rb +265 -0
- data/test/instrumentation/redis_keys_test.rb +318 -0
- data/test/instrumentation/redis_lists_test.rb +310 -0
- data/test/instrumentation/redis_misc_test.rb +160 -0
- data/test/instrumentation/redis_sets_test.rb +293 -0
- data/test/instrumentation/redis_sortedsets_test.rb +325 -0
- data/test/instrumentation/redis_strings_test.rb +333 -0
- data/test/instrumentation/resque_test.rb +62 -0
- data/test/instrumentation/rest-client_test.rb +294 -0
- data/test/instrumentation/sequel_mysql2_test.rb +326 -0
- data/test/instrumentation/sequel_mysql_test.rb +326 -0
- data/test/instrumentation/sequel_pg_test.rb +330 -0
- data/test/instrumentation/typhoeus_test.rb +285 -0
- data/test/minitest_helper.rb +187 -0
- data/test/profiling/method_test.rb +198 -0
- data/test/servers/rackapp_8101.rb +22 -0
- data/test/support/backcompat_test.rb +269 -0
- data/test/support/config_test.rb +128 -0
- data/test/support/dnt_test.rb +73 -0
- data/test/support/liboboe_settings_test.rb +104 -0
- data/test/support/xtrace_test.rb +35 -0
- data/traceview.gemspec +29 -0
- metadata +248 -0
|
@@ -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,145 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module TraceView
|
|
5
|
+
module Rails
|
|
6
|
+
module Helpers
|
|
7
|
+
extend ActiveSupport::Concern if defined?(::Rails) and ::Rails::VERSION::MAJOR > 2
|
|
8
|
+
|
|
9
|
+
@@rum_xhr_tmpl = File.read(File.dirname(__FILE__) + '/rails/helpers/rum/rum_ajax_header.js.erb')
|
|
10
|
+
@@rum_hdr_tmpl = File.read(File.dirname(__FILE__) + '/rails/helpers/rum/rum_header.js.erb')
|
|
11
|
+
@@rum_ftr_tmpl = File.read(File.dirname(__FILE__) + '/rails/helpers/rum/rum_footer.js.erb')
|
|
12
|
+
|
|
13
|
+
def traceview_rum_header
|
|
14
|
+
begin
|
|
15
|
+
return unless TraceView::Config.rum_id
|
|
16
|
+
if TraceView.tracing?
|
|
17
|
+
if request.xhr?
|
|
18
|
+
return raw(ERB.new(@@rum_xhr_tmpl).result)
|
|
19
|
+
else
|
|
20
|
+
return raw(ERB.new(@@rum_hdr_tmpl).result)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
rescue StandardError => e
|
|
24
|
+
TraceView.logger.warn "traceview_rum_header: #{e.message}."
|
|
25
|
+
return ""
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def traceview_rum_footer
|
|
30
|
+
begin
|
|
31
|
+
return unless TraceView::Config.rum_id
|
|
32
|
+
if TraceView.tracing?
|
|
33
|
+
# Even though the footer template is named xxxx.erb, there are no ERB tags in it so we'll
|
|
34
|
+
# skip that step for now
|
|
35
|
+
return raw(@@rum_ftr_tmpl)
|
|
36
|
+
end
|
|
37
|
+
rescue StandardError => e
|
|
38
|
+
TraceView.logger.warn "traceview_rum_footer: #{e.message}."
|
|
39
|
+
return ""
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end # Helpers
|
|
43
|
+
|
|
44
|
+
def self.load_initializer
|
|
45
|
+
# Force load the TraceView Rails initializer if there is one
|
|
46
|
+
# Prefer traceview.rb but give priority to the legacy tracelytics.rb if it exists
|
|
47
|
+
if ::Rails::VERSION::MAJOR > 2
|
|
48
|
+
rails_root = "#{::Rails.root.to_s}"
|
|
49
|
+
else
|
|
50
|
+
rails_root = "#{RAILS_ROOT}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# We've been through 3 initializer names. Try each one.
|
|
55
|
+
#
|
|
56
|
+
if File.exists?("#{rails_root}/config/initializers/tracelytics.rb")
|
|
57
|
+
tr_initializer = "#{rails_root}/config/initializers/tracelytics.rb"
|
|
58
|
+
|
|
59
|
+
elsif File.exists?("#{rails_root}/config/initializers/oboe.rb")
|
|
60
|
+
tr_initializer = "#{rails_root}/config/initializers/oboe.rb"
|
|
61
|
+
|
|
62
|
+
else
|
|
63
|
+
tr_initializer = "#{rails_root}/config/initializers/traceview.rb"
|
|
64
|
+
end
|
|
65
|
+
require tr_initializer if File.exists?(tr_initializer)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.load_instrumentation
|
|
69
|
+
# Load the Rails specific instrumentation
|
|
70
|
+
pattern = File.join(File.dirname(__FILE__), 'rails/inst', '*.rb')
|
|
71
|
+
Dir.glob(pattern) do |f|
|
|
72
|
+
begin
|
|
73
|
+
require f
|
|
74
|
+
rescue => e
|
|
75
|
+
TraceView.logger.error "[traceview/loading] Error loading rails insrumentation file '#{f}' : #{e}"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
TraceView.logger.info "TraceView gem #{TraceView::Version::STRING} successfully loaded."
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def self.include_helpers
|
|
83
|
+
# TBD: This would make the helpers available to controllers which is occasionally desired.
|
|
84
|
+
# ActiveSupport.on_load(:action_controller) do
|
|
85
|
+
# include TraceView::Rails::Helpers
|
|
86
|
+
# end
|
|
87
|
+
if ::Rails::VERSION::MAJOR > 2
|
|
88
|
+
ActiveSupport.on_load(:action_view) do
|
|
89
|
+
include TraceView::Rails::Helpers
|
|
90
|
+
end
|
|
91
|
+
else
|
|
92
|
+
ActionView::Base.send :include, TraceView::Rails::Helpers
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end # Rails
|
|
97
|
+
end # TraceView
|
|
98
|
+
|
|
99
|
+
if defined?(::Rails)
|
|
100
|
+
require 'traceview/inst/rack'
|
|
101
|
+
|
|
102
|
+
if ::Rails::VERSION::MAJOR > 2
|
|
103
|
+
module TraceView
|
|
104
|
+
class Railtie < ::Rails::Railtie
|
|
105
|
+
|
|
106
|
+
initializer 'traceview.helpers' do
|
|
107
|
+
TraceView::Rails.include_helpers
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
initializer 'traceview.rack' do |app|
|
|
111
|
+
TraceView.logger.info "[traceview/loading] Instrumenting rack" if TraceView::Config[:verbose]
|
|
112
|
+
app.config.middleware.insert 0, "TraceView::Rack"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
config.after_initialize do
|
|
116
|
+
TraceView.logger = ::Rails.logger if ::Rails.logger
|
|
117
|
+
|
|
118
|
+
TraceView::Loading.load_access_key
|
|
119
|
+
TraceView::Inst.load_instrumentation
|
|
120
|
+
TraceView::Rails.load_instrumentation
|
|
121
|
+
|
|
122
|
+
# Report __Init after fork when in Heroku
|
|
123
|
+
TraceView::API.report_init unless TraceView.heroku?
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
else
|
|
128
|
+
TraceView.logger = ::Rails.logger if ::Rails.logger
|
|
129
|
+
|
|
130
|
+
TraceView::Rails.load_initializer
|
|
131
|
+
TraceView::Loading.load_access_key
|
|
132
|
+
|
|
133
|
+
Rails.configuration.after_initialize do
|
|
134
|
+
TraceView.logger.info "[traceview/loading] Instrumenting rack" if TraceView::Config[:verbose]
|
|
135
|
+
Rails.configuration.middleware.insert 0, "TraceView::Rack"
|
|
136
|
+
|
|
137
|
+
TraceView::Inst.load_instrumentation
|
|
138
|
+
TraceView::Rails.load_instrumentation
|
|
139
|
+
TraceView::Rails.include_helpers
|
|
140
|
+
|
|
141
|
+
# Report __Init after fork when in Heroku
|
|
142
|
+
TraceView::API.report_init unless TraceView.heroku?
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
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
|
|
@@ -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,279 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module TraceView
|
|
5
|
+
module Inst
|
|
6
|
+
module Cassandra
|
|
7
|
+
def extract_trace_details(op, column_family, keys, args, options = {})
|
|
8
|
+
report_kvs = {}
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
report_kvs[:Op] = op.to_s
|
|
12
|
+
report_kvs[:Cf] = column_family.to_s if column_family
|
|
13
|
+
report_kvs[:Key] = keys.inspect if keys
|
|
14
|
+
|
|
15
|
+
# Open issue - how to handle multiple Cassandra servers
|
|
16
|
+
report_kvs[:RemoteHost], report_kvs[:RemotePort] = @servers.first.split(':')
|
|
17
|
+
|
|
18
|
+
report_kvs[:Backtrace] = TraceView::API.backtrace if TraceView::Config[:cassandra][:collect_backtraces]
|
|
19
|
+
|
|
20
|
+
if options.empty? && args.is_a?(Array)
|
|
21
|
+
options = args.last if args.last.is_a?(Hash)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
unless options.empty?
|
|
25
|
+
[:start_key, :finish_key, :key_count, :batch_size, :columns, :count, :start,
|
|
26
|
+
:stop, :finish, :finished, :reversed, :consistency, :ttl].each do |k|
|
|
27
|
+
report_kvs[k.to_s.capitalize] = options[k] if options.key?(k)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if op == :get_indexed_slices
|
|
31
|
+
index_clause = columns_and_options[:index_clause] || {}
|
|
32
|
+
unless index_clause.empty?
|
|
33
|
+
[:column_name, :value, :comparison].each do |k|
|
|
34
|
+
report_kvs[k.to_s.capitalize] = index_clause[k] if index_clause.key?(k)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
rescue
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
report_kvs
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def insert_with_traceview(column_family, key, hash, options = {})
|
|
46
|
+
return insert_without_traceview(column_family, key, hash, options = {}) unless TraceView.tracing?
|
|
47
|
+
|
|
48
|
+
report_kvs = extract_trace_details(:insert, column_family, key, hash, options)
|
|
49
|
+
|
|
50
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
51
|
+
insert_without_traceview(column_family, key, hash, options = {})
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def remove_with_traceview(column_family, key, *columns_and_options)
|
|
56
|
+
return send :remove_without_traceview, *args unless TraceView.tracing?
|
|
57
|
+
|
|
58
|
+
args = [column_family, key] + columns_and_options
|
|
59
|
+
report_kvs = extract_trace_details(:remove, column_family, key, columns_and_options)
|
|
60
|
+
|
|
61
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
62
|
+
send :remove_without_traceview, *args
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def count_columns_with_traceview(column_family, key, *columns_and_options)
|
|
67
|
+
return send :count_columns_without_traceview, *args unless TraceView.tracing?
|
|
68
|
+
|
|
69
|
+
args = [column_family, key] + columns_and_options
|
|
70
|
+
report_kvs = extract_trace_details(:count_columns, column_family, key, columns_and_options)
|
|
71
|
+
|
|
72
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
73
|
+
send :count_columns_without_traceview, *args
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def get_columns_with_traceview(column_family, key, *columns_and_options)
|
|
78
|
+
args = [column_family, key] + columns_and_options
|
|
79
|
+
|
|
80
|
+
if TraceView.tracing? && !TraceView.tracing_layer_op?(:multi_get_columns)
|
|
81
|
+
report_kvs = extract_trace_details(:get_columns, column_family, key, columns_and_options)
|
|
82
|
+
|
|
83
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
84
|
+
send :get_columns_without_traceview, *args
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
send :get_columns_without_traceview, *args
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def multi_get_columns_with_traceview(column_family, key, *columns_and_options)
|
|
92
|
+
return send :multi_get_columns_without_traceview, *args unless TraceView.tracing?
|
|
93
|
+
|
|
94
|
+
args = [column_family, key] + columns_and_options
|
|
95
|
+
report_kvs = extract_trace_details(:multi_get_columns, column_family, key, columns_and_options)
|
|
96
|
+
|
|
97
|
+
TraceView::API.trace('cassandra', report_kvs, :multi_get_columns) do
|
|
98
|
+
send :multi_get_columns_without_traceview, *args
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def get_with_traceview(column_family, key, *columns_and_options)
|
|
103
|
+
return send :get_without_traceview, *args unless TraceView.tracing?
|
|
104
|
+
|
|
105
|
+
args = [column_family, key] + columns_and_options
|
|
106
|
+
report_kvs = extract_trace_details(:get, column_family, key, columns_and_options)
|
|
107
|
+
|
|
108
|
+
TraceView::API.trace('cassandra', report_kvs, :get) do
|
|
109
|
+
send :get_without_traceview, *args
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def multi_get_with_traceview(column_family, key, *columns_and_options)
|
|
114
|
+
args = [column_family, key] + columns_and_options
|
|
115
|
+
|
|
116
|
+
if TraceView.tracing? && !TraceView.tracing_layer_op?(:get)
|
|
117
|
+
report_kvs = extract_trace_details(:multi_get, column_family, key, columns_and_options)
|
|
118
|
+
|
|
119
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
120
|
+
send :multi_get_without_traceview, *args
|
|
121
|
+
end
|
|
122
|
+
else
|
|
123
|
+
send :multi_get_without_traceview, *args
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def exists_with_traceview?(column_family, key, *columns_and_options)
|
|
128
|
+
return send :exists_without_traceview?, *args unless TraceView.tracing?
|
|
129
|
+
|
|
130
|
+
args = [column_family, key] + columns_and_options
|
|
131
|
+
report_kvs = extract_trace_details(:exists?, column_family, key, columns_and_options)
|
|
132
|
+
|
|
133
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
134
|
+
send :exists_without_traceview?, *args
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def get_range_single_with_traceview(column_family, options = {})
|
|
139
|
+
if TraceView.tracing? && !TraceView.tracing_layer_op?(:get_range_batch)
|
|
140
|
+
report_kvs = extract_trace_details(:get_range_single, column_family, nil, nil)
|
|
141
|
+
|
|
142
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
143
|
+
get_range_single_without_traceview(column_family, options)
|
|
144
|
+
end
|
|
145
|
+
else
|
|
146
|
+
get_range_single_without_traceview(column_family, options)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def get_range_batch_with_traceview(column_family, options = {})
|
|
151
|
+
return get_range_batch_without_traceview(column_family, options) unless TraceView.tracing?
|
|
152
|
+
|
|
153
|
+
report_kvs = extract_trace_details(:get_range_batch, column_family, nil, nil)
|
|
154
|
+
|
|
155
|
+
TraceView::API.trace('cassandra', report_kvs, :get_range_batch) do
|
|
156
|
+
get_range_batch_without_traceview(column_family, options)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def get_indexed_slices_with_traceview(column_family, index_clause, *columns_and_options)
|
|
161
|
+
return send :get_indexed_slices_without_traceview, *args unless TraceView.tracing?
|
|
162
|
+
|
|
163
|
+
args = [column_family, index_clause] + columns_and_options
|
|
164
|
+
report_kvs = extract_trace_details(:get_indexed_slices, column_family, nil, columns_and_options)
|
|
165
|
+
|
|
166
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
167
|
+
send :get_indexed_slices_without_traceview, *args
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def create_index_with_traceview(keyspace, column_family, column_name, validation_class)
|
|
172
|
+
unless TraceView.tracing?
|
|
173
|
+
return create_index_without_traceview(keyspace, column_family, column_name, validation_class)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
report_kvs = extract_trace_details(:create_index, column_family, nil, nil)
|
|
177
|
+
begin
|
|
178
|
+
report_kvs[:Keyspace] = keyspace.to_s
|
|
179
|
+
report_kvs[:Column_name] = column_name.to_s
|
|
180
|
+
report_kvs[:Validation_class] = validation_class.to_s
|
|
181
|
+
rescue
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
185
|
+
create_index_without_traceview(keyspace, column_family, column_name, validation_class)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def drop_index_with_traceview(keyspace, column_family, column_name)
|
|
190
|
+
return drop_index_without_traceview(keyspace, column_family, column_name) unless TraceView.tracing?
|
|
191
|
+
|
|
192
|
+
report_kvs = extract_trace_details(:drop_index, column_family, nil, nil)
|
|
193
|
+
begin
|
|
194
|
+
report_kvs[:Keyspace] = keyspace.to_s
|
|
195
|
+
report_kvs[:Column_name] = column_name.to_s
|
|
196
|
+
rescue
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
200
|
+
drop_index_without_traceview(keyspace, column_family, column_name)
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def add_column_family_with_traceview(cf_def)
|
|
205
|
+
return add_column_family_without_traceview(cf_def) unless TraceView.tracing?
|
|
206
|
+
|
|
207
|
+
report_kvs = extract_trace_details(:add_column_family, nil, nil, nil)
|
|
208
|
+
begin
|
|
209
|
+
report_kvs[:Cf] = cf_def[:name] if cf_def.is_a?(Hash) && cf_def.key?(:name)
|
|
210
|
+
rescue
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
214
|
+
add_column_family_without_traceview(cf_def)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def drop_column_family_with_traceview(column_family)
|
|
219
|
+
return drop_column_family_without_traceview(column_family) unless TraceView.tracing?
|
|
220
|
+
|
|
221
|
+
report_kvs = extract_trace_details(:drop_column_family, column_family, nil, nil)
|
|
222
|
+
|
|
223
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
224
|
+
drop_column_family_without_traceview(column_family)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def add_keyspace_with_traceview(ks_def)
|
|
229
|
+
return add_keyspace_without_traceview(ks_def) unless TraceView.tracing?
|
|
230
|
+
|
|
231
|
+
report_kvs = extract_trace_details(:add_keyspace, nil, nil, nil)
|
|
232
|
+
report_kvs[:Name] = ks_def.name rescue ''
|
|
233
|
+
|
|
234
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
235
|
+
add_keyspace_without_traceview(ks_def)
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def drop_keyspace_with_traceview(keyspace)
|
|
240
|
+
return drop_keyspace_without_traceview(keyspace) unless TraceView.tracing?
|
|
241
|
+
|
|
242
|
+
report_kvs = extract_trace_details(:drop_keyspace, nil, nil, nil)
|
|
243
|
+
report_kvs[:Name] = keyspace.to_s rescue ''
|
|
244
|
+
|
|
245
|
+
TraceView::API.trace('cassandra', report_kvs) do
|
|
246
|
+
drop_keyspace_without_traceview(keyspace)
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
if defined?(::Cassandra) && TraceView::Config[:cassandra][:enabled]
|
|
254
|
+
TraceView.logger.info '[traceview/loading] Instrumenting cassandra' if TraceView::Config[:verbose]
|
|
255
|
+
|
|
256
|
+
class ::Cassandra
|
|
257
|
+
include TraceView::Inst::Cassandra
|
|
258
|
+
|
|
259
|
+
[:insert, :remove, :count_columns, :get_columns, :multi_get_columns, :get,
|
|
260
|
+
:multi_get, :get_range_single, :get_range_batch, :get_indexed_slices,
|
|
261
|
+
:create_index, :drop_index, :add_column_family, :drop_column_family,
|
|
262
|
+
:add_keyspace, :drop_keyspace].each do |m|
|
|
263
|
+
if method_defined?(m)
|
|
264
|
+
class_eval "alias #{m}_without_traceview #{m}"
|
|
265
|
+
class_eval "alias #{m} #{m}_with_traceview"
|
|
266
|
+
else TraceView.logger.warn "[traceview/loading] Couldn't properly instrument Cassandra (#{m}). Partial traces may occur."
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Special case handler for question mark methods
|
|
271
|
+
if method_defined?(:exists?)
|
|
272
|
+
alias exists_without_traceview? exists?
|
|
273
|
+
alias exists? exists_with_traceview?
|
|
274
|
+
else TraceView.logger.warn '[traceview/loading] Couldn\'t properly instrument Cassandra (exists?). Partial traces may occur.'
|
|
275
|
+
end
|
|
276
|
+
end # class Cassandra
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
|