appoptics_apm 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +43 -0
  3. data/.dockerignore +5 -0
  4. data/.gitignore +23 -0
  5. data/.rubocop.yml +5 -0
  6. data/.travis.yml +82 -0
  7. data/CHANGELOG.md +769 -0
  8. data/CONFIG.md +33 -0
  9. data/Dockerfile +41 -0
  10. data/Dockerfile_test +66 -0
  11. data/Gemfile +41 -0
  12. data/LICENSE +193 -0
  13. data/README.md +351 -0
  14. data/Rakefile +202 -0
  15. data/Vagrantfile +67 -0
  16. data/appoptics_apm.gemspec +55 -0
  17. data/build_gems.sh +15 -0
  18. data/docker-compose.yml +73 -0
  19. data/examples/DNT.md +35 -0
  20. data/examples/carrying_context.rb +220 -0
  21. data/examples/instrumenting_metal_controller.rb +8 -0
  22. data/examples/puma_on_heroku_config.rb +17 -0
  23. data/examples/tracing_async_threads.rb +124 -0
  24. data/examples/tracing_background_jobs.rb +53 -0
  25. data/examples/tracing_forked_processes.rb +99 -0
  26. data/examples/unicorn_on_heroku_config.rb +28 -0
  27. data/ext/oboe_metal/extconf.rb +54 -0
  28. data/ext/oboe_metal/lib/.keep +0 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0.so.0.0.0 +0 -0
  30. data/ext/oboe_metal/noop/noop.c +7 -0
  31. data/ext/oboe_metal/src/VERSION +1 -0
  32. data/ext/oboe_metal/src/bson/bson.h +221 -0
  33. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  34. data/ext/oboe_metal/src/oboe.h +883 -0
  35. data/ext/oboe_metal/src/oboe.hpp +793 -0
  36. data/ext/oboe_metal/src/oboe_debug.h +50 -0
  37. data/ext/oboe_metal/src/oboe_wrap.cxx +6088 -0
  38. data/ext/oboe_metal/tests/test.rb +11 -0
  39. data/gemfiles/delayed_job.gemfile +36 -0
  40. data/gemfiles/frameworks.gemfile +44 -0
  41. data/gemfiles/instrumentation_mocked.gemfile +29 -0
  42. data/gemfiles/libraries.gemfile +85 -0
  43. data/gemfiles/rails23.gemfile +39 -0
  44. data/gemfiles/rails30.gemfile +42 -0
  45. data/gemfiles/rails31.gemfile +44 -0
  46. data/gemfiles/rails32.gemfile +54 -0
  47. data/gemfiles/rails40.gemfile +27 -0
  48. data/gemfiles/rails41.gemfile +27 -0
  49. data/gemfiles/rails42.gemfile +35 -0
  50. data/gemfiles/rails50.gemfile +44 -0
  51. data/gemfiles/rails51.gemfile +44 -0
  52. data/get_version.rb +5 -0
  53. data/init.rb +4 -0
  54. data/lib/appoptics_apm/api/layerinit.rb +39 -0
  55. data/lib/appoptics_apm/api/logging.rb +359 -0
  56. data/lib/appoptics_apm/api/memcache.rb +34 -0
  57. data/lib/appoptics_apm/api/profiling.rb +201 -0
  58. data/lib/appoptics_apm/api/tracing.rb +152 -0
  59. data/lib/appoptics_apm/api/util.rb +128 -0
  60. data/lib/appoptics_apm/api.rb +18 -0
  61. data/lib/appoptics_apm/base.rb +252 -0
  62. data/lib/appoptics_apm/config.rb +281 -0
  63. data/lib/appoptics_apm/frameworks/grape.rb +93 -0
  64. data/lib/appoptics_apm/frameworks/padrino/templates.rb +58 -0
  65. data/lib/appoptics_apm/frameworks/padrino.rb +52 -0
  66. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +106 -0
  67. data/lib/appoptics_apm/frameworks/rails/inst/action_controller2.rb +61 -0
  68. data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +58 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_view_2x.rb +56 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -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 +28 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +120 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +101 -0
  81. data/lib/appoptics_apm/frameworks/rails.rb +116 -0
  82. data/lib/appoptics_apm/frameworks/sinatra/templates.rb +56 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +71 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +92 -0
  86. data/lib/appoptics_apm/inst/curb.rb +329 -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 +105 -0
  90. data/lib/appoptics_apm/inst/excon.rb +130 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +77 -0
  92. data/lib/appoptics_apm/inst/http.rb +83 -0
  93. data/lib/appoptics_apm/inst/httpclient.rb +176 -0
  94. data/lib/appoptics_apm/inst/memcache.rb +102 -0
  95. data/lib/appoptics_apm/inst/memcached.rb +94 -0
  96. data/lib/appoptics_apm/inst/mongo.rb +242 -0
  97. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  98. data/lib/appoptics_apm/inst/moped.rb +466 -0
  99. data/lib/appoptics_apm/inst/rack.rb +146 -0
  100. data/lib/appoptics_apm/inst/redis.rb +275 -0
  101. data/lib/appoptics_apm/inst/resque.rb +151 -0
  102. data/lib/appoptics_apm/inst/rest-client.rb +50 -0
  103. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  104. data/lib/appoptics_apm/inst/sidekiq-client.rb +53 -0
  105. data/lib/appoptics_apm/inst/sidekiq-worker.rb +67 -0
  106. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  107. data/lib/appoptics_apm/inst/typhoeus.rb +113 -0
  108. data/lib/appoptics_apm/instrumentation.rb +22 -0
  109. data/lib/appoptics_apm/legacy_method_profiling.rb +97 -0
  110. data/lib/appoptics_apm/loading.rb +66 -0
  111. data/lib/appoptics_apm/logger.rb +41 -0
  112. data/lib/appoptics_apm/method_profiling.rb +33 -0
  113. data/lib/appoptics_apm/ruby.rb +35 -0
  114. data/lib/appoptics_apm/support.rb +135 -0
  115. data/lib/appoptics_apm/test.rb +94 -0
  116. data/lib/appoptics_apm/thread_local.rb +26 -0
  117. data/lib/appoptics_apm/util.rb +312 -0
  118. data/lib/appoptics_apm/version.rb +15 -0
  119. data/lib/appoptics_apm/xtrace.rb +103 -0
  120. data/lib/appoptics_apm.rb +72 -0
  121. data/lib/joboe_metal.rb +214 -0
  122. data/lib/oboe/README +2 -0
  123. data/lib/oboe/backward_compatibility.rb +80 -0
  124. data/lib/oboe/inst/rack.rb +11 -0
  125. data/lib/oboe.rb +7 -0
  126. data/lib/oboe_metal.rb +187 -0
  127. data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
  128. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +222 -0
  129. data/ruby_setup.sh +47 -0
  130. data/run_docker_build_gem_upload_to_packagecloud.sh +20 -0
  131. data/run_tests_docker.rb +32 -0
  132. data/test/benchmark/README.md +65 -0
  133. data/test/benchmark/logging_bench.rb +54 -0
  134. data/test/benchmark/with_libraries_gemfile/bunny_bench.rb +69 -0
  135. data/test/benchmark/with_rails5x_gemfile/action_controller5x_bench.rb +43 -0
  136. data/test/frameworks/apps/grape_nested.rb +33 -0
  137. data/test/frameworks/apps/grape_simple.rb +80 -0
  138. data/test/frameworks/apps/padrino_simple.rb +80 -0
  139. data/test/frameworks/apps/sinatra_simple.rb +55 -0
  140. data/test/frameworks/grape_test.rb +286 -0
  141. data/test/frameworks/padrino_test.rb +222 -0
  142. data/test/frameworks/rails3x_test.rb +554 -0
  143. data/test/frameworks/rails4x_test.rb +570 -0
  144. data/test/frameworks/rails5x_api_test.rb +210 -0
  145. data/test/frameworks/rails5x_test.rb +376 -0
  146. data/test/frameworks/rails_shared_tests.rb +172 -0
  147. data/test/frameworks/sinatra_test.rb +140 -0
  148. data/test/instrumentation/bunny_client_test.rb +276 -0
  149. data/test/instrumentation/bunny_consumer_test.rb +204 -0
  150. data/test/instrumentation/curb_test.rb +398 -0
  151. data/test/instrumentation/dalli_test.rb +177 -0
  152. data/test/instrumentation/em_http_request_test.rb +89 -0
  153. data/test/instrumentation/excon_test.rb +231 -0
  154. data/test/instrumentation/faraday_test.rb +228 -0
  155. data/test/instrumentation/http_test.rb +143 -0
  156. data/test/instrumentation/httpclient_test.rb +320 -0
  157. data/test/instrumentation/memcache_test.rb +260 -0
  158. data/test/instrumentation/memcached_test.rb +229 -0
  159. data/test/instrumentation/mongo_v1_test.rb +479 -0
  160. data/test/instrumentation/mongo_v2_index_test.rb +124 -0
  161. data/test/instrumentation/mongo_v2_test.rb +584 -0
  162. data/test/instrumentation/mongo_v2_view_test.rb +435 -0
  163. data/test/instrumentation/moped_test.rb +517 -0
  164. data/test/instrumentation/rack_test.rb +165 -0
  165. data/test/instrumentation/redis_hashes_test.rb +268 -0
  166. data/test/instrumentation/redis_keys_test.rb +321 -0
  167. data/test/instrumentation/redis_lists_test.rb +310 -0
  168. data/test/instrumentation/redis_misc_test.rb +163 -0
  169. data/test/instrumentation/redis_sets_test.rb +296 -0
  170. data/test/instrumentation/redis_sortedsets_test.rb +328 -0
  171. data/test/instrumentation/redis_strings_test.rb +349 -0
  172. data/test/instrumentation/resque_test.rb +185 -0
  173. data/test/instrumentation/rest-client_test.rb +288 -0
  174. data/test/instrumentation/sequel_mysql2_test.rb +353 -0
  175. data/test/instrumentation/sequel_mysql_test.rb +334 -0
  176. data/test/instrumentation/sequel_pg_test.rb +336 -0
  177. data/test/instrumentation/sidekiq-client_test.rb +159 -0
  178. data/test/instrumentation/sidekiq-worker_test.rb +180 -0
  179. data/test/instrumentation/twitter-cassandra_test.rb +424 -0
  180. data/test/instrumentation/typhoeus_test.rb +284 -0
  181. data/test/jobs/delayed_job/db_worker_job.rb +29 -0
  182. data/test/jobs/delayed_job/error_worker_job.rb +10 -0
  183. data/test/jobs/delayed_job/remote_call_worker_job.rb +20 -0
  184. data/test/jobs/resque/db_worker_job.rb +29 -0
  185. data/test/jobs/resque/error_worker_job.rb +10 -0
  186. data/test/jobs/resque/remote_call_worker_job.rb +20 -0
  187. data/test/jobs/sidekiq/db_worker_job.rb +29 -0
  188. data/test/jobs/sidekiq/error_worker_job.rb +10 -0
  189. data/test/jobs/sidekiq/remote_call_worker_job.rb +20 -0
  190. data/test/minitest_helper.rb +276 -0
  191. data/test/mocked/curb_mocked_test.rb +311 -0
  192. data/test/mocked/excon_mocked_test.rb +166 -0
  193. data/test/mocked/faraday_mocked_test.rb +93 -0
  194. data/test/mocked/http_mocked_test.rb +129 -0
  195. data/test/mocked/httpclient_mocked_test.rb +245 -0
  196. data/test/mocked/rest_client_mocked_test.rb +103 -0
  197. data/test/mocked/typhoeus_mocked_test.rb +192 -0
  198. data/test/models/widget.rb +36 -0
  199. data/test/profiling/legacy_method_profiling_test.rb +201 -0
  200. data/test/profiling/method_profiling_test.rb +631 -0
  201. data/test/queues/delayed_job-client_test.rb +95 -0
  202. data/test/queues/delayed_job-worker_test.rb +91 -0
  203. data/test/reporter/reporter_test.rb +14 -0
  204. data/test/servers/delayed_job.rb +107 -0
  205. data/test/servers/rackapp_8101.rb +29 -0
  206. data/test/servers/rails3x_8140.rb +96 -0
  207. data/test/servers/rails4x_8140.rb +96 -0
  208. data/test/servers/rails5x_8140.rb +95 -0
  209. data/test/servers/rails5x_api_8150.rb +78 -0
  210. data/test/servers/sidekiq.rb +29 -0
  211. data/test/servers/sidekiq.yml +7 -0
  212. data/test/servers/sidekiq_initializer.rb +25 -0
  213. data/test/settings +0 -0
  214. data/test/support/auto_tracing_test.rb +50 -0
  215. data/test/support/backcompat_test.rb +276 -0
  216. data/test/support/config_test.rb +149 -0
  217. data/test/support/dnt_test.rb +98 -0
  218. data/test/support/init_report_test.rb +25 -0
  219. data/test/support/liboboe_settings_test.rb +110 -0
  220. data/test/support/logging_test.rb +130 -0
  221. data/test/support/noop_test.rb +88 -0
  222. data/test/support/sql_sanitize_test.rb +55 -0
  223. data/test/support/tracing_mode_test.rb +33 -0
  224. data/test/support/tvalias_test.rb +15 -0
  225. data/test/support/xtrace_test.rb +41 -0
  226. metadata +475 -0
