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,33 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class Transaction
5
+ module TransactionIgnore
6
+
7
+ def ignore!
8
+ @ignore_this_transaction = true
9
+ end
10
+
11
+ def ignore?
12
+ @ignore_this_transaction
13
+ end
14
+
15
+ def ignore_apdex!
16
+ @ignore_apdex = true
17
+ end
18
+
19
+ def ignore_apdex?
20
+ @ignore_apdex
21
+ end
22
+
23
+ def ignore_enduser!
24
+ @ignore_enduser = true
25
+ end
26
+
27
+ def ignore_enduser?
28
+ @ignore_enduser
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class Transaction
5
+
6
+ @@java_classes_loaded = false
7
+
8
+ if defined? JRuby
9
+ begin
10
+ require 'java'
11
+ java_import 'java.lang.management.ManagementFactory'
12
+ java_import 'com.sun.management.OperatingSystemMXBean'
13
+ @@java_classes_loaded = true
14
+ rescue
15
+ end
16
+ end
17
+
18
+ JRUBY_CPU_TIME_ERROR = "Error calculating JRuby CPU Time".freeze
19
+
20
+ def jruby_cpu_time
21
+ return nil unless @@java_classes_loaded
22
+ threadMBean = Java::JavaLangManagement::ManagementFactory.getThreadMXBean()
23
+
24
+ return nil unless threadMBean.isCurrentThreadCpuTimeSupported
25
+ java_utime = threadMBean.getCurrentThreadUserTime() # ns
26
+
27
+ -1 == java_utime ? 0.0 : java_utime/1e9
28
+ rescue => e
29
+ ::OneApm::Agent.logger.log_once(:warn, :jruby_cpu_time, JRUBY_CPU_TIME_ERROR, e)
30
+ ::OneApm::Agent.logger.debug(JRUBY_CPU_TIME_ERROR, e)
31
+ nil
32
+ end
33
+
34
+ def jruby_cpu_burn
35
+ return unless @jruby_cpu_start
36
+ jruby_cpu_time - @jruby_cpu_start
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ # This class represents a set of metrics that were recorded during a single
4
+ # transaction. Since the name of the transaction is not known until its end, we
5
+ # don't save explicit scopes with these metrics, we just keep separate
6
+ # collections of scoped and unscoped metrics.
7
+
8
+ module OneApm
9
+ class TransactionMetrics
10
+ DEFAULT_PROC = Proc.new { |hash, name| hash[name] = OneApm::Metrics::Stats.new }
11
+
12
+ def initialize
13
+ @unscoped = Hash.new(&DEFAULT_PROC)
14
+ @scoped = Hash.new(&DEFAULT_PROC)
15
+ end
16
+
17
+ def record_scoped(names, value=nil, aux=nil, &blk)
18
+ _record_metrics(names, value, aux, @scoped, &blk)
19
+ end
20
+
21
+ def record_unscoped(names, value=nil, aux=nil, &blk)
22
+ _record_metrics(names, value, aux, @unscoped, &blk)
23
+ end
24
+
25
+ def has_key?(key)
26
+ @unscoped.has_key?(key)
27
+ end
28
+
29
+ def [](key)
30
+ @unscoped[key]
31
+ end
32
+
33
+ def each_unscoped
34
+ @unscoped.each { |name, stats| yield name, stats }
35
+ end
36
+
37
+ def each_scoped
38
+ @scoped.each { |name, stats| yield name, stats }
39
+ end
40
+
41
+ def _record_metrics(names, value, aux, target, &blk)
42
+ # This looks dumb, but we're avoiding an extra Array allocation.
43
+ case names
44
+ when Array
45
+ names.each do |name|
46
+ target[name].record(value, aux, &blk)
47
+ end
48
+ else
49
+ target[names].record(value, aux, &blk)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class Transaction
5
+ module TransactionName
6
+
7
+ def overridden_name=(name)
8
+ @overridden_name = Helper.correctly_encoded(name)
9
+ end
10
+
11
+ def default_name=(name)
12
+ @default_name = Helper.correctly_encoded(name)
13
+ end
14
+
15
+ def make_transaction_name(name, category = nil)
16
+ "#{OneApm::TransactionNamer.prefix_for_category(self, category)}#{name}"
17
+ end
18
+
19
+ def set_default_transaction_name(name, category)
20
+ return log_frozen_name(name) if name_frozen?
21
+ if influences_transaction_name?(category)
22
+ self.default_name = name
23
+ @category = category if category
24
+ end
25
+ end
26
+
27
+ def set_overriding_transaction_name(name, category)
28
+ return log_frozen_name(name) if name_frozen?
29
+ if influences_transaction_name?(category)
30
+ self.overridden_name = name
31
+ @category = category if category
32
+ end
33
+ end
34
+
35
+ def name_last_frame(name)
36
+ frame_stack.last.name = name
37
+ end
38
+
39
+ def log_frozen_name(name)
40
+ OneApm::Agent.logger.warn("Attempted to rename transaction to '#{name}' after transaction name was already frozen as '#{@frozen_name}'.")
41
+ nil
42
+ end
43
+
44
+ def influences_transaction_name?(category)
45
+ !category || frame_stack.size == 1 || similar_category?(category)
46
+ end
47
+
48
+ def best_name
49
+ @frozen_name || @overridden_name ||
50
+ @default_name || Transaction::UNKNOWN_METRIC
51
+ end
52
+
53
+ def name_set?
54
+ (@overridden_name || @default_name) ? true : false
55
+ end
56
+
57
+ def promoted_transaction_name(name)
58
+ if name.start_with?(Transaction::MIDDLEWARE_PREFIX)
59
+ "#{Transaction::CONTROLLER_PREFIX}#{name}"
60
+ else
61
+ name
62
+ end
63
+ end
64
+
65
+ def freeze_name_and_execute_if_not_ignored
66
+ if !name_frozen?
67
+ name = promoted_transaction_name(best_name)
68
+ name = OneApm::Agent.instance.transaction_rules.rename(name)
69
+ @name_frozen = true
70
+
71
+ if name.nil?
72
+ ignore!
73
+ @frozen_name = best_name
74
+ else
75
+ @frozen_name = name
76
+ end
77
+ end
78
+
79
+ if block_given? && !@ignore_this_transaction
80
+ yield
81
+ end
82
+ end
83
+
84
+ def name_frozen?
85
+ @frozen_name ? true : false
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,49 @@
1
+ module OneApm
2
+ class TransactionNamer
3
+
4
+ def self.name_for(txn, traced_obj, category, options={})
5
+ "#{prefix_for_category(txn, category)}#{path_name(traced_obj, options)}"
6
+ end
7
+
8
+ def self.prefix_for_category(txn, category = nil)
9
+ category ||= (txn && txn.category)
10
+ case category
11
+ when :controller then ::OneApm::Transaction::CONTROLLER_PREFIX
12
+ when :task then ::OneApm::Transaction::TASK_PREFIX
13
+ when :rack then ::OneApm::Transaction::RACK_PREFIX
14
+ when :uri then ::OneApm::Transaction::CONTROLLER_PREFIX
15
+ when :sinatra then ::OneApm::Transaction::SINATRA_PREFIX
16
+ when :middleware then ::OneApm::Transaction::MIDDLEWARE_PREFIX
17
+ when :grape then ::OneApm::Transaction::GRAPE_PREFIX
18
+ else "#{category.to_s}/" # for internal use only
19
+ end
20
+ end
21
+
22
+ def self.path_name(traced_obj, options={})
23
+ return options[:path] if options[:path]
24
+
25
+ class_name = class_name(traced_obj, options)
26
+ if options[:name]
27
+ if class_name
28
+ "#{class_name}/#{options[:name]}"
29
+ else
30
+ options[:name]
31
+ end
32
+ elsif traced_obj.respond_to?(:oneapm_metric_path)
33
+ traced_obj.oneapm_metric_path
34
+ else
35
+ class_name
36
+ end
37
+ end
38
+
39
+ def self.class_name(traced_obj, options={})
40
+ return options[:class_name] if options[:class_name]
41
+ if (traced_obj.is_a?(Class) || traced_obj.is_a?(Module))
42
+ traced_obj.name
43
+ else
44
+ traced_obj.class.name
45
+ end
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,204 @@
1
+ # encoding: utf-8
2
+
3
+ require 'base64'
4
+
5
+ require 'one_apm/transaction/segment'
6
+ require 'one_apm/transaction/transaction_analysis'
7
+
8
+ module OneApm
9
+ # the number of segments that need to exist before we roll them up
10
+ # into one segment with multiple executions
11
+ COLLAPSE_SEGMENTS_THRESHOLD = 2
12
+
13
+ class TransactionSample
14
+ include TransactionAnalysis
15
+
16
+ attr_accessor :params, :root_segment, :profile, :force_persist, :guid,
17
+ :threshold, :finished, :xray_session_id, :start_time,
18
+ :synthetics_resource_id
19
+ attr_reader :root_segment, :params, :sample_id
20
+ attr_writer :prepared
21
+
22
+ @@start_time = Time.now
23
+
24
+ def initialize(time = Time.now.to_f, sample_id = nil)
25
+ @sample_id = sample_id || object_id
26
+ @start_time = time
27
+ @params = { :segment_count => -1, :request_params => {} }
28
+ @segment_count = -1
29
+ @root_segment = create_segment 0.0, "ROOT"
30
+ @prepared = false
31
+ end
32
+
33
+ def prepared?
34
+ @prepared
35
+ end
36
+
37
+ def count_segments
38
+ @segment_count
39
+ end
40
+
41
+ # makes sure that the parameter cache for segment count is set to
42
+ # the correct value
43
+ def ensure_segment_count_set(count)
44
+ params[:segment_count] ||= count
45
+ end
46
+
47
+ # offset from start of app
48
+ def timestamp
49
+ @start_time - @@start_time.to_f
50
+ end
51
+
52
+ def set_custom_param(name, value)
53
+ @params[:custom_params] ||= {}
54
+ @params[:custom_params][name] = value
55
+ end
56
+
57
+ include OneApm::Coerce
58
+
59
+ def to_array
60
+ [ float(@start_time),
61
+ @params[:request_params],
62
+ @params[:custom_params],
63
+ @root_segment.to_array ]
64
+ end
65
+
66
+ def to_collector_array(encoder)
67
+ trace_tree = encoder.encode(self.to_array)
68
+ [ Helper.time_to_millis(@start_time),
69
+ Helper.time_to_millis(duration),
70
+ string(transaction_name),
71
+ string(@params[:uri]),
72
+ trace_tree,
73
+ string(@guid),
74
+ nil,
75
+ forced?,
76
+ int_or_nil(xray_session_id),
77
+ string(synthetics_resource_id)
78
+ ]
79
+ end
80
+
81
+ def path_string
82
+ @root_segment.path_string
83
+ end
84
+
85
+ def transaction_name
86
+ @params[:path]
87
+ end
88
+
89
+ def transaction_name=(new_name)
90
+ @params[:path] = new_name
91
+ end
92
+
93
+ def forced?
94
+ !!@force_persist || !int_or_nil(xray_session_id).nil?
95
+ end
96
+
97
+ # relative_timestamp is seconds since the start of the transaction
98
+ def create_segment(relative_timestamp, metric_name=nil)
99
+ raise TypeError.new("Frozen Transaction Sample") if finished
100
+ @params[:segment_count] += 1
101
+ @segment_count += 1
102
+ OneApm::TransactionSample::Segment.new(relative_timestamp, metric_name)
103
+ end
104
+
105
+ def duration
106
+ root_segment.duration
107
+ end
108
+
109
+ # Iterates recursively over each segment in the entire transaction
110
+ # sample tree
111
+ def each_segment(&block)
112
+ @root_segment.each_segment(&block)
113
+ end
114
+
115
+ # Iterates recursively over each segment in the entire transaction
116
+ # sample tree while keeping track of nested segments
117
+ def each_segment_with_nest_tracking(&block)
118
+ @root_segment.each_segment_with_nest_tracking(&block)
119
+ end
120
+
121
+ def to_s_compact
122
+ @root_segment.to_s_compact
123
+ end
124
+
125
+ # Searches the tree recursively for the segment with the given
126
+ # id. note that this is an internal id, not an ActiveRecord id
127
+ def find_segment(id)
128
+ @root_segment.find_segment(id)
129
+ end
130
+
131
+ def to_s
132
+ s = "Transaction Sample collected at #{Time.at(start_time)}\n"
133
+ s << " {\n"
134
+ s << " Path: #{params[:path]} \n"
135
+
136
+ params.each do |k,v|
137
+ next if k == :path
138
+ s << " #{k}: " <<
139
+ case v
140
+ when Enumerable then v.map(&:to_s).sort.join("; ")
141
+ when String then v
142
+ when Float then '%6.3s' % v
143
+ when Fixnum then v.to_s
144
+ when nil then ''
145
+ else
146
+ raise "unexpected value type for #{k}: '#{v}' (#{v.class})"
147
+ end << "\n"
148
+ end
149
+ s << " }\n\n"
150
+ s << @root_segment.to_debug_str(0)
151
+ end
152
+
153
+ # Return a new transaction sample that can be sent to the OneApm service.
154
+ def prepare_to_send!
155
+ return self if @prepared
156
+
157
+ if Agent::Database.should_record_sql?
158
+ collect_explain_plans!
159
+ prepare_sql_for_transmission!
160
+ else
161
+ strip_sql!
162
+ end
163
+
164
+ @prepared = true
165
+ self
166
+ end
167
+
168
+ def params=(params)
169
+ @params = params
170
+ end
171
+
172
+ private
173
+
174
+ def strip_sql!
175
+ each_segment do |segment|
176
+ segment.params.delete(:sql)
177
+ end
178
+ end
179
+
180
+ def collect_explain_plans!
181
+ return unless Agent::Database.should_collect_explain_plans?
182
+ threshold = Agent.config[:'transaction_tracer.explain_threshold']
183
+ each_segment do |segment|
184
+ if segment[:sql] && segment.duration > threshold
185
+ segment[:explain_plan] = segment.explain_sql
186
+ end
187
+ end
188
+ end
189
+
190
+ def prepare_sql_for_transmission!
191
+ strategy = Agent::Database.record_sql_method
192
+ each_segment do |segment|
193
+ if segment[:sql]
194
+ segment[:sql] = case strategy
195
+ when :raw
196
+ segment[:sql].to_s
197
+ when :obfuscated
198
+ Agent::Database.obfuscate_sql(segment[:sql]).to_s
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end