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,43 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Agent
5
+ module Instrumentation
6
+ module Rails3
7
+ module Errors
8
+ def oneapm_notice_error(exception, custom_params = {})
9
+ filtered_params = (respond_to? :filter_parameters) ? filter_parameters(params) : params
10
+ filtered_params.merge!(custom_params)
11
+ OneApm::Transaction.notice_error( \
12
+ exception, \
13
+ :request => request, \
14
+ :metric => oneapm_metric_path, \
15
+ :custom_params => filtered_params)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ LibraryDetection.defer do
24
+ @name = :rails3_error
25
+
26
+ depends_on do
27
+ defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
28
+ end
29
+
30
+ depends_on do
31
+ defined?(ActionController) && defined?(ActionController::Base)
32
+ end
33
+
34
+ executes do
35
+ ::OneApm::Agent.logger.info 'Installing Rails 3 Error instrumentation'
36
+ end
37
+
38
+ executes do
39
+ class ActionController::Base
40
+ include OneApm::Agent::Instrumentation::Rails3::Errors
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require 'one_apm/inst/rails4/action_controller_subscriber'
3
+
4
+
5
+ LibraryDetection.defer do
6
+ @name = :rails4_controller
7
+
8
+ depends_on do
9
+ defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 4
10
+ end
11
+
12
+ depends_on do
13
+ defined?(ActionController) && defined?(ActionController::Base)
14
+ end
15
+
16
+ executes do
17
+ ::OneApm::Agent.logger.info 'Installing Rails 4 Controller instrumentation'
18
+ end
19
+
20
+ executes do
21
+ class ActionController::Base
22
+ include OneApm::Agent::Instrumentation::TransactionBase
23
+ end
24
+ OneApm::Agent::Instrumentation::ActionControllerSubscriber \
25
+ .subscribe(/^process_action.action_controller$/)
26
+ end
27
+ end
@@ -0,0 +1,121 @@
1
+ # encoding: utf-8
2
+ require 'one_apm/inst/support/evented_subscriber'
3
+ require 'one_apm/inst/support/ignore_actions'
4
+
5
+ module OneApm
6
+ module Agent
7
+ module Instrumentation
8
+ class ActionControllerSubscriber < EventedSubscriber
9
+
10
+ def start(name, id, payload) #THREAD_LOCAL_ACCESS
11
+ state = TransactionState.tl_get
12
+ request = state.request
13
+ event = ControllerEvent.new(name, Time.now, nil, id, payload, request)
14
+ push_event(event)
15
+
16
+ if state.is_execution_traced? && !event.ignored?
17
+ start_transaction(state, event)
18
+ else
19
+ # if this transaction is ignored, make sure child
20
+ # transaction are also ignored
21
+ state.current_transaction.ignore! if state.current_transaction
22
+ OneApm::Agent.instance.push_trace_execution_flag(false)
23
+ end
24
+ rescue => e
25
+ log_notification_error(e, name, 'start')
26
+ end
27
+
28
+ def finish(name, id, payload) #THREAD_LOCAL_ACCESS
29
+ event = pop_event(id)
30
+ event.payload.merge!(payload)
31
+
32
+ state = TransactionState.tl_get
33
+
34
+ if state.is_execution_traced? && !event.ignored?
35
+ stop_transaction(state, event)
36
+ else
37
+ Agent.instance.pop_trace_execution_flag
38
+ end
39
+ rescue => e
40
+ log_notification_error(e, name, 'finish')
41
+ end
42
+
43
+ def start_transaction(state, event)
44
+ Transaction.start(state, :controller,
45
+ :request => event.request,
46
+ :filtered_params => filter(event.payload[:params]),
47
+ :apdex_start_time => event.queue_start,
48
+ :transaction_name => event.metric_name)
49
+ end
50
+
51
+ def stop_transaction(state, event)
52
+ txn = state.current_transaction
53
+ txn.ignore_apdex! if event.apdex_ignored?
54
+ txn.ignore_enduser! if event.enduser_ignored?
55
+ Transaction.stop(state)
56
+ end
57
+
58
+ def filter(params)
59
+ munged_params = params.dup
60
+ munged_params.delete('controller')
61
+ munged_params.delete('action')
62
+ filters = Rails.application.config.filter_parameters
63
+ ActionDispatch::Http::ParameterFilter.new(filters).filter(munged_params)
64
+ end
65
+ end
66
+
67
+ class ControllerEvent < Event
68
+ attr_accessor :parent
69
+ attr_reader :queue_start, :request
70
+
71
+ def initialize(name, start, ending, transaction_id, payload, request)
72
+ # We have a different initialize parameter list, so be explicit
73
+ super(name, start, ending, transaction_id, payload)
74
+
75
+ @request = request
76
+ @controller_class = payload[:controller].split('::') \
77
+ .inject(Object){|m,o| m.const_get(o)}
78
+
79
+ if request && request.respond_to?(:env)
80
+ @queue_start = QueueTime.parse_frontend_timestamp(request.env, self.time)
81
+ end
82
+ end
83
+
84
+ def metric_name
85
+ @metric_name || "Controller/#{metric_path}/#{metric_action}"
86
+ end
87
+
88
+ def metric_path
89
+ @controller_class.controller_path
90
+ end
91
+
92
+ def metric_action
93
+ payload[:action]
94
+ end
95
+
96
+ def ignored?
97
+ _is_filtered?(TransactionBase::OA_DO_NOT_TRACE_KEY)
98
+ end
99
+
100
+ def apdex_ignored?
101
+ _is_filtered?(TransactionBase::OA_IGNORE_APDEX_KEY)
102
+ end
103
+
104
+ def enduser_ignored?
105
+ _is_filtered?(TransactionBase::OA_IGNORE_ENDUSER_KEY)
106
+ end
107
+
108
+ def _is_filtered?(key)
109
+ OneApm::Agent::Instrumentation::IgnoreActions.is_filtered?(
110
+ key,
111
+ @controller_class,
112
+ metric_action)
113
+ end
114
+
115
+ def to_s
116
+ "#<OneApm::Agent::Instrumentation::ControllerEvent:#{object_id} name: \"#{name}\" id: #{transaction_id} payload: #{payload}}>"
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ require 'one_apm/inst/rails4/action_view_subscriber'
3
+
4
+ LibraryDetection.defer do
5
+ @name = :rails4_view
6
+
7
+ depends_on do
8
+ defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 4
9
+ end
10
+
11
+ depends_on do
12
+ !OneApm::Agent.config[:disable_view_instrumentation] &&
13
+ !OneApm::Agent::Instrumentation::ActionViewSubscriber.subscribed?
14
+ end
15
+
16
+ executes do
17
+ ::OneApm::Agent.logger.info 'Installing Rails 4 view instrumentation'
18
+ end
19
+
20
+ executes do
21
+ OneApm::Agent::Instrumentation::ActionViewSubscriber.subscribe(/render_.+\.action_view$/)
22
+ end
23
+ end
@@ -0,0 +1,93 @@
1
+ # encoding: utf-8
2
+ require 'one_apm/inst/support/evented_subscriber'
3
+
4
+ # Listen for ActiveSupport::Notifications events for ActionView render
5
+ # events. Write metric data and transaction trace segments for each event.
6
+ module OneApm
7
+ module Agent
8
+ module Instrumentation
9
+ class ActionViewSubscriber < EventedSubscriber
10
+ def start(name, id, payload) #THREAD_LOCAL_ACCESS
11
+ event = RenderEvent.new(name, Time.now, nil, id, payload)
12
+ push_event(event)
13
+
14
+ state = OneApm::TransactionState.tl_get
15
+
16
+ if state.is_execution_traced? && event.recordable?
17
+ stack = state.traced_method_stack
18
+ event.frame = stack.push_frame(state, :action_view, event.time)
19
+ end
20
+ rescue => e
21
+ log_notification_error(e, name, 'start')
22
+ end
23
+
24
+ def finish(name, id, payload) #THREAD_LOCAL_ACCESS
25
+ event = pop_event(id)
26
+
27
+ state = OneApm::TransactionState.tl_get
28
+
29
+ if state.is_execution_traced? && event.recordable?
30
+ stack = state.traced_method_stack
31
+ frame = stack.pop_frame(state, event.frame, event.metric_name, event.end)
32
+ record_metrics(event, frame)
33
+ end
34
+ rescue => e
35
+ log_notification_error(e, name, 'finish')
36
+ end
37
+
38
+ def record_metrics(event, frame) #THREAD_LOCAL_ACCESS
39
+ exclusive = event.duration - frame.children_time
40
+ OneApm::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
41
+ event.metric_name, nil, event.duration, exclusive)
42
+ end
43
+
44
+ class RenderEvent < Event
45
+ # Nearly every "render_blah.action_view" event has a child
46
+ # in the form of "!render_blah.action_view". The children
47
+ # are the ones we want to record. There are a couple
48
+ # special cases of events without children.
49
+ def recordable?
50
+ name[0] == '!' ||
51
+ metric_name == 'View/text template/Rendering' ||
52
+ metric_name == "View/#{OneApm::Transaction::UNKNOWN_METRIC}/Partial"
53
+ end
54
+
55
+ def metric_name
56
+ if parent && (payload[:virtual_path] ||
57
+ (parent.payload[:identifier] =~ /template$/))
58
+ return parent.metric_name
59
+ elsif payload.key?(:virtual_path)
60
+ identifier = payload[:virtual_path]
61
+ else
62
+ identifier = payload[:identifier]
63
+ end
64
+
65
+ # memoize
66
+ @metric_name ||= "View/#{metric_path(identifier)}/#{metric_action(name)}"
67
+ @metric_name
68
+ end
69
+
70
+ def metric_path(identifier)
71
+ if identifier == nil
72
+ 'file'
73
+ elsif identifier =~ /template$/
74
+ identifier
75
+ elsif (parts = identifier.split('/')).size > 1
76
+ parts[-2..-1].join('/')
77
+ else
78
+ OneApm::Transaction::UNKNOWN_METRIC
79
+ end
80
+ end
81
+
82
+ def metric_action(name)
83
+ case name
84
+ when /render_template.action_view$/ then 'Rendering'
85
+ when 'render_partial.action_view' then 'Partial'
86
+ when 'render_collection.action_view' then 'Partial'
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,96 @@
1
+ # encoding: utf-8
2
+ require 'one_apm/agent/database/active_record_helper'
3
+ require 'one_apm/inst/support/evented_subscriber'
4
+
5
+ # Listen for ActiveSupport::Notifications events for ActiveRecord query
6
+ # events. Write metric data, transaction trace segments and slow sql
7
+ # nodes for each event.
8
+ module OneApm
9
+ module Agent
10
+ module Instrumentation
11
+ class ActiveRecordSubscriber < EventedSubscriber
12
+ CACHED_QUERY_NAME = 'CACHE'.freeze unless defined? CACHED_QUERY_NAME
13
+
14
+ def start(name, id, payload) #THREAD_LOCAL_ACCESS
15
+ return if payload[:name] == CACHED_QUERY_NAME
16
+ return unless OneApm::Agent.tl_is_execution_traced?
17
+ super
18
+ rescue => e
19
+ log_notification_error(e, name, 'start')
20
+ end
21
+
22
+ def finish(name, id, payload) #THREAD_LOCAL_ACCESS
23
+ return if payload[:name] == CACHED_QUERY_NAME
24
+ state = OneApm::TransactionState.tl_get
25
+ return unless state.is_execution_traced?
26
+ event = pop_event(id)
27
+ record_metrics(event)
28
+ notice_sql(state, event)
29
+ rescue => e
30
+ log_notification_error(e, name, 'finish')
31
+ end
32
+
33
+ def get_explain_plan( config, query )
34
+ connection = OneApm::Agent::Database.get_connection(config) do
35
+ ::ActiveRecord::Base.send("#{config[:adapter]}_connection",
36
+ config)
37
+ end
38
+ if connection && connection.respond_to?(:execute)
39
+ return connection.execute("EXPLAIN #{query}")
40
+ end
41
+ end
42
+
43
+ def notice_sql(state, event)
44
+ stack = state.traced_method_stack
45
+ config = active_record_config_for_event(event)
46
+ metric = base_metric(event)
47
+
48
+ # enter transaction trace segment
49
+ frame = stack.push_frame(state, :active_record, event.time)
50
+
51
+ OneApm::Agent.instance.transaction_sampler \
52
+ .notice_sql(event.payload[:sql], config,
53
+ Helper.milliseconds_to_seconds(event.duration),
54
+ state, &method(:get_explain_plan))
55
+
56
+ OneApm::Agent.instance.sql_sampler \
57
+ .notice_sql(event.payload[:sql], metric, config,
58
+ Helper.milliseconds_to_seconds(event.duration),
59
+ state, &method(:get_explain_plan))
60
+
61
+ # exit transaction trace segment
62
+ stack.pop_frame(state, frame, metric, event.end)
63
+ end
64
+
65
+ def record_metrics(event) #THREAD_LOCAL_ACCESS
66
+ base = base_metric(event)
67
+
68
+ other_metrics = ActiveRecordHelper.rollup_metrics_for(base)
69
+ if config = active_record_config_for_event(event)
70
+ other_metrics << ActiveRecordHelper.remote_service_metric(config[:adapter], config[:host])
71
+ end
72
+ other_metrics.compact!
73
+
74
+ OneApm::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
75
+ base, other_metrics,
76
+ Helper.milliseconds_to_seconds(event.duration)
77
+ )
78
+ end
79
+
80
+ def base_metric(event)
81
+ ActiveRecordHelper.metric_for_name(event.payload[:name]) ||
82
+ ActiveRecordHelper.metric_for_sql(OneApm::Helper.correctly_encoded(event.payload[:sql]))
83
+ end
84
+
85
+ def active_record_config_for_event(event)
86
+ return unless event.payload[:connection_id]
87
+
88
+ connections = ::ActiveRecord::Base.connection_handler.connection_pool_list.map { |handler| handler.connections }.flatten
89
+ connection = connections.detect { |cnxn| cnxn.object_id == event.payload[:connection_id] }
90
+
91
+ connection.instance_variable_get(:@config) if connection
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Agent
5
+ module Instrumentation
6
+ module Rails4
7
+ module Errors
8
+ def oneapm_notice_error(exception, custom_params = {})
9
+ filtered_params = (respond_to? :filter_parameters) ? filter_parameters(params) : params
10
+ filtered_params.merge!(custom_params)
11
+ OneApm::Transaction.notice_error( \
12
+ exception, \
13
+ :request => request, \
14
+ :custom_params => filtered_params)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ LibraryDetection.defer do
23
+ @name = :rails4_error
24
+
25
+ depends_on do
26
+ defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 4
27
+ end
28
+
29
+ depends_on do
30
+ defined?(ActionController) && defined?(ActionController::Base)
31
+ end
32
+
33
+ executes do
34
+ ::OneApm::Agent.logger.info 'Installing Rails 4 Error instrumentation'
35
+ end
36
+
37
+ executes do
38
+ class ActionController::Base
39
+ include OneApm::Agent::Instrumentation::Rails4::Errors
40
+ end
41
+ end
42
+ end