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,129 @@
1
+ # encoding: utf-8
2
+
3
+ require 'thread'
4
+
5
+ module OneApm
6
+ module Support
7
+ module VM
8
+ class RubiniusVM
9
+ def snapshot
10
+ snap = Snapshot.new
11
+ gather_stats(snap)
12
+ snap
13
+ end
14
+
15
+ def gather_stats(snap)
16
+ gather_gc_stats(snap)
17
+ gather_thread_stats(snap)
18
+ end
19
+
20
+ def gather_gc_stats(snap)
21
+ snap.gc_runs = GC.count
22
+
23
+ # Rubinius::Metrics is available since Rubinius 2.3
24
+ if has_metrics?
25
+ gather_stats_from_metrics(snap)
26
+ else
27
+ gather_stats_from_gc_stat(snap)
28
+ end
29
+
30
+ gather_gc_time(snap)
31
+ end
32
+
33
+ # The '+ 0' bits in here are a workaround for a Rubinius bug wherein
34
+ # Rubinius::Metrics.data returns 0's as Bignums, and these Bignums
35
+ # cannot be safely subtraced from Fixnums. The + 0 has the effect of
36
+ # truncating to a Fixnum if possible without loss of precision.
37
+ def gather_stats_from_metrics(snap)
38
+ snap.major_gc_count = metric(:'gc.immix.count') + 0
39
+ snap.minor_gc_count = metric(:'gc.young.count') + 0
40
+
41
+ snap.heap_live = metric(:'memory.large.objects.current') +
42
+ metric(:'memory.young.objects.current') +
43
+ metric(:'memory.immix.objects.current')
44
+
45
+ snap.total_allocated_object =
46
+ metric(:'memory.large.objects.total') +
47
+ metric(:'memory.young.objects.total') +
48
+ metric(:'memory.immix.objects.total')
49
+
50
+ snap.method_cache_invalidations = metric(:'vm.inline_cache.resets') + 0
51
+ end
52
+
53
+ def gather_stats_from_gc_stat(snap)
54
+ gc_stats = GC.stat[:gc]
55
+
56
+ if gc_stats
57
+ snap.major_gc_count = gc_stats[:full][:count] if gc_stats[:full]
58
+ snap.minor_gc_count = gc_stats[:young][:count] if gc_stats[:young]
59
+ end
60
+ end
61
+
62
+ def gather_gc_time(snap)
63
+ if GC.respond_to?(:time)
64
+ # On Rubinius GC.time returns a time in miliseconds, not seconds.
65
+ snap.gc_total_time = GC.time / 1000
66
+ end
67
+ end
68
+
69
+ def gather_thread_stats(snap)
70
+ snap.thread_count = Thread.list.size
71
+ end
72
+
73
+ def has_metrics?
74
+ Rubinius.const_defined?(:Metrics)
75
+ end
76
+
77
+ def metric(key)
78
+ Rubinius::Metrics.data[key]
79
+ end
80
+
81
+ SUPPORTED_KEYS_GC_RBX_METRICS = [
82
+ :gc_runs,
83
+ :heap_live,
84
+ :major_gc_count,
85
+ :minor_gc_count,
86
+ :method_cache_invalidations,
87
+ :thread_count,
88
+ :total_allocated_object
89
+ ].freeze
90
+
91
+ def supports?(key)
92
+ if has_metrics?
93
+ case key
94
+ when :major_gc_count
95
+ true
96
+ when :minor_gc_count
97
+ true
98
+ when :heap_live
99
+ true
100
+ when :total_allocated_object
101
+ true
102
+ when :method_cache_invalidations
103
+ true
104
+ when :gc_runs
105
+ true
106
+ when :gc_total_time
107
+ GC.respond_to?(:time)
108
+ when :thread_count
109
+ true
110
+ else
111
+ false
112
+ end
113
+ else
114
+ case key
115
+ when :major_gc_count
116
+ true
117
+ when :minor_gc_count
118
+ true
119
+ when :thread_count
120
+ true
121
+ else
122
+ false
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module Support
5
+ module VM
6
+ class Snapshot
7
+ attr_accessor :gc_total_time, :gc_runs, :major_gc_count, :minor_gc_count,
8
+ :total_allocated_object, :heap_live, :heap_free,
9
+ :method_cache_invalidations, :constant_cache_invalidations,
10
+ :thread_count, :taken_at
11
+
12
+ def initialize
13
+ @taken_at = Time.now.to_f
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,336 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/inst/support/queue_time'
4
+ require 'one_apm/transaction/transaction_timings'
5
+ require 'one_apm/transaction/transaction_metrics'
6
+ require 'one_apm/transaction/thread_local_access'
7
+ require 'one_apm/transaction/metric_constants'
8
+ require 'one_apm/transaction/transaction_synthetics'
9
+ require 'one_apm/transaction/transaction_ignore'
10
+ require 'one_apm/transaction/transaction_name'
11
+ require 'one_apm/transaction/transaction_finish_append'
12
+ require 'one_apm/transaction/class_methods'
13
+ require 'one_apm/transaction/instance_helpers'
14
+ require 'one_apm/transaction/transaction_jruby_functions'
15
+ require 'one_apm/transaction/transaction_summary'
16
+ require 'one_apm/transaction/transaction_cpu'
17
+ require 'one_apm/transaction/transaction_apdex'
18
+ require 'one_apm/support/method_tracer/helpers'
19
+
20
+ module OneApm
21
+ class Transaction
22
+ extend ThreadLocalAccess
23
+
24
+ include TransactionSynthetics
25
+ include TransactionIgnore
26
+ include TransactionName
27
+ include TransactionFinishAppend
28
+ include InstanceHelpers
29
+
30
+ attr_accessor :start_time,
31
+ :apdex_start,
32
+ :exceptions,
33
+ :filtered_params,
34
+ :jruby_cpu_start,
35
+ :process_cpu_start,
36
+ :http_response_code,
37
+ :request
38
+
39
+ attr_reader :database_metric_name,
40
+ :guid,
41
+ :metrics,
42
+ :gc_start_snapshot,
43
+ :category,
44
+ :frame_stack,
45
+ :cat_path_hashes,
46
+ :transaction_trace
47
+
48
+ def initialize(category, options)
49
+ @frame_stack = []
50
+ @has_children = false
51
+
52
+ self.default_name = options[:transaction_name]
53
+ @overridden_name = nil
54
+ @frozen_name = nil
55
+
56
+ @category = category
57
+ @start_time = Time.now
58
+ @apdex_start = options[:apdex_start_time] || @start_time
59
+ @jruby_cpu_start = jruby_cpu_time
60
+ @process_cpu_start = process_cpu
61
+ @gc_start_snapshot = OneApm::Collector::StatsEngine::GCProfiler.take_snapshot
62
+ @filtered_params = options[:filtered_params] || {}
63
+ @request = options[:request]
64
+ @exceptions = {}
65
+ @metrics = TransactionMetrics.new
66
+ @guid = generate_guid
67
+ @cat_path_hashes = nil
68
+
69
+ @ignore_this_transaction = false
70
+ @ignore_apdex = false
71
+ @ignore_enduser = false
72
+ end
73
+
74
+ def start(state)
75
+ return if !state.is_execution_traced?
76
+
77
+ transaction_sampler.on_start_transaction(state, start_time, uri)
78
+ sql_sampler.on_start_transaction(state, start_time, uri)
79
+ agent.events.notify(:start_transaction)
80
+ OneApm::Agent::BusyCalculator.dispatcher_start(start_time)
81
+
82
+ frame_stack.push OneApm::Support::MethodTracer::Helpers.trace_execution_scoped_header(state, start_time.to_f)
83
+ name_last_frame @default_name
84
+ end
85
+
86
+ def stop(state, end_time, outermost_frame)
87
+ return if !state.is_execution_traced?
88
+ freeze_name_and_execute_if_not_ignored
89
+ ignore! if user_defined_rules_ignore?
90
+
91
+ if @has_children
92
+ name = Transaction.nested_transaction_name(outermost_frame.name)
93
+ trace_options = TRACE_OPTIONS_SCOPED
94
+ else
95
+ name = @frozen_name
96
+ trace_options = TRACE_OPTIONS_UNSCOPED
97
+ end
98
+
99
+ # These metrics are recorded here instead of in record_summary_metrics
100
+ # in order to capture the exclusive time associated with the outer-most
101
+ # TT node.
102
+ if needs_middleware_summary_metrics?(name)
103
+ summary_metrics_with_exclusive_time = MIDDLEWARE_SUMMARY_METRICS
104
+ else
105
+ summary_metrics_with_exclusive_time = EMPTY_SUMMARY_METRICS
106
+ end
107
+
108
+ OneApm::Support::MethodTracer::Helpers.trace_execution_scoped_footer(
109
+ state,
110
+ start_time.to_f,
111
+ name,
112
+ summary_metrics_with_exclusive_time,
113
+ outermost_frame,
114
+ trace_options,
115
+ end_time.to_f)
116
+
117
+ OneApm::Agent::BusyCalculator.dispatcher_finish(end_time)
118
+
119
+ commit!(state, end_time, name) unless @ignore_this_transaction
120
+ end
121
+
122
+ def commit!(state, end_time, outermost_segment_name)
123
+ record_transaction_cpu(state)
124
+ record_gc(state, end_time)
125
+ sql_sampler.on_finishing_transaction(state, @frozen_name)
126
+
127
+ record_summary_metrics(outermost_segment_name, end_time)
128
+ record_apdex(state, end_time) unless ignore_apdex?
129
+ record_queue_time
130
+
131
+ record_exceptions
132
+ merge_metrics
133
+
134
+ send_transaction_finished_event(state, start_time, end_time)
135
+ end
136
+
137
+ # This event is fired when the transaction is fully completed. The metric
138
+ # values and sampler can't be successfully modified from this event.
139
+ def send_transaction_finished_event(state, start_time, end_time)
140
+ duration = end_time.to_f - start_time.to_f
141
+ payload = {
142
+ :name => @frozen_name,
143
+ :start_timestamp => start_time.to_f,
144
+ :duration => duration,
145
+ :metrics => @metrics,
146
+ :custom_params => custom_parameters
147
+ }
148
+ append_cat_info(state, duration, payload)
149
+ append_apdex_perf_zone(duration, payload)
150
+ append_synthetics_to(state, payload)
151
+ append_referring_transaction_guid_to(state, payload)
152
+ append_http_response_code(payload)
153
+
154
+ agent.events.notify(:transaction_finished, payload)
155
+ end
156
+
157
+ # Call this to ensure that the current transaction is not saved
158
+ def abort_transaction!(state)
159
+ transaction_sampler.ignore_transaction(state)
160
+ end
161
+
162
+ def record_transaction_cpu(state)
163
+ burn = cpu_burn
164
+ if burn
165
+ transaction_sampler.notice_transaction_cpu_time(state, burn)
166
+ end
167
+ end
168
+
169
+ def record_gc(state, end_time)
170
+ gc_stop_snapshot = OneApm::Collector::StatsEngine::GCProfiler.take_snapshot
171
+ gc_delta = OneApm::Collector::StatsEngine::GCProfiler.record_delta(gc_start_snapshot, gc_stop_snapshot)
172
+ @transaction_trace = transaction_sampler.on_finishing_transaction(state, self, end_time, gc_delta)
173
+ end
174
+
175
+ # The summary metrics recorded by this method all end up with a duration
176
+ # equal to the transaction itself, and an exclusive time of zero.
177
+ def record_summary_metrics(outermost_segment_name, end_time)
178
+ metrics = summary_metrics
179
+ metrics << @frozen_name unless @frozen_name == outermost_segment_name
180
+ @metrics.record_unscoped(metrics, end_time.to_f - start_time.to_f, 0)
181
+ end
182
+
183
+ def record_apdex(state, end_time=Time.now)
184
+ return unless recording_web_transaction? && state.is_execution_traced?
185
+
186
+ freeze_name_and_execute_if_not_ignored do
187
+ action_duration = end_time - start_time
188
+ total_duration = end_time - apdex_start
189
+
190
+ apdex_bucket_global = apdex_bucket(total_duration)
191
+ apdex_bucket_txn = apdex_bucket(action_duration)
192
+
193
+ @metrics.record_unscoped(APDEX_METRIC, apdex_bucket_global, apdex_t)
194
+ txn_apdex_metric = @frozen_name.gsub(/^[^\/]+\//, 'Apdex/')
195
+ @metrics.record_unscoped(txn_apdex_metric, apdex_bucket_txn, apdex_t)
196
+ end
197
+ end
198
+
199
+ def record_queue_time
200
+ value = queue_time
201
+ if value > 0.0
202
+ if value < OneApm::Support::MethodTracer::Helpers::MAX_ALLOWED_METRIC_DURATION
203
+ @metrics.record_unscoped(QUEUE_TIME_METRIC, value)
204
+ else
205
+ ::OneApm::Agent.logger.log_once(:warn, :too_high_queue_time, "Not recording unreasonably large queue time of #{value} s")
206
+ end
207
+ end
208
+ end
209
+
210
+ def record_exceptions
211
+ @exceptions.each do |exception, options|
212
+ options[:metric] = best_name
213
+ agent.error_collector.notice_error(exception, options)
214
+ end
215
+ end
216
+
217
+ def merge_metrics
218
+ agent.stats_engine.merge_transaction_metrics!(@metrics, best_name)
219
+ end
220
+
221
+ def instrumentation_state
222
+ @instrumentation_state ||= {}
223
+ end
224
+
225
+ def with_database_metric_name(model, method)
226
+ previous = self.instrumentation_state[:datastore_override]
227
+ model_name = case model
228
+ when Class
229
+ model.name
230
+ when String
231
+ model
232
+ else
233
+ model.to_s
234
+ end
235
+ self.instrumentation_state[:datastore_override] = [method, model_name]
236
+ yield
237
+ ensure
238
+ self.instrumentation_state[:datastore_override] = previous
239
+ end
240
+
241
+ def noticed_error_ids
242
+ @noticed_error_ids ||= []
243
+ end
244
+
245
+ def create_nested_frame(state, category, options)
246
+ @has_children = true
247
+ if options[:filtered_params] && !options[:filtered_params].empty?
248
+ @filtered_params = options[:filtered_params]
249
+ end
250
+
251
+ frame_stack.push OneApm::Support::MethodTracer::Helpers.trace_execution_scoped_header(state, Time.now.to_f)
252
+ name_last_frame(options[:transaction_name])
253
+
254
+ set_default_transaction_name(options[:transaction_name], category)
255
+ end
256
+
257
+ def user_defined_rules_ignore?
258
+ return unless uri
259
+ return if (rules = OneApm::Agent.config[:"rules.ignore_url_regexes"]).empty?
260
+
261
+ parsed = OneApm::Support::HTTPClients::URIUtil.parse_url(uri)
262
+ filtered_uri = OneApm::Support::HTTPClients::URIUtil.filter_uri(parsed)
263
+
264
+ rules.any? do |rule|
265
+ filtered_uri.match(rule)
266
+ end
267
+ rescue URI::InvalidURIError => e
268
+ OneApm::Agent.logger.debug("Error parsing URI: #{uri}", e)
269
+ false
270
+ end
271
+
272
+ def cat_trip_id(state)
273
+ agent.cross_app_monitor.client_referring_transaction_trip_id(state) || guid
274
+ end
275
+
276
+ def cat_path_hash(state)
277
+ referring_path_hash = cat_referring_path_hash(state) || '0'
278
+ seed = referring_path_hash.to_i(16)
279
+ result = agent.cross_app_monitor.path_hash(best_name, seed)
280
+ record_cat_path_hash(result)
281
+ result
282
+ end
283
+
284
+ def record_cat_path_hash(hash)
285
+ @cat_path_hashes ||= []
286
+ if @cat_path_hashes.size < 10 && !@cat_path_hashes.include?(hash)
287
+ @cat_path_hashes << hash
288
+ end
289
+ end
290
+
291
+ def cat_referring_path_hash(state)
292
+ agent.cross_app_monitor.client_referring_transaction_path_hash(state)
293
+ end
294
+
295
+ # Do not call this. Invoke the class method instead.
296
+ def notice_error(error, options={}) # :nodoc:
297
+ options[:uri] ||= uri if uri
298
+ options[:referer] ||= referer if referer
299
+
300
+ if filtered_params && !filtered_params.empty?
301
+ options[:request_params] = filtered_params
302
+ end
303
+
304
+ options.merge!(custom_parameters)
305
+
306
+ if @exceptions[error]
307
+ @exceptions[error].merge! options
308
+ else
309
+ @exceptions[error] = options
310
+ end
311
+ end
312
+
313
+ # Yield to a block that is run with a database metric name context. This means
314
+ # the Database instrumentation will use this for the metric name if it does not
315
+ # otherwise know about a model. This is re-entrant.
316
+ #
317
+ # * <tt>model</tt> is the DB model class
318
+ # * <tt>method</tt> is the name of the finder method or other method to identify the operation with.
319
+ #
320
+ def with_database_metric_name(model, method)
321
+ previous = @database_metric_name
322
+ model_name = case model
323
+ when Class
324
+ model.name
325
+ when String
326
+ model
327
+ else
328
+ model.to_s
329
+ end
330
+ @database_metric_name = "ActiveRecord/#{model_name}/#{method}"
331
+ yield
332
+ ensure
333
+ @database_metric_name = previous
334
+ end
335
+ end
336
+ end