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,193 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class TransactionSample
5
+ class Segment
6
+ attr_reader :entry_timestamp
7
+ # The exit timestamp will be relative except for the outermost sample which will
8
+ # have a timestamp.
9
+ attr_reader :exit_timestamp
10
+ attr_reader :parent_segment
11
+
12
+ # This is only used from developer mode and rpm_site.
13
+ # No new clients should be added.
14
+ attr_reader :segment_id
15
+
16
+ attr_accessor :metric_name
17
+
18
+ UNKNOWN_SEGMENT_NAME = '<unknown>'.freeze
19
+
20
+ def initialize(timestamp, metric_name, segment_id=nil)
21
+ @entry_timestamp = timestamp
22
+ @metric_name = metric_name || UNKNOWN_SEGMENT_NAME
23
+ @segment_id = segment_id || object_id
24
+ end
25
+
26
+ # sets the final timestamp on a segment to indicate the exit
27
+ # point of the segment
28
+ def end_trace(timestamp)
29
+ @exit_timestamp = timestamp
30
+ end
31
+
32
+ def add_called_segment(s)
33
+ @called_segments ||= []
34
+ @called_segments << s
35
+ s.parent_segment = self
36
+ end
37
+
38
+ def to_s
39
+ to_debug_str(0)
40
+ end
41
+
42
+ include OneApm::Coerce
43
+
44
+ def to_array
45
+ [ OneApm::Helper.time_to_millis(@entry_timestamp),
46
+ OneApm::Helper.time_to_millis(@exit_timestamp),
47
+ string(@metric_name),
48
+ (@params || {}) ] +
49
+ [ (@called_segments ? @called_segments.map{|s| s.to_array} : []) ]
50
+ end
51
+
52
+ def path_string
53
+ "#{metric_name}[#{called_segments.collect {|segment| segment.path_string }.join('')}]"
54
+ end
55
+
56
+ def to_s_compact
57
+ str = ""
58
+ str << metric_name
59
+ if called_segments.any?
60
+ str << "{#{called_segments.map { | cs | cs.to_s_compact }.join(",")}}"
61
+ end
62
+ str
63
+ end
64
+
65
+ def to_debug_str(depth)
66
+ tab = " " * depth
67
+ s = tab.clone
68
+ s << ">> #{'%3i ms' % (@entry_timestamp*1000)} [#{self.class.name.split("::").last}] #{metric_name} \n"
69
+ unless params.empty?
70
+ params.each do |k,v|
71
+ s << "#{tab} -#{'%-16s' % k}: #{v.to_s[0..80]}\n"
72
+ end
73
+ end
74
+ called_segments.each do |cs|
75
+ s << cs.to_debug_str(depth + 1)
76
+ end
77
+ s << tab + "<< "
78
+ s << case @exit_timestamp
79
+ when nil then ' n/a'
80
+ when Numeric then '%3i ms' % (@exit_timestamp*1000)
81
+ else @exit_timestamp.to_s
82
+ end
83
+ s << " #{metric_name}\n"
84
+ end
85
+
86
+ def called_segments
87
+ @called_segments || []
88
+ end
89
+
90
+ # return the total duration of this segment
91
+ def duration
92
+ (@exit_timestamp - @entry_timestamp).to_f
93
+ end
94
+
95
+ # return the duration of this segment without
96
+ # including the time in the called segments
97
+ def exclusive_duration
98
+ d = duration
99
+
100
+ called_segments.each do |segment|
101
+ d -= segment.duration
102
+ end
103
+ d
104
+ end
105
+
106
+ def count_segments
107
+ count = 1
108
+ called_segments.each { | seg | count += seg.count_segments }
109
+ count
110
+ end
111
+
112
+ def []=(key, value)
113
+ # only create a parameters field if a parameter is set; this will save
114
+ # bandwidth etc as most segments have no parameters
115
+ params[key] = value
116
+ end
117
+
118
+ def [](key)
119
+ params[key]
120
+ end
121
+
122
+ def params
123
+ @params ||= {}
124
+ end
125
+
126
+ def params=(p)
127
+ @params = p
128
+ end
129
+
130
+ # call the provided block for this segment and each
131
+ # of the called segments
132
+ def each_segment(&block)
133
+ block.call self
134
+
135
+ if @called_segments
136
+ @called_segments.each do |segment|
137
+ segment.each_segment(&block)
138
+ end
139
+ end
140
+ end
141
+
142
+ # call the provided block for this segment and each
143
+ # of the called segments while keeping track of nested segments
144
+ def each_segment_with_nest_tracking(&block)
145
+ summary = block.call self
146
+ summary.current_nest_count += 1 if summary
147
+
148
+ if @called_segments
149
+ @called_segments.each do |segment|
150
+ segment.each_segment_with_nest_tracking(&block)
151
+ end
152
+ end
153
+
154
+ summary.current_nest_count -= 1 if summary
155
+ end
156
+
157
+ # This is only for use by developer mode
158
+ def find_segment(id)
159
+ return self if segment_id == id
160
+ called_segments.each do |segment|
161
+ found = segment.find_segment(id)
162
+ return found if found
163
+ end
164
+ nil
165
+ end
166
+
167
+ def explain_sql
168
+ return params[:explain_plan] if params.key?(:explain_plan)
169
+
170
+ statement = params[:sql]
171
+ return nil unless statement.respond_to?(:config) &&
172
+ statement.respond_to?(:explainer)
173
+
174
+ OneApm::Agent::Database.explain_sql(statement,
175
+ statement.config,
176
+ &statement.explainer)
177
+ end
178
+
179
+ def obfuscated_sql
180
+ OneApm::Agent::Database.obfuscate_sql(params[:sql])
181
+ end
182
+
183
+ def called_segments=(segments)
184
+ @called_segments = segments
185
+ end
186
+
187
+ protected
188
+ def parent_segment=(s)
189
+ @parent_segment = s
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ module TransactionAnalysis
5
+ # summarizes performance data for all calls to segments
6
+ # with the same metric_name
7
+ class SegmentSummary
8
+ attr_accessor :metric_name, :total_time, :exclusive_time, :call_count, :current_nest_count
9
+ def initialize(metric_name, sample)
10
+ @metric_name = metric_name
11
+ @total_time, @exclusive_time, @call_count = 0,0,0
12
+ @sample = sample
13
+ @current_nest_count = 0
14
+ end
15
+
16
+ def <<(segment)
17
+ if metric_name != segment.metric_name
18
+ raise ArgumentError, "Metric Name Mismatch: #{segment.metric_name} != #{metric_name}"
19
+ end
20
+
21
+ # a nested segment should use the sum of the top level totals
22
+ @total_time += segment.duration if current_nest_count == 0
23
+ @exclusive_time += segment.exclusive_duration
24
+ @call_count += 1
25
+ end
26
+
27
+ def average_time
28
+ @total_time / @call_count
29
+ end
30
+
31
+ def average_exclusive_time
32
+ @exclusive_time / @call_count
33
+ end
34
+
35
+ def exclusive_time_percentage
36
+ return 0 unless @exclusive_time && @sample.duration && @sample.duration > 0
37
+ @exclusive_time / @sample.duration
38
+ end
39
+
40
+ def total_time_percentage
41
+ return 0 unless @total_time && @sample.duration && @sample.duration > 0
42
+ @total_time / @sample.duration
43
+ end
44
+
45
+ def ui_name
46
+ return @metric_name if @metric_name == 'Remainder'
47
+ OneApm::MetricParser::MetricParser.parse(@metric_name).developer_name
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class Transaction
5
+ module ThreadLocalAccess
6
+
7
+ def tl_current
8
+ TransactionState.tl_get.current_transaction
9
+ end
10
+
11
+ def set_default_transaction_name(name, category = nil, segment_name = nil)
12
+ txn = tl_current
13
+ name = txn.make_transaction_name(name, category)
14
+ txn.name_last_frame(segment_name || name)
15
+ txn.set_default_transaction_name(name, category)
16
+ end
17
+
18
+ def set_overriding_transaction_name(name, category = nil)
19
+ txn = tl_current
20
+ return unless txn
21
+
22
+ name = txn.make_transaction_name(name, category)
23
+
24
+ txn.name_last_frame(name)
25
+ txn.set_overriding_transaction_name(name, category)
26
+ end
27
+
28
+ # Indicate that you don't want to keep the currently saved transaction
29
+ # information
30
+ def abort_transaction! #THREAD_LOCAL_ACCESS
31
+ state = OneApm::TransactionState.tl_get
32
+ txn = state.current_transaction
33
+ txn.abort_transaction!(state) if txn
34
+ end
35
+
36
+ # If we have an active transaction, notice the error and increment the error metric.
37
+ # Options:
38
+ # * <tt>:request</tt> => Request object to get the uri and referer
39
+ # * <tt>:uri</tt> => The request path, minus any request params or query string.
40
+ # * <tt>:referer</tt> => The URI of the referer
41
+ # * <tt>:metric</tt> => The metric name associated with the transaction
42
+ # * <tt>:request_params</tt> => Request parameters, already filtered if necessary
43
+ # * <tt>:custom_params</tt> => Custom parameters
44
+ # Anything left over is treated as custom params
45
+
46
+ def notice_error(e, options={})
47
+ options = extract_request_options(options)
48
+ state = OneApm::TransactionState.tl_get
49
+ txn = state.current_transaction
50
+ if txn
51
+ txn.notice_error(e, options)
52
+ else
53
+ OneApm::Agent.instance.error_collector.notice_error(e, options)
54
+ end
55
+ end
56
+
57
+ def extract_request_options(options)
58
+ req = options.delete(:request)
59
+ if req
60
+ options[:uri] = uri_from_request(req)
61
+ options[:referer] = referer_from_request(req)
62
+ end
63
+ options
64
+ end
65
+
66
+ def recording_web_transaction?
67
+ txn = tl_current
68
+ txn && txn.recording_web_transaction?
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ require 'one_apm/transaction/segment_summary'
4
+ # Add these methods to TransactionSample that enable performance analysis in the user interface.
5
+ module OneApm
6
+ module TransactionAnalysis
7
+ def database_time
8
+ time_percentage(/^Database\/.*/)
9
+ end
10
+
11
+ def render_time
12
+ time_percentage(/^View\/.*/)
13
+ end
14
+
15
+ # return the data that breaks down the performance of the transaction
16
+ # as an array of SegmentSummary objects. If a limit is specified, then
17
+ # limit the data set to the top n
18
+ def breakdown_data(limit = nil)
19
+ metric_hash = {}
20
+ each_segment_with_nest_tracking do |segment|
21
+ unless segment == root_segment
22
+ metric_name = segment.metric_name
23
+ metric_hash[metric_name] ||= SegmentSummary.new(metric_name, self)
24
+ metric_hash[metric_name] << segment
25
+ metric_hash[metric_name]
26
+ end
27
+ end
28
+
29
+ data = metric_hash.values
30
+
31
+ data.sort! do |x,y|
32
+ y.exclusive_time <=> x.exclusive_time
33
+ end
34
+
35
+ if limit && data.length > limit
36
+ data = data[0..limit - 1]
37
+ end
38
+
39
+ # add one last segment for the remaining time if any
40
+ remainder = duration
41
+ data.each do |segment|
42
+ remainder -= segment.exclusive_time
43
+ end
44
+
45
+ if (remainder*1000).round > 0
46
+ remainder_summary = SegmentSummary.new('Remainder', self)
47
+ remainder_summary.total_time = remainder_summary.exclusive_time = remainder
48
+ remainder_summary.call_count = 1
49
+ data << remainder_summary
50
+ end
51
+
52
+ data
53
+ end
54
+
55
+ # return an array of sql statements executed by this transaction
56
+ # each element in the array contains [sql, parent_segment_metric_name, duration]
57
+ def sql_segments(show_non_sql_segments = true)
58
+ segments = []
59
+ each_segment do |segment|
60
+ segments << segment if segment[:sql] || segment[:sql_obfuscated] || (show_non_sql_segments && segment[:key])
61
+ end
62
+ segments
63
+ end
64
+
65
+ private
66
+ def time_percentage(regex)
67
+ total = 0
68
+ each_segment do |segment|
69
+ if regex =~ segment.metric_name
70
+ total += segment.duration
71
+ end
72
+ end
73
+ fraction = 100.0 * total / duration
74
+ # percent value rounded to two digits:
75
+ return (100 * fraction).round / 100.0
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class Transaction
5
+
6
+ def apdex_bucket(duration)
7
+ Transaction.apdex_bucket(duration, had_error?, apdex_t)
8
+ end
9
+
10
+ def apdex_t
11
+ transaction_specific_apdex_t || Agent.config[:apdex_t]
12
+ end
13
+
14
+ def transaction_specific_apdex_t
15
+ key = :web_transactions_apdex
16
+ Agent.config[key] && Agent.config[key][best_name]
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class Transaction
5
+
6
+ def cpu_burn
7
+ normal_cpu_burn || jruby_cpu_burn
8
+ end
9
+
10
+ def normal_cpu_burn
11
+ return unless @process_cpu_start
12
+ process_cpu - @process_cpu_start
13
+ end
14
+
15
+ def process_cpu
16
+ return nil if defined? JRuby
17
+ p = Process.times
18
+ p.stime + p.utime
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+
3
+ module OneApm
4
+ class Transaction
5
+ module TransactionFinishAppend
6
+
7
+ def append_cat_info(state, duration, payload)
8
+ return unless include_guid?(state, duration)
9
+ payload[:guid] = guid
10
+
11
+ return unless state.is_cross_app?
12
+ trip_id = cat_trip_id(state)
13
+ path_hash = cat_path_hash(state)
14
+ referring_path_hash = cat_referring_path_hash(state)
15
+
16
+ payload[:cat_trip_id] = trip_id if trip_id
17
+ payload[:cat_referring_path_hash] = referring_path_hash if referring_path_hash
18
+
19
+ if path_hash
20
+ payload[:cat_path_hash] = path_hash
21
+
22
+ alternate_path_hashes = cat_path_hashes - [path_hash]
23
+ unless alternate_path_hashes.empty?
24
+ payload[:cat_alternate_path_hashes] = alternate_path_hashes
25
+ end
26
+ end
27
+ end
28
+
29
+ def append_apdex_perf_zone(duration, payload)
30
+ return unless recording_web_transaction?
31
+
32
+ bucket = apdex_bucket(duration)
33
+ bucket_str = case bucket
34
+ when :apdex_s then Transaction::APDEX_S
35
+ when :apdex_t then Transaction::APDEX_T
36
+ when :apdex_f then Transaction::APDEX_F
37
+ else nil
38
+ end
39
+ payload[:apdex_perf_zone] = bucket_str if bucket_str
40
+ end
41
+
42
+ def append_referring_transaction_guid_to(state, payload)
43
+ referring_guid = OneApm::Agent.instance.cross_app_monitor.client_referring_transaction_guid(state)
44
+ if referring_guid
45
+ payload[:referring_transaction_guid] = referring_guid
46
+ end
47
+ end
48
+
49
+ def append_http_response_code(payload)
50
+ payload[:http_response_code] = http_response_code if http_response_code
51
+ end
52
+
53
+ def append_synthetics_to(state, payload)
54
+ return unless is_synthetics_request?
55
+
56
+ payload[:synthetics_resource_id] = synthetics_resource_id
57
+ payload[:synthetics_job_id] = synthetics_job_id
58
+ payload[:synthetics_monitor_id] = synthetics_monitor_id
59
+ end
60
+
61
+ def include_guid?(state, duration)
62
+ state.is_cross_app? || is_synthetics_request?
63
+ end
64
+
65
+ end
66
+ end
67
+ end