appoptics_apm_mnfst 4.5.2
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/.dockerignore +5 -0
- data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
- data/.gitignore +29 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +121 -0
- data/.yardopts +4 -0
- data/CHANGELOG.md +769 -0
- data/CONFIG.md +33 -0
- data/Gemfile +29 -0
- data/LICENSE +193 -0
- data/README.md +393 -0
- data/Rakefile +230 -0
- data/appoptics_apm.gemspec +61 -0
- data/bin/appoptics_apm_config +15 -0
- data/build_gem.sh +15 -0
- data/build_gem_upload_to_packagecloud.sh +20 -0
- data/examples/SDK/01_basic_tracing.rb +67 -0
- data/examples/carrying_context.rb +220 -0
- data/ext/oboe_metal/extconf.rb +114 -0
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/VERSION +1 -0
- data/init.rb +4 -0
- data/lib/appoptics_apm.rb +76 -0
- data/lib/appoptics_apm/api.rb +20 -0
- data/lib/appoptics_apm/api/layerinit.rb +41 -0
- data/lib/appoptics_apm/api/logging.rb +375 -0
- data/lib/appoptics_apm/api/memcache.rb +37 -0
- data/lib/appoptics_apm/api/metrics.rb +55 -0
- data/lib/appoptics_apm/api/profiling.rb +203 -0
- data/lib/appoptics_apm/api/tracing.rb +53 -0
- data/lib/appoptics_apm/api/util.rb +122 -0
- data/lib/appoptics_apm/base.rb +230 -0
- data/lib/appoptics_apm/config.rb +254 -0
- data/lib/appoptics_apm/frameworks/grape.rb +97 -0
- data/lib/appoptics_apm/frameworks/padrino.rb +108 -0
- data/lib/appoptics_apm/frameworks/rails.rb +94 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +55 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +108 -0
- data/lib/appoptics_apm/frameworks/sinatra.rb +125 -0
- data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
- data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
- data/lib/appoptics_apm/inst/curb.rb +330 -0
- data/lib/appoptics_apm/inst/dalli.rb +85 -0
- data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
- data/lib/appoptics_apm/inst/em-http-request.rb +101 -0
- data/lib/appoptics_apm/inst/excon.rb +125 -0
- data/lib/appoptics_apm/inst/faraday.rb +94 -0
- data/lib/appoptics_apm/inst/grpc_client.rb +162 -0
- data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
- data/lib/appoptics_apm/inst/http.rb +73 -0
- data/lib/appoptics_apm/inst/httpclient.rb +174 -0
- data/lib/appoptics_apm/inst/memcached.rb +86 -0
- data/lib/appoptics_apm/inst/mongo.rb +246 -0
- data/lib/appoptics_apm/inst/mongo2.rb +225 -0
- data/lib/appoptics_apm/inst/moped.rb +466 -0
- data/lib/appoptics_apm/inst/rack.rb +199 -0
- data/lib/appoptics_apm/inst/redis.rb +275 -0
- data/lib/appoptics_apm/inst/resque.rb +151 -0
- data/lib/appoptics_apm/inst/rest-client.rb +48 -0
- data/lib/appoptics_apm/inst/sequel.rb +178 -0
- data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
- data/lib/appoptics_apm/inst/sidekiq-worker.rb +65 -0
- data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
- data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
- data/lib/appoptics_apm/instrumentation.rb +22 -0
- data/lib/appoptics_apm/legacy_method_profiling.rb +90 -0
- data/lib/appoptics_apm/loading.rb +65 -0
- data/lib/appoptics_apm/logger.rb +42 -0
- data/lib/appoptics_apm/method_profiling.rb +33 -0
- data/lib/appoptics_apm/noop/README.md +9 -0
- data/lib/appoptics_apm/noop/context.rb +26 -0
- data/lib/appoptics_apm/noop/metadata.rb +22 -0
- data/lib/appoptics_apm/ruby.rb +35 -0
- data/lib/appoptics_apm/sdk/custom_metrics.rb +92 -0
- data/lib/appoptics_apm/sdk/tracing.rb +315 -0
- data/lib/appoptics_apm/support.rb +119 -0
- data/lib/appoptics_apm/test.rb +94 -0
- data/lib/appoptics_apm/thread_local.rb +26 -0
- data/lib/appoptics_apm/util.rb +319 -0
- data/lib/appoptics_apm/version.rb +15 -0
- data/lib/appoptics_apm/xtrace.rb +103 -0
- data/lib/joboe_metal.rb +212 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +80 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe_metal.rb +198 -0
- data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +265 -0
- data/yardoc_frontpage.md +26 -0
- metadata +266 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module Inst
|
|
6
|
+
#
|
|
7
|
+
# ActionController
|
|
8
|
+
#
|
|
9
|
+
# This modules contains the instrumentation code specific
|
|
10
|
+
# to Rails v4
|
|
11
|
+
#
|
|
12
|
+
module ActionController
|
|
13
|
+
include AppOpticsAPM::Inst::RailsBase
|
|
14
|
+
|
|
15
|
+
def self.included(base)
|
|
16
|
+
base.class_eval do
|
|
17
|
+
alias_method_chain :process_action, :appoptics
|
|
18
|
+
alias_method_chain :render, :appoptics
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def process_action_with_appoptics(method_name, *args)
|
|
23
|
+
kvs = {
|
|
24
|
+
:Controller => self.class.name,
|
|
25
|
+
:Action => self.action_name,
|
|
26
|
+
}
|
|
27
|
+
request.env['appoptics_apm.controller'] = kvs[:Controller]
|
|
28
|
+
request.env['appoptics_apm.action'] = kvs[:Action]
|
|
29
|
+
|
|
30
|
+
return process_action_without_appoptics(method_name, *args) unless AppOpticsAPM.tracing?
|
|
31
|
+
begin
|
|
32
|
+
kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_controller][:collect_backtraces]
|
|
33
|
+
|
|
34
|
+
AppOpticsAPM::API.log_entry('rails', kvs)
|
|
35
|
+
|
|
36
|
+
process_action_without_appoptics(method_name, *args)
|
|
37
|
+
|
|
38
|
+
rescue Exception => e
|
|
39
|
+
AppOpticsAPM::API.log_exception('rails', e) if log_rails_error?(e)
|
|
40
|
+
raise
|
|
41
|
+
ensure
|
|
42
|
+
AppOpticsAPM::API.log_exit('rails')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module Inst
|
|
6
|
+
#
|
|
7
|
+
# ActionController
|
|
8
|
+
#
|
|
9
|
+
# This modules contains the instrumentation code specific
|
|
10
|
+
# to Rails v5
|
|
11
|
+
#
|
|
12
|
+
module ActionController
|
|
13
|
+
include AppOpticsAPM::Inst::RailsBase
|
|
14
|
+
|
|
15
|
+
def process_action(method_name, *args)
|
|
16
|
+
kvs = {
|
|
17
|
+
:Controller => self.class.name,
|
|
18
|
+
:Action => self.action_name,
|
|
19
|
+
}
|
|
20
|
+
request.env['appoptics_apm.controller'] = kvs[:Controller]
|
|
21
|
+
request.env['appoptics_apm.action'] = kvs[:Action]
|
|
22
|
+
|
|
23
|
+
return super(method_name, *args) unless AppOpticsAPM.tracing?
|
|
24
|
+
begin
|
|
25
|
+
kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_controller][:collect_backtraces]
|
|
26
|
+
|
|
27
|
+
AppOpticsAPM::API.log_entry('rails', kvs)
|
|
28
|
+
super(method_name, *args)
|
|
29
|
+
|
|
30
|
+
rescue Exception => e
|
|
31
|
+
AppOpticsAPM::API.log_exception('rails', e) if log_rails_error?(e)
|
|
32
|
+
raise
|
|
33
|
+
ensure
|
|
34
|
+
AppOpticsAPM::API.log_exit('rails')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# render
|
|
40
|
+
#
|
|
41
|
+
# Our render wrapper that calls 'trace', which will log if we are tracing
|
|
42
|
+
#
|
|
43
|
+
def render(*args, &blk)
|
|
44
|
+
trace('actionview') do
|
|
45
|
+
super(*args, &blk)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module Inst
|
|
6
|
+
#
|
|
7
|
+
# ActionController
|
|
8
|
+
#
|
|
9
|
+
# This modules contains the instrumentation code specific
|
|
10
|
+
# to Rails v5.
|
|
11
|
+
#
|
|
12
|
+
module ActionControllerAPI
|
|
13
|
+
include AppOpticsAPM::Inst::RailsBase
|
|
14
|
+
|
|
15
|
+
def process_action(method_name, *args)
|
|
16
|
+
kvs = {
|
|
17
|
+
:Controller => self.class.name,
|
|
18
|
+
:Action => self.action_name
|
|
19
|
+
}
|
|
20
|
+
request.env['appoptics_apm.controller'] = kvs[:Controller]
|
|
21
|
+
request.env['appoptics_apm.action'] = kvs[:Action]
|
|
22
|
+
|
|
23
|
+
return super(method_name, *args) unless AppOpticsAPM.tracing?
|
|
24
|
+
begin
|
|
25
|
+
kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_controller_api][:collect_backtraces]
|
|
26
|
+
|
|
27
|
+
AppOpticsAPM::API.log_entry('rails-api', kvs)
|
|
28
|
+
super(method_name, *args)
|
|
29
|
+
|
|
30
|
+
rescue Exception => e
|
|
31
|
+
AppOpticsAPM::API.log_exception('rails', e) if log_rails_error?(e)
|
|
32
|
+
raise
|
|
33
|
+
ensure
|
|
34
|
+
AppOpticsAPM::API.log_exit('rails-api')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# render
|
|
40
|
+
#
|
|
41
|
+
# Our render wrapper that calls 'trace', which will log if we are tracing
|
|
42
|
+
#
|
|
43
|
+
def render(*args, &blk)
|
|
44
|
+
trace('actionview') do
|
|
45
|
+
super(*args, &blk)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
if defined?(ActionView::Base) && AppOpticsAPM::Config[:action_view][:enabled]
|
|
5
|
+
|
|
6
|
+
##
|
|
7
|
+
# ActionView Instrumentation is version dependent. ActionView 2.x is separate
|
|
8
|
+
# and ActionView 3.0 is a special case.
|
|
9
|
+
# Everything else goes here. (ActionView 3.1 - 4.0 as of this writing)
|
|
10
|
+
#
|
|
11
|
+
if (Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR > 0) || Rails::VERSION::MAJOR >= 4
|
|
12
|
+
|
|
13
|
+
AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actionview' if AppOpticsAPM::Config[:verbose]
|
|
14
|
+
|
|
15
|
+
ActionView::PartialRenderer.class_eval do
|
|
16
|
+
alias :render_partial_without_appoptics :render_partial
|
|
17
|
+
def render_partial
|
|
18
|
+
entry_kvs = {}
|
|
19
|
+
begin
|
|
20
|
+
name = AppOpticsAPM::Util.prettify(@options[:partial]) if @options.is_a?(Hash)
|
|
21
|
+
entry_kvs[:FunctionName] = :render_partial
|
|
22
|
+
entry_kvs[:Class] = :PartialRenderer
|
|
23
|
+
entry_kvs[:Module] = :ActionView
|
|
24
|
+
entry_kvs[:File] = __FILE__
|
|
25
|
+
entry_kvs[:LineNumber] = __LINE__
|
|
26
|
+
rescue => e
|
|
27
|
+
AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
AppOpticsAPM::API.profile(name, entry_kvs, AppOpticsAPM::Config[:action_view][:collect_backtraces]) do
|
|
31
|
+
render_partial_without_appoptics
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias :render_collection_without_appoptics :render_collection
|
|
36
|
+
def render_collection
|
|
37
|
+
entry_kvs = {}
|
|
38
|
+
begin
|
|
39
|
+
name = AppOpticsAPM::Util.prettify(@path)
|
|
40
|
+
entry_kvs[:FunctionName] = :render_collection
|
|
41
|
+
entry_kvs[:Class] = :PartialRenderer
|
|
42
|
+
entry_kvs[:Module] = :ActionView
|
|
43
|
+
entry_kvs[:File] = __FILE__
|
|
44
|
+
entry_kvs[:LineNumber] = __LINE__
|
|
45
|
+
rescue => e
|
|
46
|
+
AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
AppOpticsAPM::API.profile(name, entry_kvs, AppOpticsAPM::Config[:action_view][:collect_backtraces]) do
|
|
50
|
+
render_collection_without_appoptics
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# vim:set expandtab:tabstop=2
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
if defined?(ActionView::Base) && AppOpticsAPM::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_appoptics :render_partial
|
|
10
|
+
def render_partial(object = @object)
|
|
11
|
+
entry_kvs = {}
|
|
12
|
+
begin
|
|
13
|
+
name = AppOpticsAPM::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 => e
|
|
20
|
+
AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
AppOpticsAPM::API.profile(name, entry_kvs, AppOpticsAPM::Config[:action_view][:collect_backtraces]) do
|
|
24
|
+
render_partial_without_appoptics(object)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
alias :render_collection_without_appoptics :render_collection
|
|
29
|
+
def render_collection
|
|
30
|
+
entry_kvs = {}
|
|
31
|
+
begin
|
|
32
|
+
name = AppOpticsAPM::Util.prettify(@path)
|
|
33
|
+
entry_kvs[:FunctionName] = :render_collection
|
|
34
|
+
entry_kvs[:Class] = :PartialRenderer
|
|
35
|
+
entry_kvs[:Module] = 'ActionView::Partials'
|
|
36
|
+
entry_kvs[:File] = __FILE__
|
|
37
|
+
entry_kvs[:LineNumber] = __LINE__
|
|
38
|
+
rescue => e
|
|
39
|
+
AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
AppOpticsAPM::API.profile(name, entry_kvs, AppOpticsAPM::Config[:action_view][:collect_backtraces]) do
|
|
43
|
+
render_collection_without_appoptics
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# vim:set expandtab:tabstop=2
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require 'appoptics_apm/frameworks/rails/inst/connection_adapters/mysql'
|
|
5
|
+
require 'appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2'
|
|
6
|
+
require 'appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql'
|
|
7
|
+
|
|
8
|
+
if AppOpticsAPM::Config[:active_record][:enabled] && !defined?(JRUBY_VERSION)
|
|
9
|
+
begin
|
|
10
|
+
adapter = ActiveRecord::Base.connection_config[:adapter]
|
|
11
|
+
|
|
12
|
+
if Rails::VERSION::MAJOR < 5
|
|
13
|
+
require 'appoptics_apm/frameworks/rails/inst/connection_adapters/utils'
|
|
14
|
+
else
|
|
15
|
+
require 'appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
AppOpticsAPM::Inst::ConnectionAdapters::FlavorInitializers.mysql if adapter == 'mysql'
|
|
19
|
+
AppOpticsAPM::Inst::ConnectionAdapters::FlavorInitializers.mysql2 if adapter == 'mysql2'
|
|
20
|
+
AppOpticsAPM::Inst::ConnectionAdapters::FlavorInitializers.postgresql if adapter == 'postgresql'
|
|
21
|
+
|
|
22
|
+
rescue StandardError => e
|
|
23
|
+
AppOpticsAPM.logger.error "[appoptics_apm/error] AppOpticsAPM/ActiveRecord error: #{e.inspect}"
|
|
24
|
+
AppOpticsAPM.logger.debug e.backtrace.join("\n")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
# vim:set expandtab:tabstop=2
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module Inst
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module FlavorInitializers
|
|
8
|
+
def self.mysql
|
|
9
|
+
AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting activerecord mysqladapter' if AppOpticsAPM::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
|
+
AppOpticsAPM::Util.send_include(ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter,
|
|
17
|
+
AppOpticsAPM::Inst::ConnectionAdapters::Utils)
|
|
18
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter, :execute)
|
|
19
|
+
|
|
20
|
+
# MysqlAdapter
|
|
21
|
+
AppOpticsAPM::Util.send_include(ActiveRecord::ConnectionAdapters::MysqlAdapter,
|
|
22
|
+
AppOpticsAPM::Inst::ConnectionAdapters::Utils)
|
|
23
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::MysqlAdapter, :exec_query)
|
|
24
|
+
|
|
25
|
+
else
|
|
26
|
+
# ActiveRecord 3.1 and below
|
|
27
|
+
|
|
28
|
+
# MysqlAdapter
|
|
29
|
+
AppOpticsAPM::Util.send_include(ActiveRecord::ConnectionAdapters::MysqlAdapter,
|
|
30
|
+
AppOpticsAPM::Inst::ConnectionAdapters::Utils)
|
|
31
|
+
|
|
32
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::MysqlAdapter, :execute)
|
|
33
|
+
|
|
34
|
+
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 1
|
|
35
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::MysqlAdapter, :begin_db_transaction)
|
|
36
|
+
AppOpticsAPM::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,29 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module Inst
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module FlavorInitializers
|
|
8
|
+
def self.mysql2
|
|
9
|
+
AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting activerecord mysql2adapter' if AppOpticsAPM::Config[:verbose]
|
|
10
|
+
|
|
11
|
+
AppOpticsAPM::Util.send_include(ActiveRecord::ConnectionAdapters::Mysql2Adapter,
|
|
12
|
+
AppOpticsAPM::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
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::Mysql2Adapter, :execute)
|
|
18
|
+
else
|
|
19
|
+
# ActiveRecord 3.1 and above
|
|
20
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_insert)
|
|
21
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_query)
|
|
22
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_update)
|
|
23
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::Mysql2Adapter, :exec_delete)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module Inst
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module FlavorInitializers
|
|
8
|
+
def self.postgresql
|
|
9
|
+
|
|
10
|
+
AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting activerecord postgresqladapter' if AppOpticsAPM::Config[:verbose]
|
|
11
|
+
|
|
12
|
+
AppOpticsAPM::Util.send_include(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter,
|
|
13
|
+
AppOpticsAPM::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
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_query)
|
|
20
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_update)
|
|
21
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :exec_delete)
|
|
22
|
+
|
|
23
|
+
else
|
|
24
|
+
# ActiveRecord 3.0 and prior
|
|
25
|
+
AppOpticsAPM::Util.method_alias(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :execute)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
module AppOpticsAPM
|
|
5
|
+
module Inst
|
|
6
|
+
module ConnectionAdapters
|
|
7
|
+
module Utils
|
|
8
|
+
|
|
9
|
+
def extract_trace_details(sql, name = nil, binds = [])
|
|
10
|
+
opts = {}
|
|
11
|
+
if AppOpticsAPM::Config[:sanitize_sql]
|
|
12
|
+
# Sanitize SQL and don't report binds
|
|
13
|
+
opts[:Query] = AppOpticsAPM::Util.sanitize_sql(sql)
|
|
14
|
+
else
|
|
15
|
+
# Report raw SQL and any binds if they exist
|
|
16
|
+
opts[:Query] = sql.to_s
|
|
17
|
+
opts[:QueryArgs] = binds.map { |col, val| [col.name, val.to_s] } unless binds.empty?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
opts[:Name] = name.to_s if name
|
|
21
|
+
opts[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:active_record][:collect_backtraces]
|
|
22
|
+
|
|
23
|
+
config = ActiveRecord::Base.connection_config
|
|
24
|
+
if config
|
|
25
|
+
opts[:Database] = config[:database] if config.key?(:database)
|
|
26
|
+
opts[:RemoteHost] = config[:host] if config.key?(:host)
|
|
27
|
+
adapter_name = config[:adapter]
|
|
28
|
+
|
|
29
|
+
case adapter_name
|
|
30
|
+
when /mysql/i
|
|
31
|
+
opts[:Flavor] = 'mysql'
|
|
32
|
+
when /postgres/i
|
|
33
|
+
opts[:Flavor] = 'postgresql'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
rescue StandardError => e
|
|
37
|
+
AppOpticsAPM.logger.debug "[appoptics_apm/rails] Exception raised capturing ActiveRecord KVs: #{e.inspect}"
|
|
38
|
+
AppOpticsAPM.logger.debug e.backtrace.join('\n')
|
|
39
|
+
ensure
|
|
40
|
+
return opts
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# We don't want to trace framework caches. Only instrument SQL that
|
|
44
|
+
# directly hits the database.
|
|
45
|
+
def ignore_payload?(name)
|
|
46
|
+
%w(SCHEMA EXPLAIN CACHE).include?(name.to_s) ||
|
|
47
|
+
(name && name.to_sym == :skip_logging) ||
|
|
48
|
+
name == 'ActiveRecord::SchemaMigration Load'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def execute_with_appoptics(sql, name = nil)
|
|
52
|
+
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
53
|
+
|
|
54
|
+
opts = extract_trace_details(sql, name)
|
|
55
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
56
|
+
execute_without_appoptics(sql, name)
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
execute_without_appoptics(sql, name)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def exec_query_with_appoptics(sql, name = nil, binds = [])
|
|
64
|
+
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
65
|
+
|
|
66
|
+
opts = extract_trace_details(sql, name, binds)
|
|
67
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
68
|
+
exec_query_without_appoptics(sql, name, binds)
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
exec_query_without_appoptics(sql, name, binds)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def exec_delete_with_appoptics(sql, name = nil, binds = [])
|
|
76
|
+
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
77
|
+
|
|
78
|
+
opts = extract_trace_details(sql, name, binds)
|
|
79
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
80
|
+
exec_delete_without_appoptics(sql, name, binds)
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
exec_delete_without_appoptics(sql, name, binds)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def exec_update_with_appoptics(sql, name = nil, binds = [])
|
|
88
|
+
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
89
|
+
|
|
90
|
+
opts = extract_trace_details(sql, name, binds)
|
|
91
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
92
|
+
exec_update_without_appoptics(sql, name, binds)
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
exec_update_without_appoptics(sql, name, binds)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def exec_insert_with_appoptics(sql, name = nil, binds = [], *args)
|
|
100
|
+
if AppOpticsAPM.tracing? && !ignore_payload?(name)
|
|
101
|
+
|
|
102
|
+
opts = extract_trace_details(sql, name, binds)
|
|
103
|
+
AppOpticsAPM::API.trace('activerecord', opts, :ar_started) do
|
|
104
|
+
exec_insert_without_appoptics(sql, name, binds, *args)
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
exec_insert_without_appoptics(sql, name, binds, *args)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def begin_db_transaction_with_appoptics
|
|
112
|
+
AppOpticsAPM::API.trace('activerecord', { :Query => 'BEGIN', :Flavor => :mysql }, :ar_started) do
|
|
113
|
+
begin_db_transaction_without_appoptics
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end # Utils
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|