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.
- checksums.yaml +7 -0
- data/.gitignore +30 -0
- data/.rubocop.yml +725 -0
- data/Gemfile +3 -0
- data/Guardfile +7 -0
- data/LICENSE +1 -0
- data/README.md +3 -0
- data/config/cert/cacert.pem +1177 -0
- data/config/database.yml +5 -0
- data/lib/initializers/goliath.rb +11 -0
- data/lib/initializers/other.rb +1 -0
- data/lib/initializers/rails.rb +15 -0
- data/lib/one_apm/agent.rb +253 -0
- data/lib/one_apm/agent/agent.rb +283 -0
- data/lib/one_apm/agent/agent/connect.rb +175 -0
- data/lib/one_apm/agent/agent/container_data_manager.rb +218 -0
- data/lib/one_apm/agent/agent/forkable_dispatcher_functions.rb +96 -0
- data/lib/one_apm/agent/agent/helpers.rb +45 -0
- data/lib/one_apm/agent/agent/start.rb +226 -0
- data/lib/one_apm/agent/agent/start_worker_thread.rb +148 -0
- data/lib/one_apm/agent/busy_calculator.rb +115 -0
- data/lib/one_apm/agent/cross_app/cross_app_monitor.rb +181 -0
- data/lib/one_apm/agent/cross_app/cross_app_tracing.rb +336 -0
- data/lib/one_apm/agent/database.rb +308 -0
- data/lib/one_apm/agent/database/active_record_helper.rb +80 -0
- data/lib/one_apm/agent/database/obfuscation_helpers.rb +76 -0
- data/lib/one_apm/agent/database/obfuscator.rb +78 -0
- data/lib/one_apm/agent/database/postgres_explain_obfuscator.rb +45 -0
- data/lib/one_apm/agent/datastores.rb +175 -0
- data/lib/one_apm/agent/datastores/metric_helper.rb +83 -0
- data/lib/one_apm/agent/datastores/mongo.rb +27 -0
- data/lib/one_apm/agent/datastores/mongo/metric_translator.rb +189 -0
- data/lib/one_apm/agent/datastores/mongo/obfuscator.rb +37 -0
- data/lib/one_apm/agent/datastores/mongo/statement_formatter.rb +51 -0
- data/lib/one_apm/agent/event/event_listener.rb +40 -0
- data/lib/one_apm/agent/event/event_loop.rb +191 -0
- data/lib/one_apm/agent/event/worker_loop.rb +97 -0
- data/lib/one_apm/agent/harvester.rb +48 -0
- data/lib/one_apm/agent/inbound_request_monitor.rb +30 -0
- data/lib/one_apm/agent/javascript_instrumentor.rb +186 -0
- data/lib/one_apm/agent/pipe/pipe_channel_manager.rb +275 -0
- data/lib/one_apm/agent/pipe/pipe_service.rb +81 -0
- data/lib/one_apm/agent/sampler.rb +55 -0
- data/lib/one_apm/agent/sampler_collection.rb +65 -0
- data/lib/one_apm/agent/samplers/cpu_sampler.rb +49 -0
- data/lib/one_apm/agent/samplers/delayed_job_sampler.rb +109 -0
- data/lib/one_apm/agent/samplers/memory_sampler.rb +144 -0
- data/lib/one_apm/agent/samplers/object_sampler.rb +22 -0
- data/lib/one_apm/agent/samplers/vm_sampler.rb +124 -0
- data/lib/one_apm/agent/synthetics_monitor.rb +48 -0
- data/lib/one_apm/agent/threading/agent_thread.rb +74 -0
- data/lib/one_apm/agent/threading/backtrace_node.rb +133 -0
- data/lib/one_apm/agent/threading/backtrace_service.rb +259 -0
- data/lib/one_apm/agent/threading/thread_profile.rb +155 -0
- data/lib/one_apm/collector/collector/helper.rb +139 -0
- data/lib/one_apm/collector/collector/http_connection.rb +254 -0
- data/lib/one_apm/collector/collector/server_methods.rb +71 -0
- data/lib/one_apm/collector/collector_service.rb +123 -0
- data/lib/one_apm/collector/commands/agent_command.rb +17 -0
- data/lib/one_apm/collector/commands/thread_profiler_session.rb +108 -0
- data/lib/one_apm/collector/commands/xray_session.rb +53 -0
- data/lib/one_apm/collector/commands/xray_session_collection.rb +156 -0
- data/lib/one_apm/collector/containers/agent_command_router.rb +153 -0
- data/lib/one_apm/collector/containers/custom_event_aggregator.rb +94 -0
- data/lib/one_apm/collector/containers/error_collector.rb +349 -0
- data/lib/one_apm/collector/containers/sql_sampler.rb +331 -0
- data/lib/one_apm/collector/containers/stats_engine.rb +34 -0
- data/lib/one_apm/collector/containers/transaction_event_aggregator.rb +249 -0
- data/lib/one_apm/collector/containers/transaction_sampler.rb +352 -0
- data/lib/one_apm/collector/containers/utilization_data.rb +36 -0
- data/lib/one_apm/collector/stats_engine/gc_profiler.rb +106 -0
- data/lib/one_apm/collector/stats_engine/metric_stats.rb +243 -0
- data/lib/one_apm/collector/stats_engine/stats_hash.rb +105 -0
- data/lib/one_apm/configuration.rb +429 -0
- data/lib/one_apm/configuration/autostart.rb +41 -0
- data/lib/one_apm/configuration/default_source.rb +1026 -0
- data/lib/one_apm/configuration/environment_source.rb +113 -0
- data/lib/one_apm/configuration/high_security_source.rb +56 -0
- data/lib/one_apm/configuration/manual_source.rb +13 -0
- data/lib/one_apm/configuration/server_source.rb +60 -0
- data/lib/one_apm/configuration/yaml_source.rb +134 -0
- data/lib/one_apm/errors/agent_errors.rb +26 -0
- data/lib/one_apm/errors/internal_agent_error.rb +16 -0
- data/lib/one_apm/errors/noticed_error.rb +79 -0
- data/lib/one_apm/frameworks/external.rb +15 -0
- data/lib/one_apm/frameworks/rails.rb +103 -0
- data/lib/one_apm/frameworks/rails3.rb +37 -0
- data/lib/one_apm/frameworks/rails4.rb +21 -0
- data/lib/one_apm/frameworks/ruby.rb +21 -0
- data/lib/one_apm/frameworks/sinatra.rb +12 -0
- data/lib/one_apm/inst/3rd/active_merchant.rb +35 -0
- data/lib/one_apm/inst/3rd/acts_as_solr.rb +70 -0
- data/lib/one_apm/inst/3rd/authlogic.rb +23 -0
- data/lib/one_apm/inst/3rd/sunspot.rb +31 -0
- data/lib/one_apm/inst/background_job/active_job.rb +88 -0
- data/lib/one_apm/inst/background_job/delayed_job.rb +52 -0
- data/lib/one_apm/inst/background_job/delayed_job_injection.rb +8 -0
- data/lib/one_apm/inst/background_job/resque.rb +107 -0
- data/lib/one_apm/inst/background_job/sidekiq.rb +64 -0
- data/lib/one_apm/inst/dispatcher/passenger.rb +25 -0
- data/lib/one_apm/inst/dispatcher/rainbows.rb +23 -0
- data/lib/one_apm/inst/framework/grape.rb +94 -0
- data/lib/one_apm/inst/framework/padrino.rb +30 -0
- data/lib/one_apm/inst/framework/sinatra.rb +185 -0
- data/lib/one_apm/inst/framework/sinatra/ignorer.rb +50 -0
- data/lib/one_apm/inst/framework/sinatra/transaction_namer.rb +54 -0
- data/lib/one_apm/inst/http_clients/curb.rb +189 -0
- data/lib/one_apm/inst/http_clients/excon.rb +70 -0
- data/lib/one_apm/inst/http_clients/excon/connection.rb +31 -0
- data/lib/one_apm/inst/http_clients/excon/middleware.rb +55 -0
- data/lib/one_apm/inst/http_clients/httpclient.rb +44 -0
- data/lib/one_apm/inst/http_clients/net.rb +34 -0
- data/lib/one_apm/inst/http_clients/typhoeus.rb +76 -0
- data/lib/one_apm/inst/nosql/memcache.rb +134 -0
- data/lib/one_apm/inst/nosql/mongo.rb +126 -0
- data/lib/one_apm/inst/nosql/mongo_moped.rb +85 -0
- data/lib/one_apm/inst/nosql/redis.rb +83 -0
- data/lib/one_apm/inst/orm/active_record.rb +99 -0
- data/lib/one_apm/inst/orm/active_record_4.rb +28 -0
- data/lib/one_apm/inst/orm/data_mapper.rb +180 -0
- data/lib/one_apm/inst/orm/sequel.rb +47 -0
- data/lib/one_apm/inst/rack.rb +38 -0
- data/lib/one_apm/inst/rack/rack.rb +44 -0
- data/lib/one_apm/inst/rack/rack_builder.rb +51 -0
- data/lib/one_apm/inst/rails/action_controller.rb +118 -0
- data/lib/one_apm/inst/rails/action_web_service.rb +44 -0
- data/lib/one_apm/inst/rails/errors.rb +43 -0
- data/lib/one_apm/inst/rails3/action_controller.rb +172 -0
- data/lib/one_apm/inst/rails3/errors.rb +43 -0
- data/lib/one_apm/inst/rails4/action_controller.rb +27 -0
- data/lib/one_apm/inst/rails4/action_controller_subscriber.rb +121 -0
- data/lib/one_apm/inst/rails4/action_view.rb +23 -0
- data/lib/one_apm/inst/rails4/action_view_subscriber.rb +93 -0
- data/lib/one_apm/inst/rails4/active_record_subscriber.rb +96 -0
- data/lib/one_apm/inst/rails4/errors.rb +42 -0
- data/lib/one_apm/inst/rails_middleware.rb +40 -0
- data/lib/one_apm/inst/support/evented_subscriber.rb +98 -0
- data/lib/one_apm/inst/support/ignore_actions.rb +39 -0
- data/lib/one_apm/inst/support/queue_time.rb +76 -0
- data/lib/one_apm/inst/transaction_base.rb +405 -0
- data/lib/one_apm/logger/agent_logger.rb +206 -0
- data/lib/one_apm/logger/audit_logger.rb +78 -0
- data/lib/one_apm/logger/memory_logger.rb +50 -0
- data/lib/one_apm/logger/null_logger.rb +19 -0
- data/lib/one_apm/metrics/metric_data.rb +72 -0
- data/lib/one_apm/metrics/metric_spec.rb +82 -0
- data/lib/one_apm/metrics/stats.rb +173 -0
- data/lib/one_apm/probe.rb +16 -0
- data/lib/one_apm/probe/framework_loader.rb +53 -0
- data/lib/one_apm/probe/instance_methods.rb +105 -0
- data/lib/one_apm/probe/instrumentation.rb +60 -0
- data/lib/one_apm/rack/browser_monitoring.rb +144 -0
- data/lib/one_apm/rack/middleware_base.rb +27 -0
- data/lib/one_apm/rack/middleware_hooks.rb +17 -0
- data/lib/one_apm/rack/middleware_tracing.rb +81 -0
- data/lib/one_apm/rack/middleware_wrapper.rb +86 -0
- data/lib/one_apm/support/chained_call.rb +15 -0
- data/lib/one_apm/support/coerce.rb +81 -0
- data/lib/one_apm/support/collection_helper.rb +79 -0
- data/lib/one_apm/support/dotted_hash.rb +45 -0
- data/lib/one_apm/support/encoders.rb +34 -0
- data/lib/one_apm/support/environment_report.rb +127 -0
- data/lib/one_apm/support/event_buffer.rb +82 -0
- data/lib/one_apm/support/event_buffer/sampled_buffer.rb +45 -0
- data/lib/one_apm/support/event_buffer/sized_buffer.rb +21 -0
- data/lib/one_apm/support/event_buffer/synthetics_event_buffer.rb +40 -0
- data/lib/one_apm/support/helper.rb +49 -0
- data/lib/one_apm/support/hostname.rb +13 -0
- data/lib/one_apm/support/http_clients/curb_wrappers.rb +65 -0
- data/lib/one_apm/support/http_clients/excon_wrappers.rb +63 -0
- data/lib/one_apm/support/http_clients/httpclient_wrappers.rb +61 -0
- data/lib/one_apm/support/http_clients/net_http_wrappers.rb +48 -0
- data/lib/one_apm/support/http_clients/typhoeus_wrappers.rb +73 -0
- data/lib/one_apm/support/http_clients/uri_util.rb +39 -0
- data/lib/one_apm/support/json_marshaller.rb +68 -0
- data/lib/one_apm/support/json_wrapper.rb +130 -0
- data/lib/one_apm/support/language_support.rb +142 -0
- data/lib/one_apm/support/library_detection.rb +119 -0
- data/lib/one_apm/support/local_environment.rb +196 -0
- data/lib/one_apm/support/marshaller.rb +62 -0
- data/lib/one_apm/support/method_tracer.rb +334 -0
- data/lib/one_apm/support/method_tracer/helpers.rb +92 -0
- data/lib/one_apm/support/method_tracer/traced_method_stack.rb +103 -0
- data/lib/one_apm/support/obfuscator.rb +47 -0
- data/lib/one_apm/support/okjson.rb +601 -0
- data/lib/one_apm/support/parameter_filtering.rb +35 -0
- data/lib/one_apm/support/rules_engine.rb +56 -0
- data/lib/one_apm/support/rules_engine/replacement_rule.rb +80 -0
- data/lib/one_apm/support/rules_engine/segment_terms_rule.rb +46 -0
- data/lib/one_apm/support/server.rb +11 -0
- data/lib/one_apm/support/supported_versions.rb +257 -0
- data/lib/one_apm/support/system_info.rb +211 -0
- data/lib/one_apm/support/timer_lib.rb +29 -0
- data/lib/one_apm/support/version_number.rb +51 -0
- data/lib/one_apm/support/vm.rb +30 -0
- data/lib/one_apm/support/vm/jruby_vm.rb +38 -0
- data/lib/one_apm/support/vm/monotonic_gc_profiler.rb +43 -0
- data/lib/one_apm/support/vm/mri_vm.rb +85 -0
- data/lib/one_apm/support/vm/rubinius_vm.rb +129 -0
- data/lib/one_apm/support/vm/snapshot.rb +18 -0
- data/lib/one_apm/transaction.rb +336 -0
- data/lib/one_apm/transaction/class_methods.rb +132 -0
- data/lib/one_apm/transaction/instance_helpers.rb +82 -0
- data/lib/one_apm/transaction/metric_constants.rb +42 -0
- data/lib/one_apm/transaction/sample_buffer/force_persist_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/slowest_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/synthetics_sample_buffer.rb +21 -0
- data/lib/one_apm/transaction/sample_buffer/transaction_sample_buffer.rb +101 -0
- data/lib/one_apm/transaction/sample_buffer/xray_sample_buffer.rb +60 -0
- data/lib/one_apm/transaction/segment.rb +193 -0
- data/lib/one_apm/transaction/segment_summary.rb +51 -0
- data/lib/one_apm/transaction/thread_local_access.rb +73 -0
- data/lib/one_apm/transaction/transaction_analysis.rb +78 -0
- data/lib/one_apm/transaction/transaction_apdex.rb +20 -0
- data/lib/one_apm/transaction/transaction_cpu.rb +22 -0
- data/lib/one_apm/transaction/transaction_finish_append.rb +67 -0
- data/lib/one_apm/transaction/transaction_ignore.rb +33 -0
- data/lib/one_apm/transaction/transaction_jruby_functions.rb +40 -0
- data/lib/one_apm/transaction/transaction_metrics.rb +53 -0
- data/lib/one_apm/transaction/transaction_name.rb +90 -0
- data/lib/one_apm/transaction/transaction_namer.rb +49 -0
- data/lib/one_apm/transaction/transaction_sample.rb +204 -0
- data/lib/one_apm/transaction/transaction_sample_builder.rb +168 -0
- data/lib/one_apm/transaction/transaction_state.rb +149 -0
- data/lib/one_apm/transaction/transaction_summary.rb +28 -0
- data/lib/one_apm/transaction/transaction_synthetics.rb +40 -0
- data/lib/one_apm/transaction/transaction_timings.rb +54 -0
- data/lib/one_apm/version.rb +13 -0
- data/lib/oneapm_rpm.rb +16 -0
- data/lib/sequel/extensions/oneapm_instrumentation.rb +84 -0
- data/lib/sequel/plugins/oneapm_instrumentation.rb +66 -0
- data/oneapm.yml +135 -0
- data/oneapm_rpm.gemspec +58 -0
- 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
|