@@ -0,0 +1,58 @@
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 v3
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, :appoptics
18
+ alias_method_chain :process_action, :appoptics
19
+ alias_method_chain :render, :appoptics
20
+ end
21
+ end
22
+
23
+ def process_with_appoptics(*args)
24
+ kvs = {
25
+ :Controller => self.class.name,
26
+ :Action => self.action_name,
27
+ }
28
+ request.env['appoptics_apm.controller'] = kvs[:Controller]
29
+ request.env['appoptics_apm.action'] = kvs[:Action]
30
+
31
+ trace('rails') do
32
+ process_without_appoptics(*args)
33
+ end
34
+ end
35
+
36
+ def process_action_with_appoptics(*args)
37
+ kvs = {
38
+ :Controller => self.class.name,
39
+ :Action => action_name,
40
+ }
41
+ request.env['appoptics_apm.controller'] = kvs[:Controller]
42
+ request.env['appoptics_apm.action'] = kvs[:Action]
43
+
44
+ return process_action_without_appoptics(*args) unless AppOpticsAPM.tracing?
45
+ begin
46
+ kvs[:Backtrace] = AppOpticsAPM::API.backtrace if AppOpticsAPM::Config[:action_controller][:collect_backtraces]
47
+ AppOpticsAPM::API.log(nil, 'info', kvs)
48
+
49
+ process_action_without_appoptics(*args)
50
+ rescue Exception
51
+ kvs[:Status] = 500
52
+ AppOpticsAPM::API.log(nil, 'info', kvs)
53
+ raise
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -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(nil, 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(nil, 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[:Controller]
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(nil, 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 'add_logging', 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,56 @@
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 == 2
7
+
8
+ AppOpticsAPM.logger.info '[appoptics_apm/loading] Instrumenting actionview' if AppOpticsAPM::Config[:verbose]
9
+
10
+ ActionView::Partials.module_eval do
11
+ alias :render_partial_without_appoptics :render_partial
12
+ def render_partial(options = {})
13
+ if options.key?(:partial) && options[:partial].is_a?(String)
14
+ entry_kvs = {}
15
+ begin
16
+ name = AppOpticsAPM::Util.prettify(options[:partial]) if options.is_a?(Hash)
17
+ entry_kvs[:FunctionName] = :render_partial
18
+ entry_kvs[:Class] = :Partials
19
+ entry_kvs[:Module] = :ActionView
20
+ entry_kvs[:File] = __FILE__
21
+ entry_kvs[:LineNumber] = __LINE__
22
+ rescue => e
23
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
24
+ end
25
+
26
+ AppOpticsAPM::API.profile(name, entry_kvs, AppOpticsAPM::Config[:action_view][:collect_backtraces]) do
27
+ render_partial_without_appoptics(options)
28
+ end
29
+ else
30
+ render_partial_without_appoptics(options)
31
+ end
32
+ end
33
+
34
+ alias :render_partial_collection_without_appoptics :render_partial_collection
35
+ def render_partial_collection(options = {})
36
+ entry_kvs = {}
37
+ begin
38
+ name = 'partial_collection'
39
+ entry_kvs[:FunctionName] = :render_partial_collection
40
+ entry_kvs[:Class] = :Partials
41
+ entry_kvs[:Module] = :ActionView
42
+ entry_kvs[:File] = __FILE__
43
+ entry_kvs[:LineNumber] = __LINE__
44
+ rescue => e
45
+ AppOpticsAPM.logger.debug "[appoptics_apm/debug] #{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" if AppOpticsAPM::Config[:verbose]
46
+ end
47
+
48
+ AppOpticsAPM::API.profile(name, entry_kvs, AppOpticsAPM::Config[:action_view][:collect_backtraces]) do
49
+ render_partial_collection_without_appoptics(options)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ # 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.adapter_name.downcase
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,28 @@
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_delete)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,30 @@
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_delete)
21
+
22
+ else
23
+ # ActiveRecord 3.0 and prior
24
+ AppOpticsAPM::Util.method_alias(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, :execute)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,120 @@
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
+ if ::Rails::VERSION::MAJOR == 2
24
+ config = ::Rails.configuration.database_configuration[::Rails.env]
25
+ else
26
+ config = ActiveRecord::Base.connection.instance_variable_get(:@config)
27
+ end
28
+
29
+ if config
30
+ opts[:Database] = config['database'] if config.key?('database')
31
+ opts[:RemoteHost] = config['host'] if config.key?('host')
32
+ adapter_name = config[:adapter]
33
+
34
+ case adapter_name
35
+ when /mysql/i
36
+ opts[:Flavor] = 'mysql'
37
+ when /postgres/i
38
+ opts[:Flavor] = 'postgresql'
39
+ end
40
+ end
41
+ rescue StandardError => e
42
+ AppOpticsAPM.logger.debug "Exception raised capturing ActiveRecord KVs: #{e.inspect}"
43
+ AppOpticsAPM.logger.debug e.backtrace.join('\n')
44
+ ensure
45
+ return opts
46
+ end
47
+
48
+ # We don't want to trace framework caches. Only instrument SQL that
49
+ # directly hits the database.
50
+ def ignore_payload?(name)
51
+ %w(SCHEMA EXPLAIN CACHE).include?(name.to_s) ||
52
+ (name && name.to_sym == :skip_logging) ||
53
+ name == 'ActiveRecord::SchemaMigration Load'
54
+ end
55
+
56
+ # def cfg
57
+ # @config
58
+ # end
59
+
60
+ def execute_with_appoptics(sql, name = nil)
61
+ if AppOpticsAPM.tracing? && !ignore_payload?(name)
62
+
63
+ opts = extract_trace_details(sql, name)
64
+ AppOpticsAPM::API.trace('activerecord', opts || {}) do
65
+ execute_without_appoptics(sql, name)
66
+ end
67
+ else
68
+ execute_without_appoptics(sql, name)
69
+ end
70
+ end
71
+
72
+ def exec_query_with_appoptics(sql, name = nil, binds = [])
73
+ if AppOpticsAPM.tracing? && !ignore_payload?(name)
74
+
75
+ opts = extract_trace_details(sql, name, binds)
76
+ AppOpticsAPM::API.trace('activerecord', opts || {}) do
77
+ exec_query_without_appoptics(sql, name, binds)
78
+ end
79
+ else
80
+ exec_query_without_appoptics(sql, name, binds)
81
+ end
82
+ end
83
+
84
+ def exec_delete_with_appoptics(sql, name = nil, binds = [])
85
+ if AppOpticsAPM.tracing? && !ignore_payload?(name)
86
+
87
+ opts = extract_trace_details(sql, name, binds)
88
+ AppOpticsAPM::API.trace('activerecord', opts || {}) do
89
+ exec_delete_without_appoptics(sql, name, binds)
90
+ end
91
+ else
92
+ exec_delete_without_appoptics(sql, name, binds)
93
+ end
94
+ end
95
+
96
+ def exec_insert_with_appoptics(sql, name = nil, binds = [], *args)
97
+ if AppOpticsAPM.tracing? && !ignore_payload?(name)
98
+
99
+ opts = extract_trace_details(sql, name, binds)
100
+ AppOpticsAPM::API.trace('activerecord', opts || {}) do
101
+ exec_insert_without_appoptics(sql, name, binds, *args)
102
+ end
103
+ else
104
+ exec_insert_without_appoptics(sql, name, binds, *args)
105
+ end
106
+ end
107
+
108
+ def begin_db_transaction_with_appoptics
109
+ if AppOpticsAPM.tracing?
110
+ AppOpticsAPM::API.trace('activerecord', { :Query => 'BEGIN', :Flavor => :mysql }) do
111
+ begin_db_transaction_without_appoptics
112
+ end
113
+ else
114
+ begin_db_transaction_without_appoptics
115
+ end
116
+ end
117
+ end # Utils
118
+ end
119
+ end
120
+ end