oneapm_rpm 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +30 -0
  3. data/.rubocop.yml +725 -0
  4. data/Gemfile +3 -0
  5. data/Guardfile +7 -0
  6. data/LICENSE +1 -0
  7. data/README.md +3 -0
  8. data/config/cert/cacert.pem +1177 -0
  9. data/config/database.yml +5 -0
  10. data/lib/initializers/goliath.rb +11 -0
  11. data/lib/initializers/other.rb +1 -0
  12. data/lib/initializers/rails.rb +15 -0
  13. data/lib/one_apm/agent.rb +253 -0
  14. data/lib/one_apm/agent/agent.rb +283 -0
  15. data/lib/one_apm/agent/agent/connect.rb +175 -0
  16. data/lib/one_apm/agent/agent/container_data_manager.rb +218 -0
  17. data/lib/one_apm/agent/agent/forkable_dispatcher_functions.rb +96 -0
  18. data/lib/one_apm/agent/agent/helpers.rb +45 -0
  19. data/lib/one_apm/agent/agent/start.rb +226 -0
  20. data/lib/one_apm/agent/agent/start_worker_thread.rb +148 -0
  21. data/lib/one_apm/agent/busy_calculator.rb +115 -0
  22. data/lib/one_apm/agent/cross_app/cross_app_monitor.rb +181 -0
  23. data/lib/one_apm/agent/cross_app/cross_app_tracing.rb +336 -0
  24. data/lib/one_apm/agent/database.rb +308 -0
  25. data/lib/one_apm/agent/database/active_record_helper.rb +80 -0
  26. data/lib/one_apm/agent/database/obfuscation_helpers.rb +76 -0
  27. data/lib/one_apm/agent/database/obfuscator.rb +78 -0
  28. data/lib/one_apm/agent/database/postgres_explain_obfuscator.rb +45 -0
  29. data/lib/one_apm/agent/datastores.rb +175 -0
  30. data/lib/one_apm/agent/datastores/metric_helper.rb +83 -0
  31. data/lib/one_apm/agent/datastores/mongo.rb +27 -0
  32. data/lib/one_apm/agent/datastores/mongo/metric_translator.rb +189 -0
  33. data/lib/one_apm/agent/datastores/mongo/obfuscator.rb +37 -0
  34. data/lib/one_apm/agent/datastores/mongo/statement_formatter.rb +51 -0
  35. data/lib/one_apm/agent/event/event_listener.rb +40 -0
  36. data/lib/one_apm/agent/event/event_loop.rb +191 -0
  37. data/lib/one_apm/agent/event/worker_loop.rb +97 -0
  38. data/lib/one_apm/agent/harvester.rb +48 -0
  39. data/lib/one_apm/agent/inbound_request_monitor.rb +30 -0
  40. data/lib/one_apm/agent/javascript_instrumentor.rb +186 -0
  41. data/lib/one_apm/agent/pipe/pipe_channel_manager.rb +275 -0
  42. data/lib/one_apm/agent/pipe/pipe_service.rb +81 -0
  43. data/lib/one_apm/agent/sampler.rb +55 -0
  44. data/lib/one_apm/agent/sampler_collection.rb +65 -0
  45. data/lib/one_apm/agent/samplers/cpu_sampler.rb +49 -0
  46. data/lib/one_apm/agent/samplers/delayed_job_sampler.rb +109 -0
  47. data/lib/one_apm/agent/samplers/memory_sampler.rb +144 -0
  48. data/lib/one_apm/agent/samplers/object_sampler.rb +22 -0
  49. data/lib/one_apm/agent/samplers/vm_sampler.rb +124 -0
  50. data/lib/one_apm/agent/synthetics_monitor.rb +48 -0
  51. data/lib/one_apm/agent/threading/agent_thread.rb +74 -0
  52. data/lib/one_apm/agent/threading/backtrace_node.rb +133 -0
  53. data/lib/one_apm/agent/threading/backtrace_service.rb +259 -0
  54. data/lib/one_apm/agent/threading/thread_profile.rb +155 -0
  55. data/lib/one_apm/collector/collector/helper.rb +139 -0
  56. data/lib/one_apm/collector/collector/http_connection.rb +254 -0
  57. data/lib/one_apm/collector/collector/server_methods.rb +71 -0
  58. data/lib/one_apm/collector/collector_service.rb +123 -0
  59. data/lib/one_apm/collector/commands/agent_command.rb +17 -0
  60. data/lib/one_apm/collector/commands/thread_profiler_session.rb +108 -0
  61. data/lib/one_apm/collector/commands/xray_session.rb +53 -0
  62. data/lib/one_apm/collector/commands/xray_session_collection.rb +156 -0
  63. data/lib/one_apm/collector/containers/agent_command_router.rb +153 -0
  64. data/lib/one_apm/collector/containers/custom_event_aggregator.rb +94 -0
  65. data/lib/one_apm/collector/containers/error_collector.rb +349 -0
  66. data/lib/one_apm/collector/containers/sql_sampler.rb +331 -0
  67. data/lib/one_apm/collector/containers/stats_engine.rb +34 -0
  68. data/lib/one_apm/collector/containers/transaction_event_aggregator.rb +249 -0
  69. data/lib/one_apm/collector/containers/transaction_sampler.rb +352 -0
  70. data/lib/one_apm/collector/containers/utilization_data.rb +36 -0
  71. data/lib/one_apm/collector/stats_engine/gc_profiler.rb +106 -0
  72. data/lib/one_apm/collector/stats_engine/metric_stats.rb +243 -0
  73. data/lib/one_apm/collector/stats_engine/stats_hash.rb +105 -0
  74. data/lib/one_apm/configuration.rb +429 -0
  75. data/lib/one_apm/configuration/autostart.rb +41 -0
  76. data/lib/one_apm/configuration/default_source.rb +1026 -0
  77. data/lib/one_apm/configuration/environment_source.rb +113 -0
  78. data/lib/one_apm/configuration/high_security_source.rb +56 -0
  79. data/lib/one_apm/configuration/manual_source.rb +13 -0
  80. data/lib/one_apm/configuration/server_source.rb +60 -0
  81. data/lib/one_apm/configuration/yaml_source.rb +134 -0
  82. data/lib/one_apm/errors/agent_errors.rb +26 -0
  83. data/lib/one_apm/errors/internal_agent_error.rb +16 -0
  84. data/lib/one_apm/errors/noticed_error.rb +79 -0
  85. data/lib/one_apm/frameworks/external.rb +15 -0
  86. data/lib/one_apm/frameworks/rails.rb +103 -0
  87. data/lib/one_apm/frameworks/rails3.rb +37 -0
  88. data/lib/one_apm/frameworks/rails4.rb +21 -0
  89. data/lib/one_apm/frameworks/ruby.rb +21 -0
  90. data/lib/one_apm/frameworks/sinatra.rb +12 -0
  91. data/lib/one_apm/inst/3rd/active_merchant.rb +35 -0
  92. data/lib/one_apm/inst/3rd/acts_as_solr.rb +70 -0
  93. data/lib/one_apm/inst/3rd/authlogic.rb +23 -0
  94. data/lib/one_apm/inst/3rd/sunspot.rb +31 -0
  95. data/lib/one_apm/inst/background_job/active_job.rb +88 -0
  96. data/lib/one_apm/inst/background_job/delayed_job.rb +52 -0
  97. data/lib/one_apm/inst/background_job/delayed_job_injection.rb +8 -0
  98. data/lib/one_apm/inst/background_job/resque.rb +107 -0
  99. data/lib/one_apm/inst/background_job/sidekiq.rb +64 -0
  100. data/lib/one_apm/inst/dispatcher/passenger.rb +25 -0
  101. data/lib/one_apm/inst/dispatcher/rainbows.rb +23 -0
  102. data/lib/one_apm/inst/framework/grape.rb +94 -0
  103. data/lib/one_apm/inst/framework/padrino.rb +30 -0
  104. data/lib/one_apm/inst/framework/sinatra.rb +185 -0
  105. data/lib/one_apm/inst/framework/sinatra/ignorer.rb +50 -0
  106. data/lib/one_apm/inst/framework/sinatra/transaction_namer.rb +54 -0
  107. data/lib/one_apm/inst/http_clients/curb.rb +189 -0
  108. data/lib/one_apm/inst/http_clients/excon.rb +70 -0
  109. data/lib/one_apm/inst/http_clients/excon/connection.rb +31 -0
  110. data/lib/one_apm/inst/http_clients/excon/middleware.rb +55 -0
  111. data/lib/one_apm/inst/http_clients/httpclient.rb +44 -0
  112. data/lib/one_apm/inst/http_clients/net.rb +34 -0
  113. data/lib/one_apm/inst/http_clients/typhoeus.rb +76 -0
  114. data/lib/one_apm/inst/nosql/memcache.rb +134 -0
  115. data/lib/one_apm/inst/nosql/mongo.rb +126 -0
  116. data/lib/one_apm/inst/nosql/mongo_moped.rb +85 -0
  117. data/lib/one_apm/inst/nosql/redis.rb +83 -0
  118. data/lib/one_apm/inst/orm/active_record.rb +99 -0
  119. data/lib/one_apm/inst/orm/active_record_4.rb +28 -0
  120. data/lib/one_apm/inst/orm/data_mapper.rb +180 -0
  121. data/lib/one_apm/inst/orm/sequel.rb +47 -0
  122. data/lib/one_apm/inst/rack.rb +38 -0
  123. data/lib/one_apm/inst/rack/rack.rb +44 -0
  124. data/lib/one_apm/inst/rack/rack_builder.rb +51 -0
  125. data/lib/one_apm/inst/rails/action_controller.rb +118 -0
  126. data/lib/one_apm/inst/rails/action_web_service.rb +44 -0
  127. data/lib/one_apm/inst/rails/errors.rb +43 -0
  128. data/lib/one_apm/inst/rails3/action_controller.rb +172 -0
  129. data/lib/one_apm/inst/rails3/errors.rb +43 -0
  130. data/lib/one_apm/inst/rails4/action_controller.rb +27 -0
  131. data/lib/one_apm/inst/rails4/action_controller_subscriber.rb +121 -0
  132. data/lib/one_apm/inst/rails4/action_view.rb +23 -0
  133. data/lib/one_apm/inst/rails4/action_view_subscriber.rb +93 -0
  134. data/lib/one_apm/inst/rails4/active_record_subscriber.rb +96 -0
  135. data/lib/one_apm/inst/rails4/errors.rb +42 -0
  136. data/lib/one_apm/inst/rails_middleware.rb +40 -0
  137. data/lib/one_apm/inst/support/evented_subscriber.rb +98 -0
  138. data/lib/one_apm/inst/support/ignore_actions.rb +39 -0
  139. data/lib/one_apm/inst/support/queue_time.rb +76 -0
  140. data/lib/one_apm/inst/transaction_base.rb +405 -0
  141. data/lib/one_apm/logger/agent_logger.rb +206 -0
  142. data/lib/one_apm/logger/audit_logger.rb +78 -0
  143. data/lib/one_apm/logger/memory_logger.rb +50 -0
  144. data/lib/one_apm/logger/null_logger.rb +19 -0
  145. data/lib/one_apm/metrics/metric_data.rb +72 -0
  146. data/lib/one_apm/metrics/metric_spec.rb +82 -0
  147. data/lib/one_apm/metrics/stats.rb +173 -0
  148. data/lib/one_apm/probe.rb +16 -0
  149. data/lib/one_apm/probe/framework_loader.rb +53 -0
  150. data/lib/one_apm/probe/instance_methods.rb +105 -0
  151. data/lib/one_apm/probe/instrumentation.rb +60 -0
  152. data/lib/one_apm/rack/browser_monitoring.rb +144 -0
  153. data/lib/one_apm/rack/middleware_base.rb +27 -0
  154. data/lib/one_apm/rack/middleware_hooks.rb +17 -0
  155. data/lib/one_apm/rack/middleware_tracing.rb +81 -0
  156. data/lib/one_apm/rack/middleware_wrapper.rb +86 -0
  157. data/lib/one_apm/support/chained_call.rb +15 -0
  158. data/lib/one_apm/support/coerce.rb +81 -0
  159. data/lib/one_apm/support/collection_helper.rb +79 -0
  160. data/lib/one_apm/support/dotted_hash.rb +45 -0
  161. data/lib/one_apm/support/encoders.rb +34 -0
  162. data/lib/one_apm/support/environment_report.rb +127 -0
  163. data/lib/one_apm/support/event_buffer.rb +82 -0
  164. data/lib/one_apm/support/event_buffer/sampled_buffer.rb +45 -0
  165. data/lib/one_apm/support/event_buffer/sized_buffer.rb +21 -0
  166. data/lib/one_apm/support/event_buffer/synthetics_event_buffer.rb +40 -0
  167. data/lib/one_apm/support/helper.rb +49 -0
  168. data/lib/one_apm/support/hostname.rb +13 -0
  169. data/lib/one_apm/support/http_clients/curb_wrappers.rb +65 -0
  170. data/lib/one_apm/support/http_clients/excon_wrappers.rb +63 -0
  171. data/lib/one_apm/support/http_clients/httpclient_wrappers.rb +61 -0
  172. data/lib/one_apm/support/http_clients/net_http_wrappers.rb +48 -0
  173. data/lib/one_apm/support/http_clients/typhoeus_wrappers.rb +73 -0
  174. data/lib/one_apm/support/http_clients/uri_util.rb +39 -0
  175. data/lib/one_apm/support/json_marshaller.rb +68 -0
  176. data/lib/one_apm/support/json_wrapper.rb +130 -0
  177. data/lib/one_apm/support/language_support.rb +142 -0
  178. data/lib/one_apm/support/library_detection.rb +119 -0
  179. data/lib/one_apm/support/local_environment.rb +196 -0
  180. data/lib/one_apm/support/marshaller.rb +62 -0
  181. data/lib/one_apm/support/method_tracer.rb +334 -0
  182. data/lib/one_apm/support/method_tracer/helpers.rb +92 -0
  183. data/lib/one_apm/support/method_tracer/traced_method_stack.rb +103 -0
  184. data/lib/one_apm/support/obfuscator.rb +47 -0
  185. data/lib/one_apm/support/okjson.rb +601 -0
  186. data/lib/one_apm/support/parameter_filtering.rb +35 -0
  187. data/lib/one_apm/support/rules_engine.rb +56 -0
  188. data/lib/one_apm/support/rules_engine/replacement_rule.rb +80 -0
  189. data/lib/one_apm/support/rules_engine/segment_terms_rule.rb +46 -0
  190. data/lib/one_apm/support/server.rb +11 -0
  191. data/lib/one_apm/support/supported_versions.rb +257 -0
  192. data/lib/one_apm/support/system_info.rb +211 -0
  193. data/lib/one_apm/support/timer_lib.rb +29 -0
  194. data/lib/one_apm/support/version_number.rb +51 -0
  195. data/lib/one_apm/support/vm.rb +30 -0
  196. data/lib/one_apm/support/vm/jruby_vm.rb +38 -0
  197. data/lib/one_apm/support/vm/monotonic_gc_profiler.rb +43 -0
  198. data/lib/one_apm/support/vm/mri_vm.rb +85 -0
  199. data/lib/one_apm/support/vm/rubinius_vm.rb +129 -0
  200. data/lib/one_apm/support/vm/snapshot.rb +18 -0
  201. data/lib/one_apm/transaction.rb +336 -0
  202. data/lib/one_apm/transaction/class_methods.rb +132 -0
  203. data/lib/one_apm/transaction/instance_helpers.rb +82 -0
  204. data/lib/one_apm/transaction/metric_constants.rb +42 -0
  205. data/lib/one_apm/transaction/sample_buffer/force_persist_sample_buffer.rb +21 -0
  206. data/lib/one_apm/transaction/sample_buffer/slowest_sample_buffer.rb +21 -0
  207. data/lib/one_apm/transaction/sample_buffer/synthetics_sample_buffer.rb +21 -0
  208. data/lib/one_apm/transaction/sample_buffer/transaction_sample_buffer.rb +101 -0
  209. data/lib/one_apm/transaction/sample_buffer/xray_sample_buffer.rb +60 -0
  210. data/lib/one_apm/transaction/segment.rb +193 -0
  211. data/lib/one_apm/transaction/segment_summary.rb +51 -0
  212. data/lib/one_apm/transaction/thread_local_access.rb +73 -0
  213. data/lib/one_apm/transaction/transaction_analysis.rb +78 -0
  214. data/lib/one_apm/transaction/transaction_apdex.rb +20 -0
  215. data/lib/one_apm/transaction/transaction_cpu.rb +22 -0
  216. data/lib/one_apm/transaction/transaction_finish_append.rb +67 -0
  217. data/lib/one_apm/transaction/transaction_ignore.rb +33 -0
  218. data/lib/one_apm/transaction/transaction_jruby_functions.rb +40 -0
  219. data/lib/one_apm/transaction/transaction_metrics.rb +53 -0
  220. data/lib/one_apm/transaction/transaction_name.rb +90 -0
  221. data/lib/one_apm/transaction/transaction_namer.rb +49 -0
  222. data/lib/one_apm/transaction/transaction_sample.rb +204 -0
  223. data/lib/one_apm/transaction/transaction_sample_builder.rb +168 -0
  224. data/lib/one_apm/transaction/transaction_state.rb +149 -0
  225. data/lib/one_apm/transaction/transaction_summary.rb +28 -0
  226. data/lib/one_apm/transaction/transaction_synthetics.rb +40 -0
  227. data/lib/one_apm/transaction/transaction_timings.rb +54 -0
  228. data/lib/one_apm/version.rb +13 -0
  229. data/lib/oneapm_rpm.rb +16 -0
  230. data/lib/sequel/extensions/oneapm_instrumentation.rb +84 -0
  231. data/lib/sequel/plugins/oneapm_instrumentation.rb +66 -0
  232. data/oneapm.yml +135 -0
  233. data/oneapm_rpm.gemspec +58 -0
  234. metadata +474 -0
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ LibraryDetection.defer do
4
+ named :httpclient
5
+
6
+ HTTPCLIENT_MINIMUM_VERSION = '2.2.0'
7
+
8
+ depends_on do
9
+ defined?(HTTPClient) && defined?(HTTPClient::VERSION)
10
+ end
11
+
12
+ depends_on do
13
+ minimum_supported_version = OneApm::VersionNumber.new(HTTPCLIENT_MINIMUM_VERSION)
14
+ current_version = OneApm::VersionNumber.new(HTTPClient::VERSION)
15
+
16
+ current_version >= minimum_supported_version
17
+ end
18
+
19
+ executes do
20
+ ::OneApm::Agent.logger.info 'Installing HTTPClient instrumentation'
21
+ require 'one_apm/agent/cross_app/cross_app_tracing'
22
+ require 'one_apm/support/http_clients/httpclient_wrappers'
23
+ end
24
+
25
+ executes do
26
+ class HTTPClient
27
+ def do_get_block_with_oneapm(req, proxy, conn, &block)
28
+ wrapped_request = OneApm::Support::HTTPClients::HTTPClientRequest.new(req)
29
+
30
+ response = nil
31
+ ::OneApm::Agent::CrossAppTracing.tl_trace_http_request(wrapped_request) do
32
+ do_get_block_without_oneapm(req, proxy, conn, &block)
33
+ response = conn.pop
34
+ conn.push response
35
+ ::OneApm::Support::HTTPClients::HTTPClientResponse.new(response)
36
+ end
37
+ response
38
+ end
39
+
40
+ alias do_get_block_without_oneapm do_get_block
41
+ alias do_get_block do_get_block_with_oneapm
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ LibraryDetection.defer do
4
+ named :net_http
5
+
6
+ depends_on do
7
+ defined?(Net) && defined?(Net::HTTP)
8
+ end
9
+
10
+ executes do
11
+ ::OneApm::Agent.logger.info 'Installing Net instrumentation'
12
+ require 'one_apm/agent/cross_app/cross_app_tracing'
13
+ require 'one_apm/support/http_clients/net_http_wrappers'
14
+ end
15
+
16
+ executes do
17
+ class Net::HTTP
18
+ def request_with_oneapm_trace(request, *args, &block)
19
+ wrapped_request = OneApm::Support::HTTPClients::NetHTTPRequest.new(self, request)
20
+
21
+ OneApm::Agent::CrossAppTracing.tl_trace_http_request( wrapped_request ) do
22
+ # RUBY-1244 Disable further tracing in request to avoid double
23
+ # counting if connection wasn't started (which calls request again).
24
+ OneApm::Agent.disable_all_tracing do
25
+ request_without_oneapm_trace( request, *args, &block )
26
+ end
27
+ end
28
+ end
29
+
30
+ alias request_without_oneapm_trace request
31
+ alias request request_with_oneapm_trace
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+
3
+ LibraryDetection.defer do
4
+ named :typhoeus
5
+
6
+ depends_on do
7
+ defined?(Typhoeus) && defined?(Typhoeus::VERSION)
8
+ end
9
+
10
+ depends_on do
11
+ OneApm::Agent::Instrumentation::TyphoeusTracing.is_supported_version?
12
+ end
13
+
14
+ executes do
15
+ ::OneApm::Agent.logger.info 'Installing Typhoeus instrumentation'
16
+ require 'one_apm/agent/cross_app/cross_app_tracing'
17
+ require 'one_apm/support/http_clients/typhoeus_wrappers'
18
+ end
19
+
20
+ # Basic request tracing
21
+ executes do
22
+ Typhoeus.before do |request|
23
+ OneApm::Agent::Instrumentation::TyphoeusTracing.trace(request)
24
+
25
+ # Ensure that we always return a truthy value from the before block,
26
+ # otherwise Typhoeus will bail out of the instrumentation.
27
+ true
28
+ end
29
+ end
30
+
31
+ # Apply single TT node for Hydra requests until async support
32
+ executes do
33
+ class Typhoeus::Hydra
34
+ include OneApm::Support::MethodTracer
35
+
36
+ def run_with_oneapm(*args)
37
+ trace_execution_scoped("External/Multiple/Typhoeus::Hydra/run") do
38
+ run_without_oneapm(*args)
39
+ end
40
+ end
41
+
42
+ alias run_without_oneapm run
43
+ alias run run_with_oneapm
44
+ end
45
+ end
46
+ end
47
+
48
+
49
+ module OneApm::Agent::Instrumentation::TyphoeusTracing
50
+
51
+ EARLIEST_VERSION = OneApm::VersionNumber.new("0.5.3")
52
+
53
+ def self.is_supported_version?
54
+ OneApm::VersionNumber.new(Typhoeus::VERSION) >= OneApm::Agent::Instrumentation::TyphoeusTracing::EARLIEST_VERSION
55
+ end
56
+
57
+ def self.request_is_hydra_enabled?(request)
58
+ request.respond_to?(:hydra) && request.hydra
59
+ end
60
+
61
+ def self.trace(request)
62
+ state = OneApm::TransactionState.tl_get
63
+ if state.is_execution_traced? && !request_is_hydra_enabled?(request)
64
+ wrapped_request = ::OneApm::Support::HTTPClients::TyphoeusHTTPRequest.new(request)
65
+ t0 = Time.now
66
+ segment = ::OneApm::Agent::CrossAppTracing.start_trace(state, t0, wrapped_request)
67
+ callback = Proc.new do
68
+ wrapped_response = ::OneApm::Support::HTTPClients::TyphoeusHTTPResponse.new(request.response)
69
+ ::OneApm::Agent::CrossAppTracing.finish_trace(state, t0, segment, wrapped_request, wrapped_response)
70
+ end
71
+ request.on_complete.unshift(callback)
72
+ end
73
+ rescue => e
74
+ OneApm::Agent.logger.error("Exception during trace setup for Typhoeus request", e)
75
+ end
76
+ end
@@ -0,0 +1,134 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/agent/datastores/metric_helper'
4
+
5
+ module OneApm
6
+ module Agent
7
+ module Instrumentation
8
+ module Memcache
9
+ module_function
10
+
11
+ def enabled?
12
+ !::OneApm::Agent.config[:disable_memcache]
13
+ end
14
+
15
+ METHODS = [:get, :get_multi, :set, :add, :incr, :decr, :delete, :replace, :append,
16
+ :prepend, :cas, :single_get, :multi_get, :single_cas, :multi_cas]
17
+
18
+ def supported_methods_for(client_class, methods)
19
+ methods.select do |method_name|
20
+ client_class.method_defined?(method_name) || client_class.private_method_defined?(method_name)
21
+ end
22
+ end
23
+
24
+ def instrument_methods(client_class, requested_methods = METHODS)
25
+ supported_methods_for(client_class, requested_methods).each do |method_name|
26
+
27
+ visibility = OneApm::Helper.instance_method_visibility client_class, method_name
28
+ method_name_without = :"#{method_name}_without_oneapm_trace"
29
+
30
+ client_class.class_eval do
31
+ alias_method method_name_without, method_name
32
+
33
+ define_method method_name do |*args, &block|
34
+ metrics = Datastores::MetricHelper.metrics_for("Memcached", method_name)
35
+
36
+ OneApm::Support::MethodTracer.trace_execution_scoped(metrics) do
37
+ t0 = Time.now
38
+ begin
39
+ send method_name_without, *args, &block
40
+ ensure
41
+ if OneApm::Agent.config[:capture_memcache_keys]
42
+ OneApm::Agent.instance.transaction_sampler.notice_nosql(args.first.inspect, (Time.now - t0).to_f) rescue nil
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ send visibility, method_name
49
+ send visibility, method_name_without
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ LibraryDetection.defer do
60
+ named :memcache_client
61
+
62
+ depends_on do
63
+ OneApm::Agent::Instrumentation::Memcache.enabled?
64
+ end
65
+
66
+ depends_on do
67
+ defined?(::MemCache)
68
+ end
69
+
70
+ executes do
71
+ ::OneApm::Agent.logger.info 'Installing Memcached instrumentation for memcache-client gem'
72
+ OneApm::Agent::Instrumentation::Memcache.instrument_methods(::MemCache)
73
+ end
74
+ end
75
+
76
+ LibraryDetection.defer do
77
+ named :memcached
78
+
79
+ depends_on do
80
+ OneApm::Agent::Instrumentation::Memcache.enabled?
81
+ end
82
+
83
+ depends_on do
84
+ defined?(::Memcached)
85
+ end
86
+
87
+ executes do
88
+ ::OneApm::Agent.logger.info 'Installing Memcached instrumentation for memcached gem'
89
+ ::OneApm::Agent::Instrumentation::Memcache.instrument_methods(::Memcached)
90
+ end
91
+ end
92
+
93
+ LibraryDetection.defer do
94
+ named :dalli
95
+
96
+ depends_on do
97
+ OneApm::Agent::Instrumentation::Memcache.enabled?
98
+ end
99
+
100
+ depends_on do
101
+ defined?(::Dalli::Client)
102
+ end
103
+
104
+ executes do
105
+ ::OneApm::Agent.logger.info 'Installing Memcache instrumentation for dalli gem'
106
+ ::OneApm::Agent::Instrumentation::Memcache.instrument_methods(::Dalli::Client)
107
+ end
108
+ end
109
+
110
+ LibraryDetection.defer do
111
+ named :dalli_cas_client
112
+
113
+ depends_on do
114
+ OneApm::Agent::Instrumentation::Memcache.enabled?
115
+ end
116
+
117
+ depends_on do
118
+ # These CAS client methods are only optionally defined if users require
119
+ # dalli/cas/client. Use a separate dependency block so it can potentially
120
+ # re-evaluate after they've done that require.
121
+ defined?(::Dalli::Client) &&
122
+ ::OneApm::Agent::Instrumentation::Memcache.supported_methods_for(::Dalli::Client,
123
+ CAS_CLIENT_METHODS).any?
124
+ end
125
+
126
+ CAS_CLIENT_METHODS = [:get_cas, :get_multi_cas, :set_cas, :replace_cas,
127
+ :delete_cas]
128
+
129
+ executes do
130
+ ::OneApm::Agent.logger.info 'Installing Dalli CAS Client Memcache instrumentation'
131
+ ::OneApm::Agent::Instrumentation::Memcache.instrument_methods(::Dalli::Client,
132
+ CAS_CLIENT_METHODS)
133
+ end
134
+ end
@@ -0,0 +1,126 @@
1
+ # encoding: utf-8
2
+
3
+ LibraryDetection.defer do
4
+ named :mongo
5
+
6
+ depends_on do
7
+ defined?(::Mongo)
8
+ end
9
+
10
+ depends_on do
11
+ require 'one_apm/agent/datastores/mongo'
12
+ OneApm::Agent::Datastores::Mongo.is_supported_version?
13
+ end
14
+
15
+ executes do
16
+ OneApm::Agent.logger.info 'Installing Mongo instrumentation'
17
+ install_mongo_instrumentation
18
+ end
19
+
20
+ def install_mongo_instrumentation
21
+ require 'one_apm/agent/datastores/mongo/metric_translator'
22
+ require 'one_apm/agent/datastores/mongo/statement_formatter'
23
+
24
+ hook_instrument_methods
25
+ instrument_save
26
+ instrument_ensure_index
27
+ end
28
+
29
+ def hook_instrument_methods
30
+ hook_instrument_method(::Mongo::Collection)
31
+ hook_instrument_method(::Mongo::Connection)
32
+ hook_instrument_method(::Mongo::Cursor)
33
+ hook_instrument_method(::Mongo::CollectionWriter) if defined?(::Mongo::CollectionWriter)
34
+ end
35
+
36
+ def hook_instrument_method(target_class)
37
+ target_class.class_eval do
38
+ include OneApm::Support::MethodTracer
39
+
40
+ # It's key that this method eats all exceptions, as it rests between the
41
+ # Mongo operation the user called and us returning them the data. Be safe!
42
+ def one_apm_notice_statement(t0, payload, name)
43
+ statement = OneApm::Agent::Datastores::Mongo::StatementFormatter.format(payload, name)
44
+ if statement
45
+ OneApm::Agent.instance.transaction_sampler.notice_nosql_statement(statement, (Time.now - t0).to_f)
46
+ end
47
+ rescue => e
48
+ OneApm::Agent.logger.debug("Exception during Mongo statement gathering", e)
49
+ end
50
+
51
+ def one_apm_generate_metrics(operation, payload = nil)
52
+ payload ||= { :collection => self.name, :database => self.db.name }
53
+ OneApm::Agent::Datastores::Mongo::MetricTranslator.metrics_for(operation, payload)
54
+ end
55
+
56
+ def instrument_with_one_apm_trace(name, payload = {}, &block)
57
+ metrics = one_apm_generate_metrics(name, payload)
58
+
59
+ trace_execution_scoped(metrics) do
60
+ t0 = Time.now
61
+
62
+ result = OneApm::Agent.disable_all_tracing do
63
+ instrument_without_one_apm_trace(name, payload, &block)
64
+ end
65
+
66
+ one_apm_notice_statement(t0, payload, name)
67
+ result
68
+ end
69
+ end
70
+
71
+ alias_method :instrument_without_one_apm_trace, :instrument
72
+ alias_method :instrument, :instrument_with_one_apm_trace
73
+ end
74
+ end
75
+
76
+ def instrument_save
77
+ ::Mongo::Collection.class_eval do
78
+ def save_with_one_apm_trace(doc, opts = {}, &block)
79
+ metrics = one_apm_generate_metrics(:save)
80
+ trace_execution_scoped(metrics) do
81
+ t0 = Time.now
82
+
83
+ result = OneApm::Agent.disable_all_tracing do
84
+ save_without_one_apm_trace(doc, opts, &block)
85
+ end
86
+
87
+ one_apm_notice_statement(t0, doc, :save)
88
+ result
89
+ end
90
+ end
91
+
92
+ alias_method :save_without_one_apm_trace, :save
93
+ alias_method :save, :save_with_one_apm_trace
94
+ end
95
+ end
96
+
97
+ def instrument_ensure_index
98
+ ::Mongo::Collection.class_eval do
99
+ def ensure_index_with_one_apm_trace(spec, opts = {}, &block)
100
+ metrics = one_apm_generate_metrics(:ensureIndex)
101
+ trace_execution_scoped(metrics) do
102
+ t0 = Time.now
103
+
104
+ result = OneApm::Agent.disable_all_tracing do
105
+ ensure_index_without_one_apm_trace(spec, opts, &block)
106
+ end
107
+
108
+ spec = case spec
109
+ when Array
110
+ Hash[spec]
111
+ when String, Symbol
112
+ { spec => 1 }
113
+ else
114
+ spec.dup
115
+ end
116
+
117
+ one_apm_notice_statement(t0, spec, :ensureIndex)
118
+ result
119
+ end
120
+ end
121
+
122
+ alias_method :ensure_index_without_one_apm_trace, :ensure_index
123
+ alias_method :ensure_index, :ensure_index_with_one_apm_trace
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/support/method_tracer'
4
+ require 'one_apm/agent/datastores'
5
+
6
+ LibraryDetection.defer do
7
+ @name = :mongo_moped
8
+
9
+ depends_on do
10
+ defined?(::Moped) && !OneApm::Agent.config[:disable_mongo_moped]
11
+ end
12
+
13
+ executes do
14
+ OneApm::Agent.logger.info 'Installing Mongo Moped instrumentation'
15
+ end
16
+
17
+ executes do
18
+ Moped::Node.class_eval do
19
+ include OneApm::Agent::Instrumentation::Moped
20
+ alias_method :logging_without_oneapm_trace, :logging
21
+ alias_method :logging, :logging_with_oneapm_trace
22
+ end
23
+ end
24
+ end
25
+
26
+ module OneApm
27
+ module Agent
28
+ module Instrumentation
29
+ module Moped
30
+ def logging_with_oneapm_trace(operations, &blk)
31
+ operation_name, collection = determine_operation_and_collection(operations.first)
32
+ log_statement = operations.first.log_inspect.encode("UTF-8")
33
+
34
+ operation = case operation_name
35
+ when 'INSERT', 'UPDATE', 'CREATE', 'FIND_AND_MODIFY' then 'save'
36
+ when 'QUERY', 'COUNT', 'GET_MORE', 'AGGREGATE' then 'find'
37
+ when 'DELETE' then 'destroy'
38
+ else
39
+ nil
40
+ end
41
+
42
+ command = Proc.new { logging_without_oneapm_trace(operations, &blk) }
43
+ res = nil
44
+
45
+ if operation
46
+ callback = Proc.new do |result, metric, elapsed|
47
+ OneApm::Agent::Datastores.notice_statement(log_statement, elapsed)
48
+ end
49
+
50
+ OneApm::Agent::Datastores.wrap('MongoDB', operation, collection, callback) do
51
+ res = command.call
52
+ end
53
+ else
54
+ res = command.call
55
+ end
56
+
57
+ res
58
+ end
59
+
60
+ def determine_operation_and_collection(operation)
61
+ log_statement = operation.log_inspect.encode("UTF-8")
62
+ collection = "Unknown"
63
+ if operation.respond_to?(:collection)
64
+ collection = operation.collection
65
+ end
66
+ operation_name = log_statement.split[0]
67
+ if operation_name == 'COMMAND' && log_statement.include?(":mapreduce")
68
+ operation_name = 'MAPREDUCE'
69
+ collection = log_statement[/:mapreduce=>"([^"]+)/,1]
70
+ elsif operation_name == 'COMMAND' && log_statement.include?(":count")
71
+ operation_name = 'COUNT'
72
+ collection = log_statement[/:count=>"([^"]+)/,1]
73
+ elsif operation_name == 'COMMAND' && log_statement.include?(":aggregate")
74
+ operation_name = 'AGGREGATE'
75
+ collection = log_statement[/:aggregate=>"([^"]+)/,1]
76
+ elsif operation_name == 'COMMAND' && log_statement.include?(":findAndModify")
77
+ operation_name = 'FIND_AND_MODIFY'
78
+ collection = log_statement[/:findAndModify=>"([^"]+)/,1]
79
+ end
80
+ return operation_name, collection
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end