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,78 @@
1
+ ##
2
+ # Copyright (c) 2016 SolarWinds, LLC.
3
+ # All rights reserved.
4
+
5
+ # This is a Rails API stack that launches on a background
6
+ # thread and listens on port 8150.
7
+ #
8
+ if ENV['DBTYPE'] == 'mysql2'
9
+ AppOpticsAPM::Test.set_mysql2_env
10
+ elsif ENV['DBTYPE'] == 'postgresql'
11
+ AppOpticsAPM::Test.set_postgresql_env
12
+ else
13
+ AppOpticsAPM.logger.warn "Unidentified DBTYPE: #{ENV['DBTYPE']}" unless ENV['DBTYPE'] == "postgresql"
14
+ AppOpticsAPM.logger.debug "Defaulting to postgres DB for background Rails server."
15
+ AppOpticsAPM::Test.set_postgresql_env
16
+ end
17
+
18
+ require "rails"
19
+ require "active_model/railtie"
20
+ require "active_job/railtie"
21
+ require "active_record/railtie"
22
+ require "action_controller/railtie"
23
+ require "action_mailer/railtie"
24
+ require "action_view/railtie"
25
+ require "action_cable/engine"
26
+ require "rails/test_unit/railtie"
27
+
28
+ require 'rack/handler/puma'
29
+ require File.expand_path(File.dirname(__FILE__) + '/../models/widget')
30
+
31
+ AppOpticsAPM.logger.info "[appoptics_apm/info] Starting background utility rails app on localhost:8150."
32
+
33
+ ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
34
+
35
+ unless ActiveRecord::Base.connection.table_exists? 'widgets'
36
+ ActiveRecord::Migration.run(CreateWidgets)
37
+ end
38
+
39
+ module Rails50APIStack
40
+ class Application < Rails::Application
41
+ config.api_only = true
42
+
43
+ routes.append do
44
+ get "/monkey/hello" => "monkey#hello"
45
+ get "/monkey/error" => "monkey#error"
46
+ end
47
+
48
+ config.cache_classes = true
49
+ config.eager_load = false
50
+ config.active_support.deprecation = :stderr
51
+ config.middleware.delete Rack::Lock
52
+ config.middleware.delete ActionDispatch::Flash
53
+ config.secret_token = "48837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk"
54
+ config.secret_key_base = "2049671-96803948"
55
+ end
56
+ end
57
+
58
+ #################################################
59
+ # Controllers
60
+ #################################################
61
+
62
+ class MonkeyController < ActionController::API
63
+ def hello
64
+ render :plain => {:Response => "Hello API!"}.to_json, content_type: 'application/json'
65
+ end
66
+
67
+ def error
68
+ raise "Rails API fake error from controller"
69
+ end
70
+ end
71
+
72
+ Rails50APIStack::Application.initialize!
73
+
74
+ Thread.new do
75
+ Rack::Handler::Puma.run(Rails50APIStack::Application.to_app, {:Host => '127.0.0.1', :Port => 8150})
76
+ end
77
+
78
+ sleep(2)
@@ -0,0 +1,29 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ # We configure and launch Sidekiq in a background
5
+ # thread here.
6
+ #
7
+ require 'sidekiq/cli'
8
+
9
+ AppOpticsAPM.logger.info "[appoptics_apm/servers] Starting up background Sidekiq."
10
+
11
+ options = []
12
+ arguments = ""
13
+ options << ["-r", Dir.pwd + "/test/servers/sidekiq_initializer.rb"]
14
+ options << ["-q", "critical,20", "-q", "default"]
15
+ options << ["-c", "10"]
16
+ options << ["-P", "/tmp/sidekiq_#{Process.pid}.pid"]
17
+
18
+ options.flatten.each do |x|
19
+ arguments += " #{x}"
20
+ end
21
+
22
+ AppOpticsAPM.logger.debug "[appoptics_apm/servers] sidekiq #{arguments}"
23
+
24
+ Thread.new do
25
+ system("OBOE_GEM_TEST=true sidekiq #{arguments}")
26
+ end
27
+
28
+ # Allow Sidekiq to boot up
29
+ sleep 10
@@ -0,0 +1,7 @@
1
+ ---
2
+ :concurrency: 2
3
+ :pidfile: tmp/pids/sidekiq.pid
4
+ :queues:
5
+ - default
6
+ - [critical, 2]
7
+ - [low, 1]
@@ -0,0 +1,25 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ # This file is used to initialize the background Sidekiq
5
+ # process launched in our test suite.
6
+ #
7
+ ENV['BUNDLE_GEMFILE'] = Dir.pwd + "/gemfiles/libraries.gemfile"
8
+
9
+ require 'rubygems'
10
+ require 'bundler/setup'
11
+ require_relative '../jobs/sidekiq/db_worker_job'
12
+ require_relative '../jobs/sidekiq/remote_call_worker_job'
13
+ require_relative '../jobs/sidekiq/error_worker_job'
14
+
15
+ ENV["RACK_ENV"] = "test"
16
+ ENV["APPOPTICS_GEM_TEST"] = "true"
17
+ ENV["APPOPTICS_GEM_VERBOSE"] = "true"
18
+
19
+ Bundler.require(:default, :test)
20
+
21
+ # Configure AppOpticsAPM
22
+ AppOpticsAPM::Config[:tracing_mode] = "always"
23
+ AppOpticsAPM::Config[:sample_rate] = 1000000
24
+ AppOpticsAPM.logger.level = Logger::DEBUG
25
+
data/test/settings ADDED
Binary file
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'minitest_helper'
5
+
6
+ class AutoTraceTest < Minitest::Test
7
+ def setup
8
+ @tm = AppOpticsAPM::Config[:tracing_mode]
9
+ end
10
+
11
+ def teardown
12
+ AppOpticsAPM::Config[:tracing_mode] = @tm
13
+ end
14
+
15
+ def test_trace_when_default_tm_dj
16
+ AppOpticsAPM::API.start_trace('delayed_job-worker') do
17
+ AppOpticsAPM.tracing?.must_equal true
18
+ end
19
+ end
20
+
21
+ def test_trace_when_default_tm_sidekiq
22
+ AppOpticsAPM::API.start_trace('sidekiq-worker') do
23
+ AppOpticsAPM.tracing?.must_equal true
24
+ end
25
+ end
26
+
27
+ def test_trace_when_default_tm_resque
28
+ AppOpticsAPM::API.start_trace('resque-worker') do
29
+ AppOpticsAPM.tracing?.must_equal true
30
+ end
31
+ end
32
+
33
+ def test_trace_when_default_tm_rabbitmq
34
+ AppOpticsAPM::API.start_trace('rabbitmq-consumer') do
35
+ AppOpticsAPM.tracing?.must_equal true
36
+ end
37
+ end
38
+
39
+ def test_dont_trace_when_never
40
+ AppOpticsAPM::Config[:tracing_mode] = :never
41
+
42
+ AppOpticsAPM::API.start_trace('delayed_job-worker') do
43
+ AppOpticsAPM.tracing?.must_equal false
44
+ end
45
+
46
+ AppOpticsAPM::API.start_trace('asdf') do
47
+ AppOpticsAPM.tracing?.must_equal false
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,276 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'minitest_helper'
5
+
6
+ describe "BackwardCompatibility" do
7
+
8
+ it 'should still export to Oboe::Ruby' do
9
+ defined?(::Oboe::Ruby).must_equal "constant"
10
+ end
11
+
12
+ it 'should still respond to Oboe::Config' do
13
+ @verbose = Oboe::Config[:verbose]
14
+ @dalli_enabled = Oboe::Config[:dalli][:enabled]
15
+ @tm = Oboe::Config[:tracing_mode]
16
+ @sr = Oboe::Config[:sample_rate]
17
+
18
+ Oboe::Config[:verbose] = true
19
+ Oboe::Config[:verbose].must_equal true
20
+ Oboe::Config.verbose.must_equal true
21
+ AppOpticsAPM::Config[:verbose].must_equal true
22
+ AppOpticsAPM::Config.verbose.must_equal true
23
+
24
+ Oboe::Config[:dalli][:enabled] = false
25
+ Oboe::Config[:dalli][:enabled].must_equal false
26
+ AppOpticsAPM::Config[:dalli][:enabled].must_equal false
27
+
28
+ Oboe::Config[:sample_rate] = 8e5
29
+ Oboe::Config.sample_rate.must_equal 8e5
30
+ AppOpticsAPM::Config.sample_rate.must_equal 8e5
31
+
32
+ Oboe::Config[:tracing_mode] = 'always'
33
+ Oboe::Config.tracing_mode.must_equal :always
34
+ AppOpticsAPM::Config.tracing_mode.must_equal :always
35
+
36
+ Oboe::Config[:sample_rate] = @sr
37
+ Oboe::Config[:tracing_mode] = @tm
38
+ Oboe::Config[:dalli][:enabled] = @dalli_enabled
39
+ Oboe::Config[:verbose] = @verbose
40
+ end
41
+
42
+ it 'should still support Oboe::API.log calls' do
43
+ clear_all_traces
44
+
45
+ Oboe::API.log_start('rack', nil, {})
46
+ Oboe::API.log_end('rack')
47
+
48
+ traces = get_all_traces
49
+ traces.count.must_equal 2
50
+ end
51
+
52
+ it 'should still support Oboe::API.trace calls' do
53
+ clear_all_traces
54
+
55
+ Oboe::API.start_trace('api_test', '', {}) do
56
+ sleep 1
57
+ end
58
+
59
+ traces = get_all_traces
60
+ traces.count.must_equal 2
61
+
62
+ validate_outer_layers(traces, 'api_test')
63
+ end
64
+
65
+ it 'should still support Oboe::API.profile'do
66
+ clear_all_traces
67
+
68
+ Oboe::API.start_trace('outer_profile_test') do
69
+ Oboe::API.profile('profile_test', {}, false) do
70
+ sleep 1
71
+ end
72
+ end
73
+
74
+ traces = get_all_traces
75
+ traces.count.must_equal 4
76
+ end
77
+
78
+ # Pasted in from test/profiling/method_test.rb
79
+ # Modified to use OboeMethodProfiling
80
+ describe "OboeMethodProfiling" do
81
+ before do
82
+ clear_all_traces
83
+ # Conditionally Undefine TestWorker
84
+ # http://stackoverflow.com/questions/11503558/how-to-undefine-class-in-ruby
85
+ Object.send(:remove_const, :TestWorker) if defined?(TestWorker)
86
+ end
87
+
88
+ it 'should be loaded, defined and ready' do
89
+ defined?(::OboeMethodProfiling).wont_match nil
90
+ end
91
+
92
+ it 'should trace Class methods' do
93
+ class TestWorker
94
+ def self.do_work
95
+ sleep 1
96
+ end
97
+
98
+ class << self
99
+ include OboeMethodProfiling
100
+ profile_method :do_work, 'do_work'
101
+ end
102
+ end
103
+
104
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
105
+ # Call the profiled class method
106
+ TestWorker.do_work
107
+ end
108
+
109
+ traces = get_all_traces
110
+ traces.count.must_equal 4
111
+
112
+ validate_outer_layers(traces, 'method_profiling')
113
+
114
+ kvs = {}
115
+ kvs["Label"] = 'profile_entry'
116
+ kvs["Language"] = "ruby"
117
+ kvs["ProfileName"] = "do_work"
118
+ kvs["FunctionName"] = "do_work"
119
+ kvs["Class"] = "TestWorker"
120
+
121
+ validate_event_keys(traces[1], kvs)
122
+
123
+ traces[1].has_key?("Layer").must_equal false
124
+ traces[1].has_key?("File").must_equal true
125
+ traces[1].has_key?("LineNumber").must_equal true
126
+
127
+ kvs.clear
128
+ kvs["Label"] = "profile_exit"
129
+ kvs["Language"] = "ruby"
130
+ kvs["ProfileName"] = "do_work"
131
+
132
+ validate_event_keys(traces[2], kvs)
133
+ traces[2].has_key?("Layer").must_equal false
134
+ end
135
+
136
+ it 'should trace Instance methods' do
137
+ class TestWorker
138
+ def do_work
139
+ sleep 1
140
+ end
141
+
142
+ include OboeMethodProfiling
143
+ profile_method :do_work, 'do_work'
144
+ end
145
+
146
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
147
+ # Call the profiled class method
148
+ tw = TestWorker.new
149
+ tw.do_work
150
+ end
151
+
152
+ traces = get_all_traces
153
+ traces.count.must_equal 4
154
+
155
+ validate_outer_layers(traces, 'method_profiling')
156
+
157
+ kvs = {}
158
+ kvs["Label"] = 'profile_entry'
159
+ kvs["Language"] = "ruby"
160
+ kvs["ProfileName"] = "do_work"
161
+ kvs["FunctionName"] = "do_work"
162
+ kvs["Class"] = "TestWorker"
163
+
164
+ validate_event_keys(traces[1], kvs)
165
+
166
+ traces[1].has_key?("Layer").must_equal false
167
+ traces[1].has_key?("File").must_equal true
168
+ traces[1].has_key?("LineNumber").must_equal true
169
+
170
+ kvs.clear
171
+ kvs["Label"] = "profile_exit"
172
+ kvs["Language"] = "ruby"
173
+ kvs["ProfileName"] = "do_work"
174
+
175
+ validate_event_keys(traces[2], kvs)
176
+ traces[2].has_key?("Layer").must_equal false
177
+ end
178
+
179
+ it 'should trace Module class methods' do
180
+ module TestWorker
181
+ def self.do_work
182
+ sleep 1
183
+ end
184
+
185
+ class << self
186
+ include OboeMethodProfiling
187
+ profile_method :do_work, 'do_work'
188
+ end
189
+ end
190
+
191
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
192
+ # Call the profiled class method
193
+ TestWorker.do_work
194
+ end
195
+
196
+ traces = get_all_traces
197
+ traces.count.must_equal 4
198
+ validate_outer_layers(traces, 'method_profiling')
199
+
200
+ kvs = {}
201
+ kvs["Label"] = 'profile_entry'
202
+ kvs["Language"] = "ruby"
203
+ kvs["ProfileName"] = "do_work"
204
+ kvs["FunctionName"] = "do_work"
205
+ kvs["Module"] = "TestWorker"
206
+
207
+ validate_event_keys(traces[1], kvs)
208
+
209
+ traces[1].has_key?("Layer").must_equal false
210
+ traces[1].has_key?("File").must_equal true
211
+ traces[1].has_key?("LineNumber").must_equal true
212
+
213
+ kvs.clear
214
+ kvs["Label"] = "profile_exit"
215
+ kvs["Language"] = "ruby"
216
+ kvs["ProfileName"] = "do_work"
217
+
218
+ validate_event_keys(traces[2], kvs)
219
+ traces[2].has_key?("Layer").must_equal false
220
+ end
221
+
222
+ it 'should not store arguments and return value by default' do
223
+ class TestWorker
224
+ def self.do_work(_s, _i, _a, _h)
225
+ sleep 1
226
+ return "the zebra is loose"
227
+ end
228
+
229
+ class << self
230
+ include OboeMethodProfiling
231
+ # Default call method
232
+ profile_method :do_work, 'do_work'
233
+ end
234
+ end
235
+
236
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
237
+ # Call the profiled class method
238
+ TestWorker.do_work('String Argument', 203984, ["1", "2", 3], { :color => :black })
239
+ end
240
+
241
+ traces = get_all_traces
242
+ traces.count.must_equal 4
243
+
244
+ traces[1].has_key?("Args").must_equal false
245
+ traces[2].has_key?("ReturnValue").must_equal false
246
+ end
247
+
248
+ it 'should store arguments and return value when asked' do
249
+ class TestWorker
250
+ def self.do_work(_s, _i, _a, _h)
251
+ sleep 1
252
+ return "the zebra is loose"
253
+ end
254
+
255
+ class << self
256
+ include OboeMethodProfiling
257
+ profile_method :do_work, 'do_work', true, true
258
+ end
259
+ end
260
+
261
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
262
+ # Call the profiled class method
263
+ TestWorker.do_work('String Argument', 203984, ["1", "2", 3], { :color => :black })
264
+ end
265
+
266
+ traces = get_all_traces
267
+ traces.count.must_equal 4
268
+
269
+ traces[1].has_key?("Args").must_equal true
270
+ traces[1]["Args"].must_equal "\"String Argument\"\n203984\n[\"1\", \"2\", 3]\n{:color=>:black}\n"
271
+
272
+ traces[2].has_key?("ReturnValue").must_equal true
273
+ traces[2]["ReturnValue"].must_equal "\"the zebra is loose\"\n"
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,149 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'minitest_helper'
5
+
6
+ describe "AppOpticsAPM::Config" do
7
+ after do
8
+ # Set back to always trace mode
9
+ AppOpticsAPM::Config[:tracing_mode] = "always"
10
+ AppOpticsAPM::Config[:sample_rate] = 1000000
11
+ end
12
+
13
+ it 'should have the correct default values' do
14
+ # Reset AppOpticsAPM::Config to defaults
15
+ AppOpticsAPM::Config.initialize
16
+
17
+ # FIXME: We set the APPOPTICS_GEM_VERBOSE env for the
18
+ # ____ test suite so this assertion is not going to fly
19
+ #
20
+ # AppOpticsAPM::Config[:verbose].must_equal false
21
+
22
+ # TODO: Is there anything we should test here?
23
+ end
24
+
25
+ it 'should have the correct instrumentation defaults' do
26
+ # Reset AppOpticsAPM::Config to defaults
27
+ AppOpticsAPM::Config.initialize
28
+
29
+ instrumentation = AppOpticsAPM::Config.instrumentation
30
+
31
+ # Verify the number of individual instrumentations
32
+ instrumentation.count.must_equal 30
33
+
34
+ AppOpticsAPM::Config[:action_controller][:enabled].must_equal true
35
+ AppOpticsAPM::Config[:action_controller_api][:enabled].must_equal true
36
+ AppOpticsAPM::Config[:action_view][:enabled].must_equal true
37
+ AppOpticsAPM::Config[:active_record][:enabled].must_equal true
38
+ AppOpticsAPM::Config[:bunnyclient][:enabled].must_equal true
39
+ AppOpticsAPM::Config[:bunnyconsumer][:enabled].must_equal true
40
+ AppOpticsAPM::Config[:cassandra][:enabled].must_equal true
41
+ AppOpticsAPM::Config[:curb][:enabled].must_equal true
42
+ AppOpticsAPM::Config[:dalli][:enabled].must_equal true
43
+ AppOpticsAPM::Config[:delayed_jobclient][:enabled].must_equal true
44
+ AppOpticsAPM::Config[:delayed_jobworker][:enabled].must_equal true
45
+ AppOpticsAPM::Config[:em_http_request][:enabled].must_equal false
46
+ AppOpticsAPM::Config[:excon][:enabled].must_equal true
47
+ AppOpticsAPM::Config[:faraday][:enabled].must_equal true
48
+ AppOpticsAPM::Config[:grape][:enabled].must_equal true
49
+ AppOpticsAPM::Config[:httpclient][:enabled].must_equal true
50
+ AppOpticsAPM::Config[:nethttp][:enabled].must_equal true
51
+ AppOpticsAPM::Config[:memcached][:enabled].must_equal true
52
+ AppOpticsAPM::Config[:memcache][:enabled].must_equal true
53
+ AppOpticsAPM::Config[:mongo][:enabled].must_equal true
54
+ AppOpticsAPM::Config[:moped][:enabled].must_equal true
55
+ AppOpticsAPM::Config[:rack][:enabled].must_equal true
56
+ AppOpticsAPM::Config[:redis][:enabled].must_equal true
57
+ AppOpticsAPM::Config[:resqueclient][:enabled].must_equal true
58
+ AppOpticsAPM::Config[:resqueworker][:enabled].must_equal true
59
+ AppOpticsAPM::Config[:rest_client][:enabled].must_equal true
60
+ AppOpticsAPM::Config[:sequel][:enabled].must_equal true
61
+ AppOpticsAPM::Config[:sidekiqclient][:enabled].must_equal true
62
+ AppOpticsAPM::Config[:sidekiqworker][:enabled].must_equal true
63
+ AppOpticsAPM::Config[:typhoeus][:enabled].must_equal true
64
+
65
+ AppOpticsAPM::Config[:action_controller][:log_args].must_equal true
66
+ AppOpticsAPM::Config[:action_controller_api][:log_args].must_equal true
67
+ AppOpticsAPM::Config[:action_view][:log_args].must_equal true
68
+ AppOpticsAPM::Config[:active_record][:log_args].must_equal true
69
+ AppOpticsAPM::Config[:bunnyclient][:log_args].must_equal true
70
+ AppOpticsAPM::Config[:bunnyconsumer][:log_args].must_equal true
71
+ AppOpticsAPM::Config[:cassandra][:log_args].must_equal true
72
+ AppOpticsAPM::Config[:curb][:log_args].must_equal true
73
+ AppOpticsAPM::Config[:dalli][:log_args].must_equal true
74
+ AppOpticsAPM::Config[:delayed_jobclient][:log_args].must_equal true
75
+ AppOpticsAPM::Config[:delayed_jobworker][:log_args].must_equal true
76
+ AppOpticsAPM::Config[:em_http_request][:log_args].must_equal true
77
+ AppOpticsAPM::Config[:excon][:log_args].must_equal true
78
+ AppOpticsAPM::Config[:faraday][:log_args].must_equal true
79
+ AppOpticsAPM::Config[:grape][:log_args].must_equal true
80
+ AppOpticsAPM::Config[:httpclient][:log_args].must_equal true
81
+ AppOpticsAPM::Config[:nethttp][:log_args].must_equal true
82
+ AppOpticsAPM::Config[:memcached][:log_args].must_equal true
83
+ AppOpticsAPM::Config[:memcache][:log_args].must_equal true
84
+ AppOpticsAPM::Config[:mongo][:log_args].must_equal true
85
+ AppOpticsAPM::Config[:moped][:log_args].must_equal true
86
+ AppOpticsAPM::Config[:rack][:log_args].must_equal true
87
+ AppOpticsAPM::Config[:redis][:log_args].must_equal true
88
+ AppOpticsAPM::Config[:resqueclient][:log_args].must_equal true
89
+ AppOpticsAPM::Config[:resqueworker][:log_args].must_equal true
90
+ AppOpticsAPM::Config[:rest_client][:log_args].must_equal true
91
+ AppOpticsAPM::Config[:sequel][:log_args].must_equal true
92
+ AppOpticsAPM::Config[:sidekiqclient][:log_args].must_equal true
93
+ AppOpticsAPM::Config[:sidekiqworker][:log_args].must_equal true
94
+ AppOpticsAPM::Config[:typhoeus][:log_args].must_equal true
95
+
96
+ AppOpticsAPM::Config[:blacklist].is_a?(Array).must_equal true
97
+
98
+ AppOpticsAPM::Config[:dnt_regexp].must_equal '\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|otf|eot|ttf|woff|woff2|svg|less)(\?.+){0,1}$'
99
+ AppOpticsAPM::Config[:dnt_opts].must_equal Regexp::IGNORECASE
100
+
101
+ AppOpticsAPM::Config[:sanitize_sql].must_equal true
102
+ end
103
+
104
+ def test_should_obey_globals
105
+ # Reset AppOpticsAPM::Config to defaults
106
+ AppOpticsAPM::Config.initialize
107
+
108
+ http_clients = AppOpticsAPM::Config.http_clients
109
+
110
+ # Restore these at the end
111
+ @url_query_params = AppOpticsAPM::Config[:include_url_query_params]
112
+ @remote_url_params = AppOpticsAPM::Config[:include_remote_url_params]
113
+
114
+ # After setting global options, the per instrumentation
115
+ # equivalents should follow suit.
116
+
117
+ #
118
+ # :include_remote_url_params
119
+ #
120
+
121
+ # Check defaults
122
+ AppOpticsAPM::Config[:include_remote_url_params].must_equal true
123
+ http_clients.each do |i|
124
+ AppOpticsAPM::Config[i][:log_args].must_equal true
125
+ end
126
+
127
+ # Check obedience
128
+ AppOpticsAPM::Config[:include_remote_url_params] = false
129
+ http_clients.each do |i|
130
+ AppOpticsAPM::Config[i][:log_args].must_equal false
131
+ end
132
+
133
+ #
134
+ # :include_url_query_params
135
+ #
136
+
137
+ # Check default
138
+ AppOpticsAPM::Config[:include_url_query_params].must_equal true
139
+ AppOpticsAPM::Config[:rack][:log_args].must_equal true
140
+
141
+ # Check obedience
142
+ AppOpticsAPM::Config[:include_url_query_params] = false
143
+ AppOpticsAPM::Config[:rack][:log_args].must_equal false
144
+
145
+ # Restore the previous values
146
+ AppOpticsAPM::Config[:include_url_query_params] = @url_query_params
147
+ AppOpticsAPM::Config[:include_remote_url_params] = @remote_url_params
148
+ end
149
+ end