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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +51 -0
- data/Appraisals +10 -0
- data/CHANGELOG.md +223 -0
- data/Gemfile +49 -0
- data/LICENSE +199 -0
- data/README.md +380 -0
- data/Rakefile +106 -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/base.rb +99 -0
- data/lib/joboe_metal.rb +185 -0
- data/lib/method_profiling.rb +70 -0
- data/lib/oboe.rb +50 -0
- data/lib/oboe/api.rb +14 -0
- data/lib/oboe/api/layerinit.rb +99 -0
- data/lib/oboe/api/logging.rb +129 -0
- data/lib/oboe/api/memcache.rb +29 -0
- data/lib/oboe/api/profiling.rb +50 -0
- data/lib/oboe/api/tracing.rb +134 -0
- data/lib/oboe/api/util.rb +117 -0
- data/lib/oboe/config.rb +140 -0
- data/lib/oboe/frameworks/grape.rb +74 -0
- data/lib/oboe/frameworks/padrino.rb +66 -0
- data/lib/oboe/frameworks/padrino/templates.rb +59 -0
- data/lib/oboe/frameworks/rails.rb +139 -0
- data/lib/oboe/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
- data/lib/oboe/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
- data/lib/oboe/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
- data/lib/oboe/frameworks/rails/inst/action_controller.rb +123 -0
- data/lib/oboe/frameworks/rails/inst/action_view.rb +56 -0
- data/lib/oboe/frameworks/rails/inst/action_view_2x.rb +54 -0
- data/lib/oboe/frameworks/rails/inst/action_view_30.rb +48 -0
- data/lib/oboe/frameworks/rails/inst/active_record.rb +24 -0
- data/lib/oboe/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/oboe/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
- data/lib/oboe/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
- data/lib/oboe/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
- data/lib/oboe/frameworks/rails/inst/connection_adapters/utils.rb +118 -0
- data/lib/oboe/frameworks/sinatra.rb +96 -0
- data/lib/oboe/frameworks/sinatra/templates.rb +56 -0
- data/lib/oboe/inst/cassandra.rb +281 -0
- data/lib/oboe/inst/dalli.rb +75 -0
- data/lib/oboe/inst/http.rb +72 -0
- data/lib/oboe/inst/memcache.rb +105 -0
- data/lib/oboe/inst/memcached.rb +96 -0
- data/lib/oboe/inst/mongo.rb +240 -0
- data/lib/oboe/inst/moped.rb +474 -0
- data/lib/oboe/inst/rack.rb +81 -0
- data/lib/oboe/inst/redis.rb +273 -0
- data/lib/oboe/inst/resque.rb +193 -0
- data/lib/oboe/instrumentation.rb +18 -0
- data/lib/oboe/loading.rb +98 -0
- data/lib/oboe/logger.rb +41 -0
- data/lib/oboe/ruby.rb +11 -0
- data/lib/oboe/util.rb +129 -0
- data/lib/oboe/version.rb +13 -0
- data/lib/oboe/xtrace.rb +52 -0
- data/lib/oboe_metal.rb +140 -0
- data/lib/rails/generators/oboe/install_generator.rb +76 -0
- data/lib/rails/generators/oboe/templates/oboe_initializer.rb +94 -0
- data/oboe.gemspec +29 -0
- data/release.sh +65 -0
- data/test/frameworks/apps/grape_simple.rb +10 -0
- data/test/frameworks/apps/padrino_simple.rb +41 -0
- data/test/frameworks/apps/sinatra_simple.rb +20 -0
- data/test/frameworks/grape_test.rb +27 -0
- data/test/frameworks/padrino_test.rb +25 -0
- data/test/frameworks/sinatra_test.rb +25 -0
- data/test/instrumentation/cassandra_test.rb +381 -0
- data/test/instrumentation/dalli_test.rb +164 -0
- data/test/instrumentation/http_test.rb +97 -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 +473 -0
- data/test/instrumentation/rack_test.rb +73 -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/minitest_helper.rb +148 -0
- data/test/profiling/method_test.rb +198 -0
- data/test/support/config_test.rb +39 -0
- data/test/support/liboboe_settings_test.rb +46 -0
- data/test/support/xtrace_test.rb +35 -0
- metadata +200 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module Oboe
|
|
5
|
+
module Inst
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module FlavorInitializers
|
|
8
|
+
def self.mysql
|
|
9
|
+
Oboe.logger.info "[oboe/loading] Instrumenting activerecord mysqladapter" if Oboe::Config[:verbose]
|
|
10
|
+
|
|
11
|
+
# ActiveRecord 3.2 and higher
|
|
12
|
+
if (::ActiveRecord::VERSION::MAJOR == 3 and ::ActiveRecord::VERSION::MINOR >= 2) or
|
|
13
|
+
::ActiveRecord::VERSION::MAJOR == 4
|
|
14
|
+
|
|
15
|
+
# AbstractMysqlAdapter
|
|
16
|
+
Oboe::Util.send_include(::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter,
|
|
17
|
+
Oboe::Inst::ConnectionAdapters::Utils)
|
|
18
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, :execute)
|
|
19
|
+
|
|
20
|
+
# MysqlAdapter
|
|
21
|
+
Oboe::Util.send_include(::ActiveRecord::ConnectionAdapters::MysqlAdapter,
|
|
22
|
+
Oboe::Inst::ConnectionAdapters::Utils)
|
|
23
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::MysqlAdapter, :exec_query)
|
|
24
|
+
|
|
25
|
+
else
|
|
26
|
+
# ActiveRecord 3.1 and below
|
|
27
|
+
|
|
28
|
+
# MysqlAdapter
|
|
29
|
+
Oboe::Util.send_include(::ActiveRecord::ConnectionAdapters::MysqlAdapter,
|
|
30
|
+
Oboe::Inst::ConnectionAdapters::Utils)
|
|
31
|
+
|
|
32
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::MysqlAdapter, :execute)
|
|
33
|
+
|
|
34
|
+
if ::ActiveRecord::VERSION::MAJOR == 3 and ::ActiveRecord::VERSION::MINOR == 1
|
|
35
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::MysqlAdapter, :begin_db_transaction)
|
|
36
|
+
Oboe::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 Oboe
|
|
5
|
+
module Inst
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module FlavorInitializers
|
|
8
|
+
def self.mysql2
|
|
9
|
+
Oboe.logger.info "[oboe/loading] Instrumenting activerecord mysql2adapter" if Oboe::Config[:verbose]
|
|
10
|
+
|
|
11
|
+
Oboe::Util.send_include(::ActiveRecord::ConnectionAdapters::Mysql2Adapter,
|
|
12
|
+
Oboe::Inst::ConnectionAdapters::Utils)
|
|
13
|
+
|
|
14
|
+
if (::ActiveRecord::VERSION::MAJOR == 3 and ::ActiveRecord::VERSION::MINOR == 0) or
|
|
15
|
+
::ActiveRecord::VERSION::MAJOR == 2
|
|
16
|
+
# ActiveRecord 3.0 and prior
|
|
17
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :execute)
|
|
18
|
+
else
|
|
19
|
+
# ActiveRecord 3.1 and above
|
|
20
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_insert)
|
|
21
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_query)
|
|
22
|
+
Oboe::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 Oboe
|
|
5
|
+
module Inst
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module FlavorInitializers
|
|
8
|
+
def self.oracle
|
|
9
|
+
Oboe.logger.info "[oboe/loading] Instrumenting activerecord oracleenhancedadapter" if Oboe::Config[:verbose]
|
|
10
|
+
::ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.module_eval do
|
|
11
|
+
include Oboe::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 Oboe
|
|
5
|
+
module Inst
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module FlavorInitializers
|
|
8
|
+
def self.postgresql
|
|
9
|
+
|
|
10
|
+
Oboe.logger.info "[oboe/loading] Instrumenting activerecord postgresqladapter" if Oboe::Config[:verbose]
|
|
11
|
+
|
|
12
|
+
Oboe::Util.send_include(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter,
|
|
13
|
+
Oboe::Inst::ConnectionAdapters::Utils)
|
|
14
|
+
|
|
15
|
+
if (::ActiveRecord::VERSION::MAJOR == 3 and ::ActiveRecord::VERSION::MINOR > 0) or
|
|
16
|
+
::ActiveRecord::VERSION::MAJOR == 4
|
|
17
|
+
|
|
18
|
+
# ActiveRecord 3.1 and up
|
|
19
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_query)
|
|
20
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_delete)
|
|
21
|
+
|
|
22
|
+
else
|
|
23
|
+
# ActiveRecord 3.0 and prior
|
|
24
|
+
Oboe::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :execute)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module Oboe
|
|
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 Oboe::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] = Oboe::API.backtrace if Oboe::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.has_key?("database")
|
|
32
|
+
opts[:RemoteHost] = config["host"] if config.has_key?("host")
|
|
33
|
+
opts[:Flavor] = config["adapter"] if config.has_key?("adapter")
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
Oboe.logger.debug "Exception raised capturing ActiveRecord KVs: #{e.inspect}"
|
|
36
|
+
Oboe.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 or
|
|
46
|
+
(name and name.to_sym == :skip_logging) or
|
|
47
|
+
name == "ActiveRecord::SchemaMigration Load"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
#def cfg
|
|
51
|
+
# @config
|
|
52
|
+
#end
|
|
53
|
+
|
|
54
|
+
def execute_with_oboe(sql, name = nil)
|
|
55
|
+
if Oboe.tracing? and !ignore_payload?(name)
|
|
56
|
+
|
|
57
|
+
opts = extract_trace_details(sql, name)
|
|
58
|
+
Oboe::API.trace('activerecord', opts || {}) do
|
|
59
|
+
execute_without_oboe(sql, name)
|
|
60
|
+
end
|
|
61
|
+
else
|
|
62
|
+
execute_without_oboe(sql, name)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def exec_query_with_oboe(sql, name = nil, binds = [])
|
|
67
|
+
if Oboe.tracing? and !ignore_payload?(name)
|
|
68
|
+
|
|
69
|
+
opts = extract_trace_details(sql, name, binds)
|
|
70
|
+
Oboe::API.trace('activerecord', opts || {}) do
|
|
71
|
+
exec_query_without_oboe(sql, name, binds)
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
exec_query_without_oboe(sql, name, binds)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def exec_delete_with_oboe(sql, name = nil, binds = [])
|
|
79
|
+
if Oboe.tracing? and !ignore_payload?(name)
|
|
80
|
+
|
|
81
|
+
opts = extract_trace_details(sql, name, binds)
|
|
82
|
+
Oboe::API.trace('activerecord', opts || {}) do
|
|
83
|
+
exec_delete_without_oboe(sql, name, binds)
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
exec_delete_without_oboe(sql, name, binds)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def exec_insert_with_oboe(sql, name = nil, binds = [], *args)
|
|
91
|
+
if Oboe.tracing? and !ignore_payload?(name)
|
|
92
|
+
|
|
93
|
+
opts = extract_trace_details(sql, name, binds)
|
|
94
|
+
Oboe::API.trace('activerecord', opts || {}) do
|
|
95
|
+
exec_insert_without_oboe(sql, name, binds, *args)
|
|
96
|
+
end
|
|
97
|
+
else
|
|
98
|
+
exec_insert_without_oboe(sql, name, binds, *args)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def begin_db_transaction_with_oboe()
|
|
103
|
+
if Oboe.tracing?
|
|
104
|
+
opts = {}
|
|
105
|
+
|
|
106
|
+
opts[:Query] = "BEGIN"
|
|
107
|
+
Oboe::API.trace('activerecord', opts || {}) do
|
|
108
|
+
begin_db_transaction_without_oboe()
|
|
109
|
+
end
|
|
110
|
+
else
|
|
111
|
+
begin_db_transaction_without_oboe()
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end # Utils
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module Oboe
|
|
5
|
+
module Sinatra
|
|
6
|
+
module Base
|
|
7
|
+
def self.included(klass)
|
|
8
|
+
::Oboe::Util.method_alias(klass, :dispatch!, ::Sinatra::Base)
|
|
9
|
+
::Oboe::Util.method_alias(klass, :handle_exception!, ::Sinatra::Base)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dispatch_with_oboe
|
|
13
|
+
if Oboe.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 Oboe::API.trace
|
|
21
|
+
# block method) This removes the need for an info
|
|
22
|
+
# event to send additonal KVs
|
|
23
|
+
::Oboe::API.log_entry('sinatra', {})
|
|
24
|
+
|
|
25
|
+
begin
|
|
26
|
+
dispatch_without_oboe
|
|
27
|
+
ensure
|
|
28
|
+
::Oboe::API.log_exit('sinatra', report_kvs)
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
dispatch_without_oboe
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def handle_exception_with_oboe(boom)
|
|
36
|
+
Oboe::API.log_exception(nil, boom) if Oboe.tracing?
|
|
37
|
+
handle_exception_without_oboe(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 oboe_rum_header
|
|
45
|
+
return unless Oboe::Config.rum_id
|
|
46
|
+
if Oboe.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
|
+
Oboe.logger.warn "oboe_rum_header: #{e.message}."
|
|
55
|
+
return ""
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def oboe_rum_footer
|
|
59
|
+
return unless Oboe::Config.rum_id
|
|
60
|
+
if Oboe.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
|
+
Oboe.logger.warn "oboe_rum_footer: #{e.message}."
|
|
67
|
+
return ""
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if defined?(::Sinatra)
|
|
74
|
+
require 'oboe/inst/rack'
|
|
75
|
+
require 'oboe/frameworks/sinatra/templates'
|
|
76
|
+
|
|
77
|
+
Oboe.logger.info "[oboe/loading] Instrumenting Sinatra" if Oboe::Config[:verbose]
|
|
78
|
+
|
|
79
|
+
Oboe::Loading.load_access_key
|
|
80
|
+
Oboe::Inst.load_instrumentation
|
|
81
|
+
|
|
82
|
+
::Sinatra::Base.use Oboe::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.has_key?("OBOE_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
|
+
::Oboe::Util.send_include(::Sinatra::Base, ::Oboe::Sinatra::Base)
|
|
90
|
+
::Oboe::Util.send_include(::Sinatra::Templates, ::Oboe::Sinatra::Templates)
|
|
91
|
+
|
|
92
|
+
# Report __Init after fork when in Heroku
|
|
93
|
+
Oboe::API.report_init unless Oboe.heroku?
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module Oboe
|
|
5
|
+
module Sinatra
|
|
6
|
+
module Templates
|
|
7
|
+
def self.included(klass)
|
|
8
|
+
::Oboe::Util.method_alias(klass, :render, ::Sinatra::Templates)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def render_with_oboe(engine, data, options = {}, locals = {}, &block)
|
|
12
|
+
if Oboe.tracing?
|
|
13
|
+
report_kvs = {}
|
|
14
|
+
|
|
15
|
+
report_kvs[:engine] = engine
|
|
16
|
+
report_kvs[:template] = data
|
|
17
|
+
|
|
18
|
+
if Oboe.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
|
+
::Oboe.logger.debug e.message
|
|
30
|
+
::Oboe.logger.debug e.backtrace.join(", ")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Oboe::API.profile(name, report_kvs, false) do
|
|
34
|
+
render_without_oboe(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 Oboe::API.trace
|
|
40
|
+
# block method) This removes the need for an info
|
|
41
|
+
# event to send additonal KVs
|
|
42
|
+
::Oboe::API.log_entry('render', {}, 'render')
|
|
43
|
+
|
|
44
|
+
begin
|
|
45
|
+
render_without_oboe(engine, data, options, locals, &block)
|
|
46
|
+
ensure
|
|
47
|
+
::Oboe::API.log_exit('render', report_kvs)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
render_without_oboe(engine, data, options, locals, &block)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module Oboe
|
|
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] = Oboe::API.backtrace if Oboe::Config[:cassandra][:collect_backtraces]
|
|
19
|
+
|
|
20
|
+
if options.empty? and 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.has_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.has_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_oboe(column_family, key, hash, options = {})
|
|
46
|
+
return insert_without_oboe(column_family, key, hash, options = {}) unless Oboe.tracing?
|
|
47
|
+
|
|
48
|
+
report_kvs = extract_trace_details(:insert, column_family, key, hash, options)
|
|
49
|
+
|
|
50
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
51
|
+
insert_without_oboe(column_family, key, hash, options = {})
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def remove_with_oboe(column_family, key, *columns_and_options)
|
|
56
|
+
return send :remove_without_oboe, *args unless Oboe.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
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
62
|
+
send :remove_without_oboe, *args
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def count_columns_with_oboe(column_family, key, *columns_and_options)
|
|
67
|
+
return send :count_columns_without_oboe, *args unless Oboe.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
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
73
|
+
send :count_columns_without_oboe, *args
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def get_columns_with_oboe(column_family, key, *columns_and_options)
|
|
78
|
+
args = [column_family, key] + columns_and_options
|
|
79
|
+
|
|
80
|
+
if Oboe.tracing? and not Oboe.tracing_layer_op?(:multi_get_columns)
|
|
81
|
+
report_kvs = extract_trace_details(:get_columns, column_family, key, columns_and_options)
|
|
82
|
+
|
|
83
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
84
|
+
send :get_columns_without_oboe, *args
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
send :get_columns_without_oboe, *args
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def multi_get_columns_with_oboe(column_family, key, *columns_and_options)
|
|
92
|
+
return send :multi_get_columns_without_oboe, *args unless Oboe.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
|
+
Oboe::API.trace('cassandra', report_kvs, :multi_get_columns) do
|
|
98
|
+
send :multi_get_columns_without_oboe, *args
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def get_with_oboe(column_family, key, *columns_and_options)
|
|
103
|
+
return send :get_without_oboe, *args unless Oboe.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
|
+
Oboe::API.trace('cassandra', report_kvs, :get) do
|
|
109
|
+
send :get_without_oboe, *args
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def multi_get_with_oboe(column_family, key, *columns_and_options)
|
|
114
|
+
args = [column_family, key] + columns_and_options
|
|
115
|
+
|
|
116
|
+
if Oboe.tracing? and not Oboe.tracing_layer_op?(:get)
|
|
117
|
+
report_kvs = extract_trace_details(:multi_get, column_family, key, columns_and_options)
|
|
118
|
+
|
|
119
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
120
|
+
send :multi_get_without_oboe, *args
|
|
121
|
+
end
|
|
122
|
+
else
|
|
123
|
+
send :multi_get_without_oboe, *args
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def exists_with_oboe?(column_family, key, *columns_and_options)
|
|
128
|
+
return send :exists_without_oboe?, *args unless Oboe.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
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
134
|
+
send :exists_without_oboe?, *args
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def get_range_single_with_oboe(column_family, options = {})
|
|
139
|
+
if Oboe.tracing? and not Oboe.tracing_layer_op?(:get_range_batch)
|
|
140
|
+
report_kvs = extract_trace_details(:get_range_single, column_family, nil, nil)
|
|
141
|
+
args = [column_family, options]
|
|
142
|
+
|
|
143
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
144
|
+
get_range_single_without_oboe(column_family, options)
|
|
145
|
+
end
|
|
146
|
+
else
|
|
147
|
+
get_range_single_without_oboe(column_family, options)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def get_range_batch_with_oboe(column_family, options = {})
|
|
152
|
+
return get_range_batch_without_oboe(column_family, options) unless Oboe.tracing?
|
|
153
|
+
|
|
154
|
+
report_kvs = extract_trace_details(:get_range_batch, column_family, nil, nil)
|
|
155
|
+
args = [column_family, options]
|
|
156
|
+
|
|
157
|
+
Oboe::API.trace('cassandra', report_kvs, :get_range_batch) do
|
|
158
|
+
get_range_batch_without_oboe(column_family, options)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def get_indexed_slices_with_oboe(column_family, index_clause, *columns_and_options)
|
|
163
|
+
return send :get_indexed_slices_without_oboe, *args unless Oboe.tracing?
|
|
164
|
+
|
|
165
|
+
args = [column_family, index_clause] + columns_and_options
|
|
166
|
+
report_kvs = extract_trace_details(:get_indexed_slices, column_family, nil, columns_and_options)
|
|
167
|
+
|
|
168
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
169
|
+
send :get_indexed_slices_without_oboe, *args
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def create_index_with_oboe(keyspace, column_family, column_name, validation_class)
|
|
174
|
+
unless Oboe.tracing?
|
|
175
|
+
return create_index_without_oboe(keyspace, column_family, column_name, validation_class)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
report_kvs = extract_trace_details(:create_index, column_family, nil, nil)
|
|
179
|
+
begin
|
|
180
|
+
report_kvs[:Keyspace] = keyspace.to_s
|
|
181
|
+
report_kvs[:Column_name] = column_name.to_s
|
|
182
|
+
report_kvs[:Validation_class] = validation_class.to_s
|
|
183
|
+
rescue
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
187
|
+
create_index_without_oboe(keyspace, column_family, column_name, validation_class)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def drop_index_with_oboe(keyspace, column_family, column_name)
|
|
192
|
+
return drop_index_without_oboe(keyspace, column_family, column_name) unless Oboe.tracing?
|
|
193
|
+
|
|
194
|
+
report_kvs = extract_trace_details(:drop_index, column_family, nil, nil)
|
|
195
|
+
begin
|
|
196
|
+
report_kvs[:Keyspace] = keyspace.to_s
|
|
197
|
+
report_kvs[:Column_name] = column_name.to_s
|
|
198
|
+
rescue
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
202
|
+
drop_index_without_oboe(keyspace, column_family, column_name)
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def add_column_family_with_oboe(cf_def)
|
|
207
|
+
return add_column_family_without_oboe(cf_def) unless Oboe.tracing?
|
|
208
|
+
|
|
209
|
+
report_kvs = extract_trace_details(:add_column_family, nil, nil, nil)
|
|
210
|
+
begin
|
|
211
|
+
report_kvs[:Cf] = cf_def[:name] if cf_def.is_a?(Hash) and cf_def.has_key?(:name)
|
|
212
|
+
rescue
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
216
|
+
add_column_family_without_oboe(cf_def)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def drop_column_family_with_oboe(column_family)
|
|
221
|
+
return drop_column_family_without_oboe(column_family) unless Oboe.tracing?
|
|
222
|
+
|
|
223
|
+
report_kvs = extract_trace_details(:drop_column_family, column_family, nil, nil)
|
|
224
|
+
|
|
225
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
226
|
+
drop_column_family_without_oboe(column_family)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def add_keyspace_with_oboe(ks_def)
|
|
231
|
+
return add_keyspace_without_oboe(ks_def) unless Oboe.tracing?
|
|
232
|
+
|
|
233
|
+
report_kvs = extract_trace_details(:add_keyspace, nil, nil, nil)
|
|
234
|
+
report_kvs[:Name] = ks_def.name rescue ""
|
|
235
|
+
|
|
236
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
237
|
+
add_keyspace_without_oboe(ks_def)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def drop_keyspace_with_oboe(keyspace)
|
|
242
|
+
return drop_keyspace_without_oboe(keyspace) unless Oboe.tracing?
|
|
243
|
+
|
|
244
|
+
report_kvs = extract_trace_details(:drop_keyspace, nil, nil, nil)
|
|
245
|
+
report_kvs[:Name] = keyspace.to_s rescue ""
|
|
246
|
+
|
|
247
|
+
Oboe::API.trace('cassandra', report_kvs) do
|
|
248
|
+
drop_keyspace_without_oboe(keyspace)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
if defined?(::Cassandra) and Oboe::Config[:cassandra][:enabled]
|
|
256
|
+
Oboe.logger.info "[oboe/loading] Instrumenting cassandra" if Oboe::Config[:verbose]
|
|
257
|
+
|
|
258
|
+
class ::Cassandra
|
|
259
|
+
include Oboe::Inst::Cassandra
|
|
260
|
+
|
|
261
|
+
[ :insert, :remove, :count_columns, :get_columns, :multi_get_columns, :get,
|
|
262
|
+
:multi_get, :get_range_single, :get_range_batch, :get_indexed_slices,
|
|
263
|
+
:create_index, :drop_index, :add_column_family, :drop_column_family,
|
|
264
|
+
:add_keyspace, :drop_keyspace].each do |m|
|
|
265
|
+
if method_defined?(m)
|
|
266
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
|
267
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
|
268
|
+
else Oboe.logger.warn "[oboe/loading] Couldn't properly instrument Cassandra (#{m}). Partial traces may occur."
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# Special case handler for question mark methods
|
|
273
|
+
if method_defined?(:exists?)
|
|
274
|
+
alias exists_without_oboe? exists?
|
|
275
|
+
alias exists? exists_with_oboe?
|
|
276
|
+
else Oboe.logger.warn "[oboe/loading] Couldn't properly instrument Cassandra (exists?). Partial traces may occur."
|
|
277
|
+
end
|
|
278
|
+
end # class Cassandra
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
|