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,75 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module Oboe
|
|
5
|
+
module Inst
|
|
6
|
+
module Dalli
|
|
7
|
+
include Oboe::API::Memcache
|
|
8
|
+
|
|
9
|
+
def self.included(cls)
|
|
10
|
+
cls.class_eval do
|
|
11
|
+
Oboe.logger.info "[oboe/loading] Instrumenting memcache (dalli)" if Oboe::Config[:verbose]
|
|
12
|
+
if ::Dalli::Client.private_method_defined? :perform
|
|
13
|
+
alias perform_without_oboe perform
|
|
14
|
+
alias perform perform_with_oboe
|
|
15
|
+
else Oboe.logger.warn "[oboe/loading] Couldn't properly instrument Memcache (Dalli). Partial traces may occur."
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if ::Dalli::Client.method_defined? :get_multi
|
|
19
|
+
alias get_multi_without_oboe get_multi
|
|
20
|
+
alias get_multi get_multi_with_oboe
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def perform_with_oboe(*all_args, &blk)
|
|
26
|
+
op, key, *args = *all_args
|
|
27
|
+
|
|
28
|
+
if Oboe.tracing? and not Oboe.tracing_layer_op?(:get_multi)
|
|
29
|
+
Oboe::API.trace('memcache', { :KVOp => op, :KVKey => key }) do
|
|
30
|
+
result = perform_without_oboe(*all_args, &blk)
|
|
31
|
+
|
|
32
|
+
info_kvs = {}
|
|
33
|
+
info_kvs[:KVHit] = memcache_hit?(result) if op == :get and key.class == String
|
|
34
|
+
info_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:dalli][:collect_backtraces]
|
|
35
|
+
|
|
36
|
+
Oboe::API.log('memcache', 'info', info_kvs) unless info_kvs.empty?
|
|
37
|
+
result
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
perform_without_oboe(*all_args, &blk)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def get_multi_with_oboe(*keys)
|
|
45
|
+
return get_multi_without_oboe(keys) unless Oboe.tracing?
|
|
46
|
+
|
|
47
|
+
info_kvs = {}
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
info_kvs[:KVKeyCount] = keys.flatten.length
|
|
51
|
+
info_kvs[:KVKeyCount] = (info_kvs[:KVKeyCount] - 1) if keys.last.is_a?(Hash) || keys.last.nil?
|
|
52
|
+
rescue
|
|
53
|
+
Oboe.logger.debug "[oboe/debug] Error collecting info keys: #{e.message}"
|
|
54
|
+
Oboe.logger.debug e.backtrace
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
Oboe::API.trace('memcache', { :KVOp => :get_multi }, :get_multi) do
|
|
58
|
+
values = get_multi_without_oboe(keys)
|
|
59
|
+
|
|
60
|
+
info_kvs[:KVHitCount] = values.length
|
|
61
|
+
info_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:dalli][:collect_backtraces]
|
|
62
|
+
Oboe::API.log('memcache', 'info', info_kvs)
|
|
63
|
+
|
|
64
|
+
values
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if defined?(Dalli) and Oboe::Config[:dalli][:enabled]
|
|
72
|
+
::Dalli::Client.module_eval do
|
|
73
|
+
include Oboe::Inst::Dalli
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require 'net/http'
|
|
5
|
+
|
|
6
|
+
if Oboe::Config[:nethttp][:enabled]
|
|
7
|
+
|
|
8
|
+
Net::HTTP.class_eval do
|
|
9
|
+
def request_with_oboe(*args, &block)
|
|
10
|
+
unless started?
|
|
11
|
+
return request_without_oboe(*args, &block)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Avoid cross host tracing for blacklisted domains
|
|
15
|
+
blacklisted = Oboe::API.blacklisted?(addr_port)
|
|
16
|
+
|
|
17
|
+
Oboe::API.trace('net-http') do
|
|
18
|
+
opts = {}
|
|
19
|
+
context = Oboe::Context.toString()
|
|
20
|
+
task_id = Oboe::XTrace.task_id(context)
|
|
21
|
+
|
|
22
|
+
# Collect KVs to report in the info event
|
|
23
|
+
if args.length and args[0]
|
|
24
|
+
req = args[0]
|
|
25
|
+
|
|
26
|
+
opts['IsService'] = 1
|
|
27
|
+
opts['RemoteProtocol'] = use_ssl? ? 'HTTPS' : 'HTTP'
|
|
28
|
+
opts['RemoteHost'] = addr_port
|
|
29
|
+
opts['ServiceArg'] = req.path
|
|
30
|
+
opts['HTTPMethod'] = req.method
|
|
31
|
+
opts['Blacklisted'] = true if blacklisted
|
|
32
|
+
opts['Backtrace'] = Oboe::API.backtrace if Oboe::Config[:nethttp][:collect_backtraces]
|
|
33
|
+
|
|
34
|
+
req['X-Trace'] = context unless blacklisted
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
begin
|
|
38
|
+
# The actual net::http call
|
|
39
|
+
resp = request_without_oboe(*args, &block)
|
|
40
|
+
|
|
41
|
+
# Re-attach net::http edge unless blacklisted and is a valid X-Trace ID
|
|
42
|
+
unless blacklisted
|
|
43
|
+
xtrace = resp.get_fields('X-Trace')
|
|
44
|
+
xtrace = xtrace[0] if xtrace and xtrace.is_a?(Array)
|
|
45
|
+
|
|
46
|
+
if Oboe::XTrace.valid?(xtrace) and Oboe.tracing?
|
|
47
|
+
|
|
48
|
+
# Assure that we received back a valid X-Trace with the same task_id
|
|
49
|
+
if task_id == Oboe::XTrace.task_id(xtrace)
|
|
50
|
+
Oboe::Context.fromString(xtrace)
|
|
51
|
+
else
|
|
52
|
+
Oboe.logger.debug "Mismatched returned X-Trace ID : #{xtrace}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
opts['HTTPStatus'] = resp.code
|
|
58
|
+
|
|
59
|
+
next resp
|
|
60
|
+
ensure
|
|
61
|
+
# Log the info event with the KVs in opts
|
|
62
|
+
Oboe::API.log('net-http', 'info', opts)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
alias request_without_oboe request
|
|
68
|
+
alias request request_with_oboe
|
|
69
|
+
|
|
70
|
+
Oboe.logger.info "[oboe/loading] Instrumenting net/http" if Oboe::Config[:verbose]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module Oboe
|
|
5
|
+
module Inst
|
|
6
|
+
module MemCache
|
|
7
|
+
include Oboe::API::Memcache
|
|
8
|
+
|
|
9
|
+
def self.included(cls)
|
|
10
|
+
Oboe.logger.info "[oboe/loading] Instrumenting memcache" if Oboe::Config[:verbose]
|
|
11
|
+
|
|
12
|
+
cls.class_eval do
|
|
13
|
+
MEMCACHE_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
|
14
|
+
|
|
15
|
+
define_method("#{m}_with_oboe") do |*args|
|
|
16
|
+
report_kvs = { :KVOp => m }
|
|
17
|
+
report_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:memcache][:collect_backtraces]
|
|
18
|
+
|
|
19
|
+
if Oboe.tracing?
|
|
20
|
+
Oboe::API.trace('memcache', report_kvs) do
|
|
21
|
+
result = send("#{m}_without_oboe", *args)
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
result = send("#{m}_without_oboe", *args)
|
|
25
|
+
end
|
|
26
|
+
result
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
|
30
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
[:request_setup, :cache_get, :get_multi].each do |m|
|
|
35
|
+
if ::MemCache.method_defined? :request_setup
|
|
36
|
+
cls.class_eval "alias #{m}_without_oboe #{m}"
|
|
37
|
+
cls.class_eval "alias #{m} #{m}_with_oboe"
|
|
38
|
+
elsif Oboe::Config[:verbose]
|
|
39
|
+
Oboe.logger.warn "[oboe/loading] Couldn't properly instrument Memcache: #{m}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def get_multi_with_oboe(*args)
|
|
45
|
+
return get_multi_without_oboe(args) unless Oboe.tracing?
|
|
46
|
+
|
|
47
|
+
info_kvs = {}
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
info_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:memcache][:collect_backtraces]
|
|
51
|
+
|
|
52
|
+
if args.last.is_a?(Hash) || args.last.nil?
|
|
53
|
+
info_kvs[:KVKeyCount] = args.flatten.length - 1
|
|
54
|
+
else
|
|
55
|
+
info_kvs[:KVKeyCount] = args.flatten.length
|
|
56
|
+
end
|
|
57
|
+
rescue StandardError => e
|
|
58
|
+
Oboe.logger.debug "[oboe/debug] Error collecting info keys: #{e.message}"
|
|
59
|
+
Oboe.logger.debug e.backtrace
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
Oboe::API.trace('memcache', {:KVOp => :get_multi}, :get_multi) do
|
|
63
|
+
values = get_multi_without_oboe(args)
|
|
64
|
+
|
|
65
|
+
info_kvs[:KVHitCount] = values.length
|
|
66
|
+
Oboe::API.log('memcache', 'info', info_kvs)
|
|
67
|
+
|
|
68
|
+
values
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def request_setup_with_oboe(*args)
|
|
73
|
+
if Oboe.tracing? and not Oboe.tracing_layer_op?(:get_multi)
|
|
74
|
+
server, cache_key = request_setup_without_oboe(*args)
|
|
75
|
+
|
|
76
|
+
info_kvs = { :KVKey => cache_key, :RemoteHost => server.host }
|
|
77
|
+
info_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:memcache][:collect_backtraces]
|
|
78
|
+
Oboe::API.log('memcache', 'info', info_kvs)
|
|
79
|
+
|
|
80
|
+
[server, cache_key]
|
|
81
|
+
else
|
|
82
|
+
request_setup_without_oboe(*args)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def cache_get_with_oboe(server, cache_key)
|
|
87
|
+
result = cache_get_without_oboe(server, cache_key)
|
|
88
|
+
|
|
89
|
+
info_kvs = { :KVHit => memcache_hit?(result) }
|
|
90
|
+
info_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:memcache][:collect_backtraces]
|
|
91
|
+
Oboe::API.log('memcache', 'info', info_kvs)
|
|
92
|
+
|
|
93
|
+
result
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end # module MemCache
|
|
97
|
+
end # module Inst
|
|
98
|
+
end # module Oboe
|
|
99
|
+
|
|
100
|
+
if defined?(::MemCache) and Oboe::Config[:memcache][:enabled]
|
|
101
|
+
::MemCache.class_eval do
|
|
102
|
+
include Oboe::Inst::MemCache
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module Oboe
|
|
5
|
+
module Inst
|
|
6
|
+
module Memcached
|
|
7
|
+
include Oboe::API::Memcache
|
|
8
|
+
|
|
9
|
+
def self.included(cls)
|
|
10
|
+
Oboe.logger.info "[oboe/loading] Instrumenting memcached" if Oboe::Config[:verbose]
|
|
11
|
+
|
|
12
|
+
cls.class_eval do
|
|
13
|
+
MEMCACHE_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
|
14
|
+
define_method("#{m}_with_oboe") do |*args|
|
|
15
|
+
opts = { :KVOp => m }
|
|
16
|
+
|
|
17
|
+
if args.length and args[0].class != Array
|
|
18
|
+
opts[:KVKey] = args[0].to_s
|
|
19
|
+
rhost = remote_host(args[0].to_s)
|
|
20
|
+
opts[:RemoteHost] = rhost if rhost
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Oboe::API.trace('memcache', opts) do
|
|
24
|
+
result = send("#{m}_without_oboe", *args)
|
|
25
|
+
|
|
26
|
+
info_kvs = {}
|
|
27
|
+
info_kvs[:KVHit] = memcache_hit?(result) if m == :get and args.length and args[0].class == String
|
|
28
|
+
info_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:memcached][:collect_backtraces]
|
|
29
|
+
|
|
30
|
+
Oboe::API.log('memcache', 'info', info_kvs) unless info_kvs.empty?
|
|
31
|
+
result
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
|
36
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end # module Memcached
|
|
42
|
+
|
|
43
|
+
module MemcachedRails
|
|
44
|
+
def self.included(cls)
|
|
45
|
+
cls.class_eval do
|
|
46
|
+
if ::Memcached::Rails.method_defined? :get_multi
|
|
47
|
+
alias get_multi_without_oboe get_multi
|
|
48
|
+
alias get_multi get_multi_with_oboe
|
|
49
|
+
elsif Oboe::Config[:verbose]
|
|
50
|
+
Oboe.logger.warn "[oboe/loading] Couldn't properly instrument Memcached. Partial traces may occur."
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def get_multi_with_oboe(keys, raw=false)
|
|
56
|
+
if Oboe.tracing?
|
|
57
|
+
layer_kvs = {}
|
|
58
|
+
layer_kvs[:KVOp] = :get_multi
|
|
59
|
+
|
|
60
|
+
Oboe::API.trace('memcache', layer_kvs || {}, :get_multi) do
|
|
61
|
+
begin
|
|
62
|
+
info_kvs = {}
|
|
63
|
+
info_kvs[:KVKeyCount] = keys.flatten.length
|
|
64
|
+
|
|
65
|
+
values = get_multi_without_oboe(keys, raw)
|
|
66
|
+
|
|
67
|
+
info_kvs[:KVHitCount] = values.length
|
|
68
|
+
info_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:memcached][:collect_backtraces]
|
|
69
|
+
|
|
70
|
+
Oboe::API.log('memcache', 'info', info_kvs)
|
|
71
|
+
rescue
|
|
72
|
+
values = get_multi_without_oboe(keys, raw)
|
|
73
|
+
end
|
|
74
|
+
values
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
get_multi_without_oboe(keys, raw)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end # module MemcachedRails
|
|
82
|
+
end # module Inst
|
|
83
|
+
end # module Oboe
|
|
84
|
+
|
|
85
|
+
if defined?(::Memcached) and Oboe::Config[:memcached][:enabled]
|
|
86
|
+
::Memcached.class_eval do
|
|
87
|
+
include Oboe::Inst::Memcached
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if defined?(::Memcached::Rails)
|
|
91
|
+
::Memcached::Rails.class_eval do
|
|
92
|
+
include Oboe::Inst::MemcachedRails
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Copyright (c) 2013 AppNeta, Inc.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module Oboe
|
|
7
|
+
module Inst
|
|
8
|
+
module Mongo
|
|
9
|
+
FLAVOR = 'mongodb'
|
|
10
|
+
|
|
11
|
+
# Operations for Mongo::DB
|
|
12
|
+
DB_OPS = [ :create_collection, :drop_collection ]
|
|
13
|
+
|
|
14
|
+
# Operations for Mongo::Cursor
|
|
15
|
+
CURSOR_OPS = [ :count ]
|
|
16
|
+
|
|
17
|
+
# Operations for Mongo::Collection
|
|
18
|
+
COLL_WRITE_OPS = [ :find_and_modify, :insert, :map_reduce, :remove, :rename, :update ]
|
|
19
|
+
COLL_QUERY_OPS = [ :distinct, :find, :group ]
|
|
20
|
+
COLL_INDEX_OPS = [ :create_index, :drop_index, :drop_indexes, :ensure_index, :index_information ]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if defined?(::Mongo) and Oboe::Config[:mongo][:enabled]
|
|
26
|
+
Oboe.logger.info "[oboe/loading] Instrumenting mongo" if Oboe::Config[:verbose]
|
|
27
|
+
|
|
28
|
+
if defined?(::Mongo::DB)
|
|
29
|
+
module ::Mongo
|
|
30
|
+
class DB
|
|
31
|
+
include Oboe::Inst::Mongo
|
|
32
|
+
|
|
33
|
+
# Instrument DB operations
|
|
34
|
+
Oboe::Inst::Mongo::DB_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
|
35
|
+
define_method("#{m}_with_oboe") do |*args|
|
|
36
|
+
report_kvs = {}
|
|
37
|
+
|
|
38
|
+
begin
|
|
39
|
+
report_kvs[:Flavor] = Oboe::Inst::Mongo::FLAVOR
|
|
40
|
+
|
|
41
|
+
report_kvs[:Database] = @name
|
|
42
|
+
|
|
43
|
+
# Mongo >= 1.10 uses @client instead of @connection
|
|
44
|
+
# Avoid the nil
|
|
45
|
+
if @connection
|
|
46
|
+
report_kvs[:RemoteHost] = @connection.host
|
|
47
|
+
report_kvs[:RemotePort] = @connection.port
|
|
48
|
+
elsif @client
|
|
49
|
+
report_kvs[:RemoteHost] = @client.host
|
|
50
|
+
report_kvs[:RemotePort] = @client.port
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
report_kvs[:QueryOp] = m
|
|
54
|
+
|
|
55
|
+
report_kvs[:New_Collection_Name] = args[0] if m == :create_collection
|
|
56
|
+
report_kvs[:Collection] = args[0] if m == :drop_collection
|
|
57
|
+
|
|
58
|
+
report_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:mongo][:collect_backtraces]
|
|
59
|
+
rescue
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
Oboe::API.trace('mongo', report_kvs) do
|
|
63
|
+
send("#{m}_without_oboe", *args)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
|
68
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
if defined?(::Mongo::Cursor)
|
|
75
|
+
module ::Mongo
|
|
76
|
+
class Cursor
|
|
77
|
+
include Oboe::Inst::Mongo
|
|
78
|
+
|
|
79
|
+
# Instrument DB cursor operations
|
|
80
|
+
Oboe::Inst::Mongo::CURSOR_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
|
81
|
+
define_method("#{m}_with_oboe") do |*args|
|
|
82
|
+
report_kvs = {}
|
|
83
|
+
|
|
84
|
+
begin
|
|
85
|
+
report_kvs[:Flavor] = Oboe::Inst::Mongo::FLAVOR
|
|
86
|
+
|
|
87
|
+
report_kvs[:Database] = @db.name
|
|
88
|
+
report_kvs[:RemoteHost] = @connection.host
|
|
89
|
+
report_kvs[:RemotePort] = @connection.port
|
|
90
|
+
|
|
91
|
+
report_kvs[:QueryOp] = m
|
|
92
|
+
if m == :count
|
|
93
|
+
unless @selector.empty?
|
|
94
|
+
report_kvs[:Query] = @selector.to_json
|
|
95
|
+
else
|
|
96
|
+
report_kvs[:Query] = 'all'
|
|
97
|
+
end
|
|
98
|
+
report_kvs[:Limit] = @limit if @limit != 0
|
|
99
|
+
end
|
|
100
|
+
rescue
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
Oboe::API.trace('mongo', report_kvs) do
|
|
104
|
+
send("#{m}_without_oboe", *args)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
|
109
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
if defined?(::Mongo::Collection)
|
|
116
|
+
module ::Mongo
|
|
117
|
+
class Collection
|
|
118
|
+
include Oboe::Inst::Mongo
|
|
119
|
+
|
|
120
|
+
def oboe_collect(m, args)
|
|
121
|
+
begin
|
|
122
|
+
report_kvs = {}
|
|
123
|
+
report_kvs[:Flavor] = Oboe::Inst::Mongo::FLAVOR
|
|
124
|
+
|
|
125
|
+
report_kvs[:Database] = @db.name
|
|
126
|
+
report_kvs[:RemoteHost] = @db.connection.host
|
|
127
|
+
report_kvs[:RemotePort] = @db.connection.port
|
|
128
|
+
report_kvs[:Collection] = @name
|
|
129
|
+
|
|
130
|
+
report_kvs[:Backtrace] = Oboe::API.backtrace if Oboe::Config[:mongo][:collect_backtraces]
|
|
131
|
+
|
|
132
|
+
report_kvs[:QueryOp] = m
|
|
133
|
+
report_kvs[:Query] = args[0].to_json if args and not args.empty? and args[0].class == Hash
|
|
134
|
+
rescue StandardError => e
|
|
135
|
+
Oboe.logger.debug "[oboe/debug] Exception in oboe_collect KV collection: #{e.inspect}"
|
|
136
|
+
end
|
|
137
|
+
report_kvs
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Instrument Collection write operations
|
|
141
|
+
Oboe::Inst::Mongo::COLL_WRITE_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
|
142
|
+
define_method("#{m}_with_oboe") do |*args|
|
|
143
|
+
report_kvs = oboe_collect(m, args)
|
|
144
|
+
args_length = args.length
|
|
145
|
+
|
|
146
|
+
begin
|
|
147
|
+
if m == :find_and_modify and args[0] and args[0].has_key?(:update)
|
|
148
|
+
report_kvs[:Update_Document] = args[0][:update].inspect
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
if m == :map_reduce
|
|
152
|
+
report_kvs[:Map_Function] = args[0]
|
|
153
|
+
report_kvs[:Reduce_Function] = args[1]
|
|
154
|
+
report_kvs[:Limit] = args[2][:limit] if args[2] and args[2].has_key?(:limit)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
report_kvs[:New_Collection_Name] = args[0] if m == :rename
|
|
158
|
+
|
|
159
|
+
if m == :update
|
|
160
|
+
if args_length >= 3
|
|
161
|
+
report_kvs[:Update_Document] = args[1].to_json
|
|
162
|
+
report_kvs[:Multi] = args[2][:multi] if args[2] and args[2].has_key?(:multi)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
rescue
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
Oboe::API.trace('mongo', report_kvs) do
|
|
169
|
+
send("#{m}_without_oboe", *args)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
|
174
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Instrument Collection query operations
|
|
178
|
+
Oboe::Inst::Mongo::COLL_QUERY_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
|
179
|
+
define_method("#{m}_with_oboe") do |*args, &blk|
|
|
180
|
+
begin
|
|
181
|
+
report_kvs = oboe_collect(m, args)
|
|
182
|
+
args_length = args.length
|
|
183
|
+
|
|
184
|
+
if m == :distinct and args_length >= 2
|
|
185
|
+
report_kvs[:Key] = args[0]
|
|
186
|
+
report_kvs[:Query] = args[1].to_json if args[1] and args[1].class == Hash
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
if m == :find and args_length > 0
|
|
190
|
+
report_kvs[:Limit] = args[0][:limit] if !args[0].nil? and args[0].has_key?(:limit)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
if m == :group
|
|
194
|
+
unless args.empty?
|
|
195
|
+
if args[0].is_a?(Hash)
|
|
196
|
+
report_kvs[:Group_Key] = args[0][:key].to_json if args[0].has_key?(:key)
|
|
197
|
+
report_kvs[:Group_Condition] = args[0][:cond].to_json if args[0].has_key?(:cond)
|
|
198
|
+
report_kvs[:Group_Initial] = args[0][:initial].to_json if args[0].has_key?(:initial)
|
|
199
|
+
report_kvs[:Group_Reduce] = args[0][:reduce] if args[0].has_key?(:reduce)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
rescue
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
Oboe::API.trace('mongo', report_kvs) do
|
|
207
|
+
send("#{m}_without_oboe", *args, &blk)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
|
212
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Instrument Collection index operations
|
|
216
|
+
Oboe::Inst::Mongo::COLL_INDEX_OPS.reject { |m| not method_defined?(m) }.each do |m|
|
|
217
|
+
define_method("#{m}_with_oboe") do |*args|
|
|
218
|
+
report_kvs = oboe_collect(m, args)
|
|
219
|
+
_args = args || []
|
|
220
|
+
|
|
221
|
+
begin
|
|
222
|
+
if [:create_index, :ensure_index, :drop_index].include? m and not _args.empty?
|
|
223
|
+
report_kvs[:Index] = _args[0].to_json
|
|
224
|
+
end
|
|
225
|
+
rescue
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
Oboe::API.trace('mongo', report_kvs) do
|
|
229
|
+
send("#{m}_without_oboe", *args)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
class_eval "alias #{m}_without_oboe #{m}"
|
|
234
|
+
class_eval "alias #{m} #{m}_with_oboe"
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|