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,222 @@
1
+ # AppOpticsAPM Initializer (for the appoptics_apm gem)
2
+ # https://www.appoptics.com/
3
+ #
4
+ # More information on instrumenting Ruby applications can be found here:
5
+ # https://docs.appoptics.com/kb/apm_tracing/ruby/
6
+
7
+ if defined?(AppOpticsAPM::Config)
8
+
9
+ #
10
+ # Turn tracing on or off
11
+ #
12
+ # By default tracing is set to 'always', the other option is 'never'.
13
+ # 'always' means that sampling will be done according to the current
14
+ # sampling rate. 'never' means that there is no sampling.
15
+ #
16
+ AppOpticsAPM::Config[:tracing_mode] = :always
17
+
18
+ #
19
+ # Verbose output of instrumentation initialization
20
+ #
21
+ # AppOpticsAPM::Config[:verbose] = <%= @verbose %>
22
+ #
23
+
24
+ #
25
+ # Logging of incoming HTTP query args
26
+ #
27
+ # This optionally disables the logging of incoming URL request
28
+ # query args.
29
+ #
30
+ # This flag is global and currently only affects the Rack
31
+ # instrumentation which reports incoming request URLs and
32
+ # query args by default.
33
+ AppOpticsAPM::Config[:include_remote_url_params] = true
34
+
35
+ #
36
+ # Logging of outgoing HTTP query args
37
+ #
38
+ # This optionally disables the logging of query args of outgoing
39
+ # HTTP clients such as Net::HTTP, excon, typhoeus and others.
40
+ #
41
+ # This flag is global to all HTTP client instrumentation.
42
+ #
43
+ # To configure this on a per instrumentation basis, set this
44
+ # option to true and instead disable the instrumentation specific
45
+ # option <tt>log_args</tt>:
46
+ #
47
+ # AppOpticsAPM::Config[:nethttp][:log_args] = false
48
+ # AppOpticsAPM::Config[:excon][:log_args] = false
49
+ # AppOpticsAPM::Config[:typhoeus][:log_args] = true
50
+ #
51
+ AppOpticsAPM::Config[:include_url_query_params] = true
52
+
53
+ #
54
+ # Sanitize SQL Statements
55
+ #
56
+ # The AppOpticsAPM Ruby client has the ability to sanitize query literals
57
+ # from SQL statements. By default this is enabled. Disable to
58
+ # collect and report query literals to AppOpticsAPM.
59
+ #
60
+ # AppOpticsAPM::Config[:sanitize_sql] = true
61
+ #
62
+
63
+ # Do Not Trace
64
+ # These two values allow you to configure specific URL patterns to
65
+ # never be traced. By default, this is set to common static file
66
+ # extensions but you may want to customize this list for your needs.
67
+ #
68
+ # dnt_regexp and dnt_opts is passed to Regexp.new to create
69
+ # a regular expression object. That is then used to match against
70
+ # the incoming request path.
71
+ #
72
+ # The path string originates from the rack layer and is retrieved
73
+ # as follows:
74
+ #
75
+ # req = ::Rack::Request.new(env)
76
+ # path = URI.unescape(req.path)
77
+ #
78
+ # Usage:
79
+ # AppOpticsAPM::Config[:dnt_regexp] = "lobster$"
80
+ # AppOpticsAPM::Config[:dnt_opts] = Regexp::IGNORECASE
81
+ #
82
+ # This will ignore all requests that end with the string lobster
83
+ # regardless of case
84
+ #
85
+ # Requests with positive matches (non nil) will not be traced.
86
+ # See lib/appoptics_apm/util.rb: AppOpticsAPM::Util.static_asset?
87
+ #
88
+ # AppOpticsAPM::Config[:dnt_regexp] = "\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|svg|less)$"
89
+ # AppOpticsAPM::Config[:dnt_opts] = Regexp::IGNORECASE
90
+
91
+ #
92
+ # Blacklist urls
93
+ #
94
+ # This configuration is used by outbound calls. If the call
95
+ # goes to a blacklisted url then we won't add any
96
+ # tracing information to the headers.
97
+ #
98
+ # The list has to an array of strings, even if only one url is blacklisted
99
+ #
100
+ # Example: AppOpticsAPM::Config[:blacklist] = ['google.com']
101
+ #
102
+ # AppOpticsAPM::Config[:blacklist]
103
+ #
104
+
105
+ #
106
+ # Rails Exception Logging
107
+ #
108
+ # In Rails, raised exceptions with rescue handlers via
109
+ # <tt>rescue_from</tt> are not reported to the AppOptics
110
+ # dashboard by default. Setting this value to true will
111
+ # report all raised exception regardless.
112
+ #
113
+ # AppOpticsAPM::Config[:report_rescued_errors] = false
114
+ #
115
+
116
+ #
117
+ # Bunny Controller and Action
118
+ #
119
+ # The bunny (Rabbitmq) instrumentation can optionally report
120
+ # Controller and Action values to allow filtering of bunny
121
+ # message handling in # the UI. Use of Controller and Action
122
+ # for filters is temporary until the UI is updated with
123
+ # additional filters.
124
+ #
125
+ # These values identify which properties of
126
+ # Bunny::MessageProperties to report as Controller
127
+ # and Action. The defaults are to report :app_id (as
128
+ # Controller) and :type (as Action). If these values
129
+ # are not specified in the publish, then nothing
130
+ # will be reported here.
131
+ #
132
+ # AppOpticsAPM::Config[:bunnyconsumer][:controller] = :app_id
133
+ # AppOpticsAPM::Config[:bunnyconsumer][:action] = :type
134
+ #
135
+
136
+ #
137
+ # Resque Argument logging
138
+ #
139
+ # Set to true to enable Resque argument logging (Default: false)
140
+ #
141
+ # AppOpticsAPM::Config[:resqueworker][:log_args] = false
142
+ # AppOpticsAPM::Config[:resqueclient[:log_args] = false
143
+ #
144
+
145
+ #
146
+ # Enabling/Disabling Instrumentation
147
+ #
148
+ # If you're having trouble with one of the instrumentation libraries, they
149
+ # can be individually disabled here by setting the :enabled
150
+ # value to false:
151
+ #
152
+ # AppOpticsAPM::Config[:action_controller][:enabled] = true
153
+ # AppOpticsAPM::Config[:action_controller_api][:enabled] = true
154
+ # AppOpticsAPM::Config[:action_view][:enabled] = true
155
+ # AppOpticsAPM::Config[:active_record][:enabled] = true
156
+ # AppOpticsAPM::Config[:bunnyclient][:enabled] = true
157
+ # AppOpticsAPM::Config[:bunnyconsumer][:enabled] = true
158
+ # AppOpticsAPM::Config[:cassandra][:enabled] = true
159
+ # AppOpticsAPM::Config[:curb][:enabled] = true
160
+ # AppOpticsAPM::Config[:dalli][:enabled] = true
161
+ # AppOpticsAPM::Config[:delayed_jobclient][:enabled] = true
162
+ # AppOpticsAPM::Config[:delayed_jobworker][:enabled] = true
163
+ # AppOpticsAPM::Config[:em_http_request][:enabled] = true
164
+ # AppOpticsAPM::Config[:excon][:enabled] = true
165
+ # AppOpticsAPM::Config[:faraday][:enabled] = true
166
+ # AppOpticsAPM::Config[:grape][:enabled] = true
167
+ # AppOpticsAPM::Config[:httpclient][:enabled] = true
168
+ # AppOpticsAPM::Config[:memcache][:enabled] = true
169
+ # AppOpticsAPM::Config[:memcached][:enabled] = true
170
+ # AppOpticsAPM::Config[:mongo][:enabled] = true
171
+ # AppOpticsAPM::Config[:moped][:enabled] = true
172
+ # AppOpticsAPM::Config[:nethttp][:enabled] = true
173
+ # AppOpticsAPM::Config[:redis][:enabled] = true
174
+ # AppOpticsAPM::Config[:resqueclient][:enabled] = true
175
+ # AppOpticsAPM::Config[:resqueworker][:enabled] = true
176
+ # AppOpticsAPM::Config[:rest_client][:enabled] = true
177
+ # AppOpticsAPM::Config[:sequel][:enabled] = true
178
+ # AppOpticsAPM::Config[:sidekiqclient][:enabled] = true
179
+ # AppOpticsAPM::Config[:sidekiqworker][:enabled] = true
180
+ # AppOpticsAPM::Config[:typhoeus][:enabled] = true
181
+ #
182
+
183
+ #
184
+ # Enabling/Disabling Backtrace Collection
185
+ #
186
+ # Instrumentation can optionally collect backtraces as they collect
187
+ # performance metrics. Note that this has a negative impact on
188
+ # performance but can be useful when trying to locate the source of
189
+ # a certain call or operation.
190
+ #
191
+ # AppOpticsAPM::Config[:action_controller][:collect_backtraces] = true
192
+ # AppOpticsAPM::Config[:action_controller_api][:collect_backtraces] = true
193
+ # AppOpticsAPM::Config[:action_view][:collect_backtraces] = true
194
+ # AppOpticsAPM::Config[:active_record][:collect_backtraces] = true
195
+ # AppOpticsAPM::Config[:bunnyclient][:collect_backtraces] = true
196
+ # AppOpticsAPM::Config[:bunnyconsumer][:collect_backtraces] = true
197
+ # AppOpticsAPM::Config[:cassandra][:collect_backtraces] = true
198
+ # AppOpticsAPM::Config[:curb][:collect_backtraces] = true
199
+ # AppOpticsAPM::Config[:dalli][:collect_backtraces] = false
200
+ # AppOpticsAPM::Config[:delayed_jobclient][:collect_backtraces] = false
201
+ # AppOpticsAPM::Config[:delayed_jobworker][:collect_backtraces] = false
202
+ # AppOpticsAPM::Config[:em_http_request][:collect_backtraces] = true
203
+ # AppOpticsAPM::Config[:excon][:collect_backtraces] = false
204
+ # AppOpticsAPM::Config[:faraday][:collect_backtraces] = false
205
+ # AppOpticsAPM::Config[:grape][:collect_backtraces] = false
206
+ # AppOpticsAPM::Config[:httpclient][:collect_backtraces] = false
207
+ # AppOpticsAPM::Config[:memcache][:collect_backtraces] = false
208
+ # AppOpticsAPM::Config[:memcached][:collect_backtraces] = false
209
+ # AppOpticsAPM::Config[:mongo][:collect_backtraces] = true
210
+ # AppOpticsAPM::Config[:moped][:collect_backtraces] = true
211
+ # AppOpticsAPM::Config[:nethttp][:collect_backtraces] = true
212
+ # AppOpticsAPM::Config[:rack][:collect_backtraces] = true
213
+ # AppOpticsAPM::Config[:redis][:collect_backtraces] = false
214
+ # AppOpticsAPM::Config[:resqueclient][:collect_backtraces] = true
215
+ # AppOpticsAPM::Config[:resqueworker][:collect_backtraces] = true
216
+ # AppOpticsAPM::Config[:rest_client][:collect_backtraces] = true
217
+ # AppOpticsAPM::Config[:sequel][:collect_backtraces] = true
218
+ # AppOpticsAPM::Config[:sidekiqclient][:collect_backtraces] = true
219
+ # AppOpticsAPM::Config[:sidekiqworker][:collect_backtraces] = true
220
+ # AppOpticsAPM::Config[:typhoeus][:collect_backtraces] = false
221
+ #
222
+ end
data/ruby_setup.sh ADDED
@@ -0,0 +1,47 @@
1
+ #!/bin/bash
2
+
3
+ # used by run_tests_docker.sh
4
+ # call with:
5
+ # docker-compose run --service-ports ruby_appoptics /code/ruby-appoptics_apm/ruby_setup.sh <ruby-version> <gemfile> <true|false>
6
+ # docker-compose run --service-ports ruby_appoptics /code/ruby-appoptics_apm/ruby_setup.sh 2.4.1 gemfiles/libraries.gemfile
7
+
8
+ cd /code/ruby-appoptics_apm/
9
+
10
+ rbenv local $1
11
+ bundle install
12
+ bundle update
13
+ bundle exec rake fetch_ext_deps
14
+ bundle exec rake clean
15
+ bundle exec rake compile
16
+
17
+ # start postgres
18
+ service postgresql start
19
+
20
+ # start redis
21
+ service redis-server start
22
+
23
+ # start memcached
24
+ service memcached start
25
+
26
+ # mysql add table for tests
27
+ mysql -e 'create database travis_ci_test;' -h$MYSQL_HOST -p$MYSQL_ROOT_PASSWORD
28
+
29
+ bundle install --gemfile $2
30
+
31
+ export RVM_TEST=$1
32
+ export BUNDLE_GEMFILE=$2
33
+
34
+ # replicate stdout of tests to file in local log directory
35
+ export TEST_RUNS_TO_FILE=true
36
+
37
+ if [ "$3" == "true" ]; then
38
+ /bin/bash
39
+ # now run tests either with:
40
+ # bundle exec rake test TEST=test/instrumentation/curb_test.rb
41
+ # or
42
+ # bundle exec ruby -I test test/instrumentation/curb_test.rb -n test_obey_collect_backtraces_when_false
43
+ else
44
+ bundle exec rake test
45
+ fi
46
+
47
+ mysql -e 'drop database travis_ci_test;' -h$MYSQL_HOST -p$MYSQL_ROOT_PASSWORD
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+
3
+ # to build the image:
4
+ docker build -f Dockerfile -t buildgem .
5
+
6
+ # build the gems in the image
7
+ docker run --rm -v `pwd`:/code/ruby-appoptics_apm buildgem bash -l -c 'cd /code/ruby-appoptics_apm && ./build_gems.sh'
8
+
9
+ # save current rbenv setting and switch to 2.4.1 for the package_cloud commands
10
+ current_ruby=`rbenv local`
11
+ rbenv local 2.4.1
12
+
13
+ # prerequisite: package_cloud tocken needs to be in ~/.packagecloud
14
+
15
+ gem=`ls -dt1 appoptics_apm-[^pre]*.gem | head -1`
16
+
17
+ package_cloud push AppOptics/apm-instrumentation $gem
18
+
19
+ # restore ruby version
20
+ rbenv local $current_ruby
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # this runs all the tests on the current code base
4
+ # any edits take effect immediately
5
+ # test output is logged to log/test_runs.log
6
+ # make sure log/ and log/test_runs.log is writeable by docker
7
+
8
+ # `docker build -f Dockerfile -t ruby_appoptics .`
9
+ # (docker-compose will build it too if missing)
10
+ #
11
+ # `docker-compose up -d`
12
+ # or to rebuild ruby_appoptics
13
+ # `docker-compose up --build -d`
14
+
15
+ require 'yaml'
16
+ travis = YAML.load_file('.travis.yml')
17
+
18
+ matrix = []
19
+ travis['rvm'].each do |rvm|
20
+ travis['gemfile'].each do |gemfile|
21
+ matrix << { "rvm" => rvm, "gemfile" => gemfile }
22
+ end
23
+ end
24
+
25
+ matrix = matrix - travis['matrix']['exclude']
26
+
27
+ matrix.each do |args|
28
+ args['rvm'] = '1.9.3-p551' if args['rvm'] =~ /1.9.3/
29
+ `docker-compose run --rm --service-ports ruby_appoptics_apm /code/ruby-appoptics_apm/ruby_setup.sh #{args['rvm']} #{args['gemfile']}`
30
+ end
31
+
32
+ # `docker-compose down --rmi all`
@@ -0,0 +1,65 @@
1
+ #Micro Benchmarking
2
+
3
+ Work In Progress
4
+
5
+ In this folder there are samples for doing microbenchmarks.
6
+
7
+ They are in folders with names indicating which gemfile needs to be set, eg:
8
+ ```
9
+ export BUNDLE_GEMFILE=gemfiles/libraries.gemfile
10
+ bundle install
11
+ ```
12
+
13
+ The gems used are `benchmark-ips` and `benchmark-memory` to compare performance and memory usage between different
14
+ versions of code.
15
+
16
+ The variable `ENV['TEST_AB']` is used to define which version of code to run.
17
+
18
+ **!!! It is very important to remove `ENV['TEST_AB']` before commiting code !!!**
19
+
20
+ ###Example of setup for benchmarking:
21
+
22
+ The benchmarking code to be run:
23
+ ```
24
+ Benchmark.ips do |x|
25
+ x.config(:time => 20, :warmup => 20, :iterations => 3)
26
+ @conn = Bunny.new(@connection_params)
27
+ @conn.start
28
+ @channel = @conn.create_channel
29
+ @queue = @channel.queue("ao.ruby.test")
30
+ @exchange = @channel.topic("ao.ruby.topic.tests", :auto_delete => true)
31
+
32
+ x.report('bunny_pub_sampling_A') do
33
+ ENV['TEST_AB'] = 'A'
34
+ AppOpticsAPM.loaded = true
35
+ AppOpticsAPM::Config[:tracing_mode] = 'always'
36
+ AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
37
+
38
+ dostuff(@exchange)
39
+ end
40
+
41
+ x.report('bunny_pub_sampling_B') do
42
+ ENV['TEST_AB'] = 'B'
43
+ AppOpticsAPM.loaded = true
44
+ AppOpticsAPM::Config[:tracing_mode] = 'always'
45
+ AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
46
+
47
+ dostuff(@exchange)
48
+ end
49
+
50
+ x.compare!
51
+ end
52
+ ```
53
+ The code to be benchmarked:
54
+ ```
55
+ def basic_publish_with_appoptics(payload, exchange, routing_key, opts = {})
56
+ # If we're not tracing, just do a fast return.
57
+ return basic_publish_without_appoptics(payload, exchange, routing_key, opts) if !AppOpticsAPM.tracing? && ENV['TEST_AB'] == 'B'
58
+
59
+ begin
60
+ kvs = collect_channel_kvs
61
+ if exchange.respond_to?(:name)
62
+ kvs[:ExchangeName] = exchange.name
63
+ elsif exchange.respond_to?(:empty?) && !exchange.empty?
64
+ ...
65
+ ```
@@ -0,0 +1,54 @@
1
+ # Copyright (c) 2017 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'benchmark/ips'
5
+ require_relative '../minitest_helper'
6
+
7
+
8
+ # compare logging when testing for loaded versus tracing?
9
+ ENV['APPOPTICS_GEM_VERBOSE'] = 'false'
10
+
11
+ n = 1000
12
+
13
+ Benchmark.ips do |x|
14
+ x.config(:time => 10, :warmup => 2)
15
+
16
+ # x.report('tracing_f') do
17
+ # AppOpticsAPM.loaded = false
18
+ # AppOpticsAPM::Config[:tracing_mode] = 'never'
19
+ # AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
20
+ # n.times do
21
+ # AppOpticsAPM.tracing?
22
+ # end
23
+ # end
24
+ # x.report('tracing_n') do
25
+ # AppOpticsAPM.loaded = true
26
+ # AppOpticsAPM::Config[:tracing_mode] = 'never'
27
+ # AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
28
+ # n.times do
29
+ # AppOpticsAPM.tracing?
30
+ # end
31
+ # end
32
+
33
+ x.report('tracing_tf') do
34
+ AppOpticsAPM.loaded = true
35
+ AppOpticsAPM::Config[:tracing_mode] = 'always'
36
+ AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
37
+ n.times do
38
+ AppOpticsAPM.tracing?
39
+ end
40
+ end
41
+ x.report('tracing_tt') do
42
+ AppOpticsAPM.loaded = true
43
+ AppOpticsAPM::Config[:tracing_mode] = 'always'
44
+ AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F01')
45
+ n.times do
46
+ AppOpticsAPM.tracing?
47
+ AppOpticsAPM.tracing?
48
+ end
49
+ end
50
+
51
+ x.compare!
52
+ end
53
+
54
+
@@ -0,0 +1,69 @@
1
+ # Copyright (c) 2017 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'benchmark/ips'
5
+ require_relative '../../minitest_helper'
6
+
7
+
8
+ # compare logging when testing for loaded versus tracing?
9
+ ENV['APPOPTICS_GEM_VERBOSE'] = 'false'
10
+
11
+ ENV['APPOPTICS_RABBITMQ_SERVER'] = "127.0.0.1" unless ENV['APPOPTICS_RABBITMQ_SERVER']
12
+ ENV['APPOPTICS_RABBITMQ_PORT'] = "5672" unless ENV['APPOPTICS_RABBITMQ_PORT']
13
+ ENV['APPOPTICS_RABBITMQ_USERNAME'] = "guest" unless ENV['APPOPTICS_RABBITMQ_USERNAME']
14
+ ENV['APPOPTICS_RABBITMQ_PASSWORD'] = "guest" unless ENV['APPOPTICS_RABBITMQ_PASSWORD']
15
+ ENV['APPOPTICS_RABBITMQ_VHOST'] = "/" unless ENV['APPOPTICS_RABBITMQ_VHOST']
16
+
17
+ @connection_params = {}
18
+ @connection_params[:host] = ENV['APPOPTICS_RABBITMQ_SERVER']
19
+ @connection_params[:port] = ENV['APPOPTICS_RABBITMQ_PORT']
20
+ @connection_params[:vhost] = ENV['APPOPTICS_RABBITMQ_VHOST']
21
+ @connection_params[:user] = ENV['APPOPTICS_RABBITMQ_USERNAME']
22
+ @connection_params[:pass] = ENV['APPOPTICS_RABBITMQ_PASSWORD']
23
+
24
+ def dostuff(exchange)
25
+ # require 'ruby-prof'
26
+
27
+ # profile the code
28
+ # RubyProf.start
29
+
30
+ n = 100
31
+
32
+ n.times do
33
+ exchange.publish("The Tortoise and the Hare", :routing_key => @queue.name)
34
+ end
35
+
36
+ # result = RubyProf.stop
37
+ # print a flat profile to text
38
+ # printer = RubyProf::FlatPrinter.new(result)
39
+ # printer.print(STDOUT)
40
+ end
41
+
42
+
43
+ Benchmark.ips do |x|
44
+ x.config(:time => 20, :warmup => 20, :iterations => 3)
45
+ @conn = Bunny.new(@connection_params)
46
+ @conn.start
47
+ @channel = @conn.create_channel
48
+ @queue = @channel.queue("ao.ruby.test")
49
+ @exchange = @channel.topic("ao.ruby.topic.tests", :auto_delete => true)
50
+
51
+ x.report('bunny_pub_sampling_A') do
52
+ ENV['TEST_AB'] = 'A'
53
+ AppOpticsAPM.loaded = true
54
+ AppOpticsAPM::Config[:tracing_mode] = 'always'
55
+ AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
56
+
57
+ dostuff(@exchange)
58
+ end
59
+ x.report('bunny_pub_sampling_B') do
60
+ ENV['TEST_AB'] = 'B'
61
+ AppOpticsAPM.loaded = true
62
+ AppOpticsAPM::Config[:tracing_mode] = 'always'
63
+ AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
64
+
65
+ dostuff(@exchange)
66
+ end
67
+
68
+ x.compare!
69
+ end
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2017 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'benchmark/ips'
5
+ require 'benchmark/memory'
6
+ require_relative '../../minitest_helper'
7
+
8
+ # compare logging when testing for loaded versus tracing?
9
+ ENV['APPOPTICS_GEM_VERBOSE'] = 'false'
10
+ ENV['DBTYPE'] = "postgresql" unless ENV['DBTYPE']
11
+
12
+ def dostuff(uri)
13
+ n = 100
14
+ n.times do
15
+ Net::HTTP.get_response(uri)
16
+ end
17
+ end
18
+
19
+
20
+ Benchmark.memory do |x|
21
+ AppOpticsAPM::Config[:action_controller][:collect_backtraces] = false
22
+ # x.config(:time => 20, :warmup => 20, :iterations => 3)
23
+ uri = URI.parse('http://127.0.0.1:8140/hello/world')
24
+
25
+ x.report('controller_A') do
26
+ ENV['TEST_AB'] = 'A'
27
+ AppOpticsAPM.loaded = true
28
+ AppOpticsAPM::Config[:tracing_mode] = 'always'
29
+ AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
30
+
31
+ dostuff(uri)
32
+ end
33
+ x.report('controller_B') do
34
+ ENV['TEST_AB'] = 'B'
35
+ AppOpticsAPM.loaded = true
36
+ AppOpticsAPM::Config[:tracing_mode] = 'always'
37
+ AppOpticsAPM::Context.fromString('2B7435A9FE510AE4533414D425DADF4E180D2B4E3649E60702469DB05F00')
38
+
39
+ dostuff(uri)
40
+ end
41
+
42
+ x.compare!
43
+ end
@@ -0,0 +1,33 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'grape'
5
+
6
+ class Wrapper < Grape::API
7
+ class GrapeSimple < Grape::API
8
+ rescue_from :all do |e|
9
+ error_response({ message: "rescued from #{e.class.name}" })
10
+ end
11
+
12
+ get '/json_endpoint' do
13
+ present({ :test => true })
14
+ end
15
+
16
+ get "/break" do
17
+ raise Exception.new("This should have http status code 500!")
18
+ end
19
+
20
+ get "/error" do
21
+ error!("This is a error with 'error'!")
22
+ end
23
+
24
+ get "/breakstring" do
25
+ raise "This should have http status code 500!"
26
+ end
27
+ end
28
+ end
29
+
30
+ class GrapeNested < Grape::API
31
+ mount Wrapper::GrapeSimple
32
+ end
33
+
@@ -0,0 +1,80 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'grape'
5
+
6
+ class GrapeSimple < Grape::API
7
+ rescue_from :all do |e|
8
+ error_response({ message: "rescued from #{e.class.name}" })
9
+ end
10
+
11
+ get '/index' do
12
+ present( )
13
+ end
14
+
15
+ get '/json_endpoint' do
16
+ present({ :test => true })
17
+ end
18
+
19
+ get "/break" do
20
+ raise Exception.new("This should have http status code 500!")
21
+ end
22
+
23
+ get "/error" do
24
+ error!("This is an error with 'error'!")
25
+ end
26
+
27
+ get "/breakstring" do
28
+ raise "This should have http status code 500!"
29
+ end
30
+
31
+ resource :employee_data do
32
+ desc "List all Employee"
33
+ get do
34
+ present({ :employee_data => "all"})
35
+ end
36
+
37
+ get ':id' do
38
+ present({ :employee_data => "Employee ##{params[:id]}"})
39
+ end
40
+
41
+ desc "create a new employee"
42
+ # This takes care of parameter validation
43
+ params do
44
+ requires :name, type: String
45
+ requires :address, type:String
46
+ requires :age, type:Integer
47
+ end
48
+ post do
49
+ present({ :employee_data => "Creating employee: #{params[:name]}, #{params[:address]}, #{params[:age]}"})
50
+ end
51
+
52
+ desc "update an employee address"
53
+ params do
54
+ requires :id, type: String
55
+ requires :address, type:String
56
+ end
57
+ put ':id' do
58
+ present({ :employee_data => "Updating employee ##{params[:id]}: #{params[:address]}"})
59
+ end
60
+
61
+ desc "delete an employee"
62
+ params do
63
+ requires :id, type: String
64
+ end
65
+
66
+ delete ':id' do
67
+ present({ :employee_data => "Deleting employee ##{params[:id]}"})
68
+ end
69
+
70
+ route_param :id do
71
+ resource :nested do
72
+ desc "try a nested route"
73
+ get ':child' do
74
+ present({ :employee_data => "Nested employee data for ##{params[:id]}: #{params[:child]}"})
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+