appoptics_apm-zearn 4.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +5 -0
  3. data/.github/ISSUE_TEMPLATE/bug-or-feature-request.md +16 -0
  4. data/.github/workflows/build_and_release_gem.yml +103 -0
  5. data/.github/workflows/build_for_packagecloud.yml +70 -0
  6. data/.github/workflows/docker-images.yml +47 -0
  7. data/.github/workflows/run_cpluplus_tests.yml +73 -0
  8. data/.github/workflows/run_tests.yml +168 -0
  9. data/.github/workflows/scripts/test_install.rb +23 -0
  10. data/.github/workflows/swig/swig-v4.0.2.tar.gz +0 -0
  11. data/.github/workflows/test_on_4_linux.yml +159 -0
  12. data/.gitignore +36 -0
  13. data/.rubocop.yml +29 -0
  14. data/.travis.yml +130 -0
  15. data/.yardopts +6 -0
  16. data/CHANGELOG.md +769 -0
  17. data/CONFIG.md +33 -0
  18. data/Gemfile +14 -0
  19. data/LICENSE +202 -0
  20. data/README.md +393 -0
  21. data/appoptics_apm.gemspec +70 -0
  22. data/bin/appoptics_apm_config +15 -0
  23. data/examples/prepend.rb +13 -0
  24. data/examples/sdk_examples.rb +158 -0
  25. data/ext/oboe_metal/README.md +69 -0
  26. data/ext/oboe_metal/extconf.rb +151 -0
  27. data/ext/oboe_metal/lib/.keep +0 -0
  28. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.0.0.0.sha256 +1 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.0.0.0.sha256 +1 -0
  30. data/ext/oboe_metal/noop/noop.c +8 -0
  31. data/ext/oboe_metal/src/README.md +6 -0
  32. data/ext/oboe_metal/src/VERSION +2 -0
  33. data/ext/oboe_metal/src/bson/bson.h +220 -0
  34. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  35. data/ext/oboe_metal/src/frames.cc +246 -0
  36. data/ext/oboe_metal/src/frames.h +40 -0
  37. data/ext/oboe_metal/src/init_appoptics_apm.cc +21 -0
  38. data/ext/oboe_metal/src/logging.cc +95 -0
  39. data/ext/oboe_metal/src/logging.h +35 -0
  40. data/ext/oboe_metal/src/oboe.h +1156 -0
  41. data/ext/oboe_metal/src/oboe_api.cpp +652 -0
  42. data/ext/oboe_metal/src/oboe_api.hpp +431 -0
  43. data/ext/oboe_metal/src/oboe_debug.h +59 -0
  44. data/ext/oboe_metal/src/oboe_swig_wrap.cc +7329 -0
  45. data/ext/oboe_metal/src/profiling.cc +435 -0
  46. data/ext/oboe_metal/src/profiling.h +78 -0
  47. data/ext/oboe_metal/test/CMakeLists.txt +53 -0
  48. data/ext/oboe_metal/test/FindGMock.cmake +43 -0
  49. data/ext/oboe_metal/test/README.md +56 -0
  50. data/ext/oboe_metal/test/frames_test.cc +164 -0
  51. data/ext/oboe_metal/test/profiling_test.cc +93 -0
  52. data/ext/oboe_metal/test/ruby_inc_dir.rb +8 -0
  53. data/ext/oboe_metal/test/ruby_prefix.rb +8 -0
  54. data/ext/oboe_metal/test/ruby_test_helper.rb +67 -0
  55. data/ext/oboe_metal/test/test.h +11 -0
  56. data/ext/oboe_metal/test/test_main.cc +32 -0
  57. data/init.rb +4 -0
  58. data/lib/appoptics_apm/api/layerinit.rb +41 -0
  59. data/lib/appoptics_apm/api/logging.rb +381 -0
  60. data/lib/appoptics_apm/api/memcache.rb +37 -0
  61. data/lib/appoptics_apm/api/metrics.rb +63 -0
  62. data/lib/appoptics_apm/api/tracing.rb +57 -0
  63. data/lib/appoptics_apm/api/util.rb +120 -0
  64. data/lib/appoptics_apm/api.rb +21 -0
  65. data/lib/appoptics_apm/base.rb +231 -0
  66. data/lib/appoptics_apm/config.rb +299 -0
  67. data/lib/appoptics_apm/frameworks/grape.rb +98 -0
  68. data/lib/appoptics_apm/frameworks/padrino.rb +78 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +104 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_controller6.rb +50 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +88 -0
  75. data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
  76. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  77. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +29 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +31 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +119 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +114 -0
  81. data/lib/appoptics_apm/frameworks/rails/inst/logger_formatters.rb +27 -0
  82. data/lib/appoptics_apm/frameworks/rails.rb +100 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +96 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +89 -0
  86. data/lib/appoptics_apm/inst/curb.rb +332 -0
  87. data/lib/appoptics_apm/inst/dalli.rb +85 -0
  88. data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
  89. data/lib/appoptics_apm/inst/em-http-request.rb +101 -0
  90. data/lib/appoptics_apm/inst/excon.rb +125 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +106 -0
  92. data/lib/appoptics_apm/inst/graphql.rb +240 -0
  93. data/lib/appoptics_apm/inst/grpc_client.rb +159 -0
  94. data/lib/appoptics_apm/inst/grpc_server.rb +120 -0
  95. data/lib/appoptics_apm/inst/http.rb +81 -0
  96. data/lib/appoptics_apm/inst/httpclient.rb +174 -0
  97. data/lib/appoptics_apm/inst/logger_formatter.rb +50 -0
  98. data/lib/appoptics_apm/inst/logging_log_event.rb +28 -0
  99. data/lib/appoptics_apm/inst/lumberjack_formatter.rb +13 -0
  100. data/lib/appoptics_apm/inst/memcached.rb +86 -0
  101. data/lib/appoptics_apm/inst/mongo.rb +246 -0
  102. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  103. data/lib/appoptics_apm/inst/moped.rb +466 -0
  104. data/lib/appoptics_apm/inst/rack.rb +182 -0
  105. data/lib/appoptics_apm/inst/rack_cache.rb +35 -0
  106. data/lib/appoptics_apm/inst/redis.rb +274 -0
  107. data/lib/appoptics_apm/inst/resque.rb +151 -0
  108. data/lib/appoptics_apm/inst/rest-client.rb +48 -0
  109. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  110. data/lib/appoptics_apm/inst/sidekiq-client.rb +55 -0
  111. data/lib/appoptics_apm/inst/sidekiq-worker.rb +66 -0
  112. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  113. data/lib/appoptics_apm/inst/typhoeus.rb +108 -0
  114. data/lib/appoptics_apm/instrumentation.rb +22 -0
  115. data/lib/appoptics_apm/loading.rb +65 -0
  116. data/lib/appoptics_apm/logger.rb +14 -0
  117. data/lib/appoptics_apm/noop/README.md +9 -0
  118. data/lib/appoptics_apm/noop/context.rb +27 -0
  119. data/lib/appoptics_apm/noop/metadata.rb +25 -0
  120. data/lib/appoptics_apm/noop/profiling.rb +21 -0
  121. data/lib/appoptics_apm/oboe_init_options.rb +211 -0
  122. data/lib/appoptics_apm/ruby.rb +35 -0
  123. data/lib/appoptics_apm/sdk/current_trace.rb +77 -0
  124. data/lib/appoptics_apm/sdk/custom_metrics.rb +94 -0
  125. data/lib/appoptics_apm/sdk/logging.rb +37 -0
  126. data/lib/appoptics_apm/sdk/tracing.rb +434 -0
  127. data/lib/appoptics_apm/support/profiling.rb +18 -0
  128. data/lib/appoptics_apm/support/transaction_metrics.rb +67 -0
  129. data/lib/appoptics_apm/support/transaction_settings.rb +219 -0
  130. data/lib/appoptics_apm/support/x_trace_options.rb +110 -0
  131. data/lib/appoptics_apm/support_report.rb +119 -0
  132. data/lib/appoptics_apm/test.rb +95 -0
  133. data/lib/appoptics_apm/thread_local.rb +26 -0
  134. data/lib/appoptics_apm/util.rb +326 -0
  135. data/lib/appoptics_apm/version.rb +16 -0
  136. data/lib/appoptics_apm/xtrace.rb +115 -0
  137. data/lib/appoptics_apm.rb +77 -0
  138. data/lib/joboe_metal.rb +212 -0
  139. data/lib/oboe.rb +7 -0
  140. data/lib/oboe_metal.rb +172 -0
  141. data/lib/rails/generators/appoptics_apm/install_generator.rb +47 -0
  142. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +425 -0
  143. data/log/.keep +0 -0
  144. data/yardoc_frontpage.md +26 -0
  145. metadata +231 -0
@@ -0,0 +1,104 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ module AppOpticsAPM
5
+ module Inst
6
+ #
7
+ # RailsBase
8
+ #
9
+ # This module contains the instrumentation code common to
10
+ # many Rails versions.
11
+ #
12
+ module RailsBase
13
+
14
+ #
15
+ # has_handler?
16
+ #
17
+ # Determins if <tt>exception</tt> has a registered
18
+ # handler via <tt>rescue_from</tt>
19
+ #
20
+ def has_handler?(exception)
21
+ # Don't log exceptions if they have a rescue handler set
22
+ has_handler = false
23
+ rescue_handlers.detect do |klass_name, _handler|
24
+ # Rescue handlers can be specified as strings or constant names
25
+ klass = self.class.const_get(klass_name) rescue nil
26
+ klass ||= klass_name.constantize rescue nil
27
+ has_handler = exception.is_a?(klass) if klass
28
+ end
29
+ has_handler
30
+ rescue => e
31
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] Error searching Rails handlers: #{e.message}"
32
+ return false
33
+ end
34
+
35
+ #
36
+ # log_rails_error?
37
+ #
38
+ # Determines whether we should log a raised exception to the
39
+ # AppOptics dashboard. This is determined by whether the exception
40
+ # has a rescue handler setup and the value of
41
+ # AppOpticsAPM::Config[:report_rescued_errors]
42
+ #
43
+ def log_rails_error?(exception)
44
+ # As it's perculating up through the layers... make sure that
45
+ # we only report it once.
46
+ return false if exception.instance_variable_get(:@exn_logged)
47
+
48
+ return false if has_handler?(exception) && !AppOpticsAPM::Config[:report_rescued_errors]
49
+
50
+ true
51
+ end
52
+
53
+ ##
54
+ # This method does the logging if we are tracing
55
+ # it `wraps` around the call to the original method
56
+ #
57
+ # This can't use the SDK trace() method because of the log_rails_error?(e) condition
58
+ def trace(layer)
59
+ return yield unless AppOpticsAPM.tracing?
60
+ begin
61
+ AppOpticsAPM::API.log_entry(layer)
62
+ yield
63
+ rescue Exception => e
64
+ AppOpticsAPM::API.log_exception(layer, e) if log_rails_error?(e)
65
+ raise
66
+ ensure
67
+ AppOpticsAPM::API.log_exit(layer)
68
+ end
69
+ end
70
+
71
+
72
+ #
73
+ # render_with_appoptics
74
+ #
75
+ # Our render wrapper that calls 'add_logging', which will log if we are tracing
76
+ #
77
+ def render_with_appoptics(*args, &blk)
78
+ trace('actionview') do
79
+ render_without_appoptics(*args, &blk)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ # ActionController::Base
87
+ if defined?(ActionController::Base) && AppOpticsAPM::Config[:action_controller][:enabled] && Rails::VERSION::MAJOR <= 6
88
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actioncontroller' if AppOpticsAPM::Config[:verbose]
89
+ require "appoptics_apm/frameworks/rails/inst/action_controller#{Rails::VERSION::MAJOR}"
90
+ if Rails::VERSION::MAJOR >= 5
91
+ ActionController::Base.send(:prepend, ::AppOpticsAPM::Inst::ActionController)
92
+ elsif Rails::VERSION::MAJOR < 5
93
+ AppOpticsAPM::Util.send_include(::ActionController::Base, AppOpticsAPM::Inst::ActionController)
94
+ end
95
+ end
96
+
97
+ # ActionController::API - Rails 5 or via the rails-api gem
98
+ if defined?(ActionController::API) && AppOpticsAPM::Config[:action_controller_api][:enabled] && Rails::VERSION::MAJOR <= 6
99
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actioncontroller api' if AppOpticsAPM::Config[:verbose]
100
+ require "appoptics_apm/frameworks/rails/inst/action_controller_api"
101
+ ActionController::API.send(:prepend, ::AppOpticsAPM::Inst::ActionControllerAPI)
102
+ end
103
+
104
+ # vim:set expandtab:tabstop=2
@@ -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 v6
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,88 @@
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 >= 4
7
+
8
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actionview' if AppOpticsAPM::Config[:verbose]
9
+ if ActionView.version >= Gem::Version.new('6.1.0') # the methods changed in this version
10
+
11
+ ActionView::PartialRenderer.class_eval do
12
+ alias :render_partial_template_without_appoptics :render_partial_template
13
+
14
+ def render_partial_template(*args)
15
+ _, _, template, _, _ = args
16
+ entry_kvs = {}
17
+ begin
18
+ entry_kvs[:Partial] = template.virtual_path
19
+ rescue => e
20
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
21
+ end
22
+ AppOpticsAPM::SDK.trace(:partial, entry_kvs) do
23
+ entry_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_view][:collect_backtraces]
24
+ render_partial_template_without_appoptics(*args)
25
+ end
26
+ end
27
+ end
28
+
29
+ ActionView::CollectionRenderer.class_eval do
30
+ alias :render_collection_without_appoptics :render_collection
31
+
32
+ def render_collection(*args)
33
+ _, _, _, template, _, _ = args
34
+ entry_kvs = {}
35
+ begin
36
+ entry_kvs[:Partial] = template.virtual_path
37
+ rescue => e
38
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
39
+ end
40
+ AppOpticsAPM::SDK.trace(:collection, entry_kvs) do
41
+ entry_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_view][:collect_backtraces]
42
+ render_collection_without_appoptics(*args)
43
+ end
44
+ end
45
+ end
46
+
47
+ else # Rails < 6.1.0
48
+
49
+ ActionView::PartialRenderer.class_eval do
50
+ alias :render_partial_without_appoptics :render_partial
51
+ def render_partial(*args)
52
+ template = @template || args[1]
53
+ entry_kvs = {}
54
+ begin
55
+ entry_kvs[:Partial] = template.virtual_path
56
+ # entry_kvs[:Partial] = AppOpticsAPM::Util.prettify(@options[:partial]) if @options.is_a?(Hash)
57
+ rescue => e
58
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
59
+ end
60
+
61
+ AppOpticsAPM::SDK.trace('partial', entry_kvs) do
62
+ entry_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_view][:collect_backtraces]
63
+ render_partial_without_appoptics(*args)
64
+ end
65
+ end
66
+
67
+ alias :render_collection_without_appoptics :render_collection
68
+ def render_collection(*args)
69
+ template = @template || args[1]
70
+ entry_kvs = {}
71
+ begin
72
+ entry_kvs[:Partial] = template.virtual_path
73
+ rescue => e
74
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
75
+ end
76
+
77
+ AppOpticsAPM::SDK.trace('collection', entry_kvs) do
78
+ entry_kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_view][:collect_backtraces]
79
+ render_collection_without_appoptics(*args)
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+
88
+ # 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) && Rails::VERSION::MAJOR <= 6
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
+ elsif Rails::VERSION::MAJOR >= 5
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|postgis/i
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|^postgis/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