scout_apm 2.2.0.pre3 → 2.3.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/CHANGELOG.markdown +147 -2
  4. data/Guardfile +43 -0
  5. data/Rakefile +2 -2
  6. data/ext/allocations/allocations.c +6 -0
  7. data/ext/allocations/extconf.rb +1 -0
  8. data/ext/rusage/README.md +26 -0
  9. data/ext/rusage/extconf.rb +5 -0
  10. data/ext/rusage/rusage.c +52 -0
  11. data/lib/scout_apm.rb +28 -15
  12. data/lib/scout_apm/agent.rb +89 -37
  13. data/lib/scout_apm/agent/logging.rb +6 -1
  14. data/lib/scout_apm/agent/reporting.rb +9 -6
  15. data/lib/scout_apm/app_server_load.rb +21 -10
  16. data/lib/scout_apm/attribute_arranger.rb +6 -3
  17. data/lib/scout_apm/background_job_integrations/delayed_job.rb +71 -1
  18. data/lib/scout_apm/background_job_integrations/resque.rb +85 -0
  19. data/lib/scout_apm/background_job_integrations/sidekiq.rb +22 -20
  20. data/lib/scout_apm/background_recorder.rb +43 -0
  21. data/lib/scout_apm/background_worker.rb +19 -15
  22. data/lib/scout_apm/config.rb +138 -28
  23. data/lib/scout_apm/db_query_metric_set.rb +80 -0
  24. data/lib/scout_apm/db_query_metric_stats.rb +102 -0
  25. data/lib/scout_apm/debug.rb +37 -0
  26. data/lib/scout_apm/environment.rb +22 -15
  27. data/lib/scout_apm/git_revision.rb +51 -0
  28. data/lib/scout_apm/histogram.rb +11 -2
  29. data/lib/scout_apm/instant/assets/xmlhttp_instrumentation.html +2 -2
  30. data/lib/scout_apm/instant/middleware.rb +196 -54
  31. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +89 -68
  32. data/lib/scout_apm/instruments/action_view.rb +49 -0
  33. data/lib/scout_apm/instruments/active_record.rb +127 -3
  34. data/lib/scout_apm/instruments/grape.rb +4 -3
  35. data/lib/scout_apm/instruments/middleware_detailed.rb +4 -6
  36. data/lib/scout_apm/instruments/mongoid.rb +24 -3
  37. data/lib/scout_apm/instruments/net_http.rb +7 -2
  38. data/lib/scout_apm/instruments/percentile_sampler.rb +36 -19
  39. data/lib/scout_apm/instruments/process/process_cpu.rb +3 -2
  40. data/lib/scout_apm/instruments/process/process_memory.rb +3 -3
  41. data/lib/scout_apm/instruments/resque.rb +40 -0
  42. data/lib/scout_apm/layaway.rb +67 -28
  43. data/lib/scout_apm/layer.rb +19 -59
  44. data/lib/scout_apm/layer_children_set.rb +77 -0
  45. data/lib/scout_apm/layer_converters/allocation_metric_converter.rb +5 -6
  46. data/lib/scout_apm/layer_converters/converter_base.rb +201 -14
  47. data/lib/scout_apm/layer_converters/database_converter.rb +55 -0
  48. data/lib/scout_apm/layer_converters/depth_first_walker.rb +22 -10
  49. data/lib/scout_apm/layer_converters/error_converter.rb +5 -7
  50. data/lib/scout_apm/layer_converters/find_layer_by_type.rb +34 -0
  51. data/lib/scout_apm/layer_converters/histograms.rb +14 -0
  52. data/lib/scout_apm/layer_converters/job_converter.rb +36 -50
  53. data/lib/scout_apm/layer_converters/metric_converter.rb +17 -19
  54. data/lib/scout_apm/layer_converters/request_queue_time_converter.rb +10 -12
  55. data/lib/scout_apm/layer_converters/slow_job_converter.rb +41 -115
  56. data/lib/scout_apm/layer_converters/slow_request_converter.rb +33 -117
  57. data/lib/scout_apm/limited_layer.rb +126 -0
  58. data/lib/scout_apm/metric_meta.rb +0 -5
  59. data/lib/scout_apm/metric_set.rb +9 -1
  60. data/lib/scout_apm/metric_stats.rb +7 -8
  61. data/lib/scout_apm/rack.rb +26 -0
  62. data/lib/scout_apm/remote/message.rb +23 -0
  63. data/lib/scout_apm/remote/recorder.rb +57 -0
  64. data/lib/scout_apm/remote/router.rb +49 -0
  65. data/lib/scout_apm/remote/server.rb +58 -0
  66. data/lib/scout_apm/reporter.rb +51 -15
  67. data/lib/scout_apm/request_histograms.rb +4 -0
  68. data/lib/scout_apm/request_manager.rb +2 -1
  69. data/lib/scout_apm/scored_item_set.rb +7 -0
  70. data/lib/scout_apm/serializers/db_query_serializer_to_json.rb +15 -0
  71. data/lib/scout_apm/serializers/histograms_serializer_to_json.rb +21 -0
  72. data/lib/scout_apm/serializers/payload_serializer.rb +10 -3
  73. data/lib/scout_apm/serializers/payload_serializer_to_json.rb +6 -6
  74. data/lib/scout_apm/serializers/slow_jobs_serializer_to_json.rb +2 -1
  75. data/lib/scout_apm/server_integrations/puma.rb +5 -2
  76. data/lib/scout_apm/slow_job_policy.rb +1 -10
  77. data/lib/scout_apm/slow_job_record.rb +6 -1
  78. data/lib/scout_apm/slow_request_policy.rb +1 -10
  79. data/lib/scout_apm/slow_transaction.rb +20 -2
  80. data/lib/scout_apm/store.rb +66 -12
  81. data/lib/scout_apm/synchronous_recorder.rb +26 -0
  82. data/lib/scout_apm/tracked_request.rb +136 -71
  83. data/lib/scout_apm/utils/active_record_metric_name.rb +8 -4
  84. data/lib/scout_apm/utils/backtrace_parser.rb +3 -3
  85. data/lib/scout_apm/utils/gzip_helper.rb +24 -0
  86. data/lib/scout_apm/utils/numbers.rb +14 -0
  87. data/lib/scout_apm/utils/scm.rb +14 -0
  88. data/lib/scout_apm/version.rb +1 -1
  89. data/scout_apm.gemspec +5 -4
  90. data/test/test_helper.rb +18 -0
  91. data/test/unit/config_test.rb +59 -8
  92. data/test/unit/db_query_metric_set_test.rb +56 -0
  93. data/test/unit/db_query_metric_stats_test.rb +113 -0
  94. data/test/unit/git_revision_test.rb +15 -0
  95. data/test/unit/histogram_test.rb +14 -0
  96. data/test/unit/instruments/net_http_test.rb +21 -0
  97. data/test/unit/instruments/percentile_sampler_test.rb +137 -0
  98. data/test/unit/layaway_test.rb +20 -0
  99. data/test/unit/layer_children_set_test.rb +88 -0
  100. data/test/unit/layer_converters/depth_first_walker_test.rb +66 -0
  101. data/test/unit/layer_converters/metric_converter_test.rb +22 -0
  102. data/test/unit/layer_converters/stubs.rb +33 -0
  103. data/test/unit/limited_layer_test.rb +53 -0
  104. data/test/unit/remote/test_message.rb +13 -0
  105. data/test/unit/remote/test_router.rb +33 -0
  106. data/test/unit/remote/test_server.rb +15 -0
  107. data/test/unit/serializers/payload_serializer_test.rb +3 -12
  108. data/test/unit/store_test.rb +66 -0
  109. data/test/unit/test_tracked_request.rb +87 -0
  110. data/test/unit/utils/active_record_metric_name_test.rb +8 -0
  111. data/test/unit/utils/backtrace_parser_test.rb +5 -0
  112. data/test/unit/utils/numbers_test.rb +15 -0
  113. data/test/unit/utils/scm.rb +17 -0
  114. metadata +125 -30
  115. data/ext/stacks/extconf.rb +0 -37
  116. data/ext/stacks/scout_atomics.h +0 -86
  117. data/ext/stacks/stacks.c +0 -811
  118. data/lib/scout_apm/capacity.rb +0 -57
  119. data/lib/scout_apm/deploy_integrations/capistrano_2.cap +0 -12
  120. data/lib/scout_apm/deploy_integrations/capistrano_2.rb +0 -83
  121. data/lib/scout_apm/deploy_integrations/capistrano_3.cap +0 -12
  122. data/lib/scout_apm/deploy_integrations/capistrano_3.rb +0 -88
  123. data/lib/scout_apm/instruments/delayed_job.rb +0 -57
  124. data/lib/scout_apm/serializers/deploy_serializer.rb +0 -16
  125. data/lib/scout_apm/trace_compactor.rb +0 -312
  126. data/lib/scout_apm/utils/fake_stacks.rb +0 -87
  127. data/tester.rb +0 -53
@@ -22,12 +22,17 @@ module ScoutApm
22
22
  include ScoutApm::Tracer
23
23
 
24
24
  def request_with_scout_instruments(*args,&block)
25
- url = (@address + args.first.path.split('?').first)[0..99]
26
- self.class.instrument("HTTP", "request", :desc => url) do
25
+ self.class.instrument("HTTP", "request", :desc => request_scout_description(args.first)) do
27
26
  request_without_scout_instruments(*args, &block)
28
27
  end
29
28
  end
30
29
 
30
+ def request_scout_description(req)
31
+ path = req.path
32
+ path = path.path if path.respond_to?(:path)
33
+ (@address + path.split('?').first)[0..99]
34
+ end
35
+
31
36
  alias request_without_scout_instruments request
32
37
  alias request request_with_scout_instruments
33
38
  end
@@ -1,36 +1,53 @@
1
1
  module ScoutApm
2
2
  module Instruments
3
+
4
+ class HistogramReport
5
+ attr_reader :name
6
+ attr_reader :histogram
7
+
8
+ def initialize(name, histogram)
9
+ @name = name
10
+ @histogram = histogram
11
+ end
12
+
13
+ def combine!(other)
14
+ raise "Mismatched Histogram Names" unless name == other.name
15
+ histogram.combine!(other.histogram)
16
+ self
17
+ end
18
+ end
19
+
3
20
  class PercentileSampler
4
21
  attr_reader :logger
5
22
 
6
- attr_reader :percentiles
23
+ # A hash of { time => RequestHistograms }
24
+ attr_reader :histograms
7
25
 
8
- def initialize(logger, percentiles)
26
+ def initialize(logger, histograms)
9
27
  @logger = logger
10
- @percentiles = Array(percentiles)
28
+ @histograms = histograms
11
29
  end
12
30
 
13
31
  def human_name
14
- "Percentiles"
32
+ 'Percentiles'
15
33
  end
16
34
 
17
- # Gets the 95th%ile for the time requested
18
- def metrics(time)
19
- ms = {}
20
- histos = ScoutApm::Agent.instance.request_histograms_by_time[time]
21
- histos.each_name do |name|
22
- percentiles.each do |percentile|
23
- meta = MetricMeta.new("Percentile/#{percentile}/#{name}")
24
- stat = MetricStats.new
25
- stat.update!(histos.quantile(name, percentile))
26
- ms[meta] = stat
27
- end
28
- end
35
+ def metrics(timestamp, store)
36
+ store.track_histograms!(percentiles(timestamp), :timestamp => timestamp)
37
+ end
38
+
39
+ def percentiles(time)
40
+ result = []
29
41
 
30
- # Wipe the histograms we just collected data on
31
- ScoutApm::Agent.instance.request_histograms_by_time.delete(time)
42
+ histogram = histograms.delete(time)
43
+
44
+ return result unless histogram
45
+
46
+ histogram.each_name do |name|
47
+ result << HistogramReport.new(name, histogram.raw(name))
48
+ end
32
49
 
33
- ms
50
+ result
34
51
  end
35
52
  end
36
53
  end
@@ -29,16 +29,17 @@ module ScoutApm
29
29
  "Process CPU"
30
30
  end
31
31
 
32
- def metrics(_time)
32
+ def metrics(timestamp, store)
33
33
  result = run
34
34
  if result
35
35
  meta = MetricMeta.new("#{metric_type}/#{metric_name}")
36
36
  stat = MetricStats.new(false)
37
37
  stat.update!(result)
38
- { meta => stat }
38
+ store.track!({ meta => stat }, :timestamp => timestamp)
39
39
  else
40
40
  {}
41
41
  end
42
+
42
43
  end
43
44
 
44
45
  # TODO: Figure out a good default instead of nil
@@ -33,20 +33,20 @@ module ScoutApm
33
33
  "Process Memory"
34
34
  end
35
35
 
36
- def metrics(_time)
36
+ def metrics(timestamp, store)
37
37
  result = run
38
38
  if result
39
39
  meta = MetricMeta.new("#{metric_type}/#{metric_name}")
40
40
  stat = MetricStats.new(false)
41
41
  stat.update!(result)
42
- { meta => stat }
42
+ store.track!({ meta => stat }, :timestamp => timestamp)
43
43
  else
44
44
  {}
45
45
  end
46
46
  end
47
47
 
48
48
  def run
49
- self.class.rss_in_mb.tap { |res| logger.debug "#{human_name}: #{res.inspect}" }
49
+ self.class.rss_in_mb.tap { |res| logger.debug "#{human_name}: #{res.inspect}" }
50
50
  end
51
51
  end
52
52
  end
@@ -0,0 +1,40 @@
1
+ module ScoutApm
2
+ module Instruments
3
+ module Resque
4
+ def around_perform_with_scout_instruments(*args)
5
+ job_name = self.to_s
6
+ queue = find_queue
7
+
8
+ if job_name == "ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper"
9
+ job_name = args.first["job_class"] rescue job_name
10
+ queue = args.first["queue_name"] rescue queue_name
11
+ end
12
+
13
+ req = ScoutApm::RequestManager.lookup
14
+ req.job!
15
+
16
+ begin
17
+ req.start_layer(ScoutApm::Layer.new('Queue', queue))
18
+ started_queue = true
19
+ req.start_layer(ScoutApm::Layer.new('Job', job_name))
20
+ started_job = true
21
+
22
+ yield
23
+ rescue => e
24
+ req.error!
25
+ raise
26
+ ensure
27
+ req.stop_layer if started_job
28
+ req.stop_layer if started_queue
29
+ end
30
+ end
31
+
32
+ def find_queue
33
+ return @queue if @queue
34
+ return queue if self.respond_to?(:queue)
35
+ return "unknown"
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -7,13 +7,13 @@
7
7
  #
8
8
  module ScoutApm
9
9
  class Layaway
10
- # How old a file needs to be in Seconds before it gets reported.
11
- REPORTING_AGE = 120
12
-
13
10
  # How long to let a stale file sit before deleting it.
14
11
  # Letting it sit a bit may be useful for debugging
15
12
  STALE_AGE = 10 * 60
16
13
 
14
+ # Failsafe to prevent writing layaway files if for some reason they are not being cleaned up
15
+ MAX_FILES_LIMIT = 5000
16
+
17
17
  # A strftime format string for how we render timestamps in filenames.
18
18
  # Must be sortable as an integer
19
19
  TIME_FORMAT = "%Y%m%d%H%M"
@@ -48,7 +48,11 @@ module ScoutApm
48
48
  @directory = Pathname.new(found)
49
49
  end
50
50
 
51
- def write_reporting_period(reporting_period)
51
+ def write_reporting_period(reporting_period, files_limit = MAX_FILES_LIMIT)
52
+ if at_layaway_file_limit?(files_limit)
53
+ ScoutApm::Agent.instance.logger.error("Hit layaway file limit. Not writing to layaway file")
54
+ return false
55
+ end
52
56
  filename = file_for(reporting_period.timestamp)
53
57
  layaway_file = LayawayFile.new(filename)
54
58
  layaway_file.write(reporting_period)
@@ -60,41 +64,56 @@ module ScoutApm
60
64
  def with_claim(timestamp)
61
65
  coordinator_file = glob_pattern(timestamp, :coordinator)
62
66
 
63
-
64
- # This file gets deleted only by a process that successfully obtained a lock
65
- f = File.open(coordinator_file, File::RDWR | File::CREAT)
66
67
  begin
67
- # Nonblocking, Exclusive lock.
68
- if f.flock(File::LOCK_EX | File::LOCK_NB)
69
-
70
- ScoutApm::Agent.instance.logger.debug("Obtained Reporting Lock")
71
-
72
- files = all_files_for(timestamp).reject{|l| l.to_s == coordinator_file.to_s }
73
- rps = files.map{ |layaway| LayawayFile.new(layaway).load }.compact
74
- if rps.any?
75
- yield rps
68
+ # This file gets deleted only by a process that successfully created and obtained the exclusive lock
69
+ f = File.open(coordinator_file, File::RDWR | File::CREAT | File::EXCL | File::NONBLOCK)
70
+ rescue Errno::EEXIST
71
+ false
72
+ end
76
73
 
77
- delete_files_for(timestamp) # also removes the coodinator_file
78
- delete_stale_files(timestamp.to_time - STALE_AGE)
79
- else
80
- File.unlink(coordinator_file)
81
- ScoutApm::Agent.instance.logger.debug("No layaway files to report")
74
+ begin
75
+ if f
76
+ begin
77
+ ScoutApm::Agent.instance.logger.debug("Obtained Reporting Lock")
78
+
79
+ log_layaway_file_information
80
+
81
+ files = all_files_for(timestamp).reject{|l| l.to_s == coordinator_file.to_s }
82
+ rps = files.map{ |layaway| LayawayFile.new(layaway).load }.compact
83
+ if rps.any?
84
+ yield rps
85
+
86
+ ScoutApm::Agent.instance.logger.debug("Deleting the now-reported layaway files for #{timestamp.to_s}")
87
+ delete_files_for(timestamp) # also removes the coodinator_file
88
+
89
+ ScoutApm::Agent.instance.logger.debug("Checking for any Stale layaway files")
90
+ delete_stale_files(timestamp.to_time - STALE_AGE)
91
+ else
92
+ File.unlink(coordinator_file)
93
+ ScoutApm::Agent.instance.logger.debug("No layaway files to report")
94
+ end
95
+
96
+ true
97
+ rescue Exception => e
98
+ ScoutApm::Agent.instance.logger.debug("Caught an exception in with_claim, with the coordination file locked: #{e.message}, #{e.backtrace.inspect}")
99
+ raise
100
+ ensure
101
+ # Unlock the file when done!
102
+ f.flock(File::LOCK_UN | File::LOCK_NB)
103
+ f.close
82
104
  end
83
-
84
- # Unlock the file when done!
85
- f.flock(File::LOCK_UN | File::LOCK_NB)
86
- f.close
87
- true
88
105
  else
89
106
  # Didn't obtain lock, another process is reporting. Return false from this function, but otherwise no work
90
- f.close
91
107
  false
92
108
  end
93
109
  end
94
110
  end
95
111
 
96
112
  def delete_files_for(timestamp)
97
- all_files_for(timestamp).each { |layaway| File.unlink(layaway) }
113
+ all_files_for(timestamp).each { |layaway|
114
+ ScoutApm::Agent.instance.logger.debug("Deleting layaway file: #{layaway}")
115
+ File.unlink(layaway)
116
+ }
98
117
  end
99
118
 
100
119
  def delete_stale_files(older_than)
@@ -105,6 +124,8 @@ module ScoutApm
105
124
  select { |timestamp| timestamp.to_i < older_than.strftime(TIME_FORMAT).to_i }.
106
125
  tap { |timestamps| ScoutApm::Agent.instance.logger.debug("Deleting stale layaway files with timestamps: #{timestamps.inspect}") }.
107
126
  map { |timestamp| delete_files_for(timestamp) }
127
+ rescue => e
128
+ ScoutApm::Agent.instance.logger.debug("Problem deleting stale files: #{e.message}, #{e.backtrace.inspect}")
108
129
  end
109
130
 
110
131
  private
@@ -155,6 +176,24 @@ module ScoutApm
155
176
  nil
156
177
  end
157
178
  end
179
+
180
+ def at_layaway_file_limit?(files_limit = MAX_FILES_LIMIT)
181
+ all_files_for(:all).count >= files_limit
182
+ end
183
+
184
+ def log_layaway_file_information
185
+ files_in_temp = Dir["#{directory}/*"].count
186
+
187
+ all_filenames = all_files_for(:all)
188
+ count_per_timestamp = Hash[
189
+ all_filenames.
190
+ group_by {|f| timestamp_from_filename(f) }.
191
+ map{ |timestamp, list| [timestamp, list.length] }
192
+ ]
193
+
194
+
195
+ ScoutApm::Agent.instance.logger.debug("Total in #{directory}: #{files_in_temp}. Total Layaway Files: #{all_filenames.size}. By Timestamp: #{count_per_timestamp.inspect}")
196
+ end
158
197
  end
159
198
  end
160
199
 
@@ -13,13 +13,17 @@ module ScoutApm
13
13
  # instrumentation for an example of how this is useful
14
14
  attr_accessor :name
15
15
 
16
- # An array of children layers, in call order.
16
+ # An array of children layers
17
17
  # For instance, if we are in a middleware, there will likely be only a single
18
18
  # child, which is another middleware. In a Controller, we may have a handful
19
19
  # of children: [ActiveRecord, ActiveRecord, View, HTTP Call].
20
20
  #
21
21
  # This useful to get actual time spent in this layer vs. children time
22
- attr_reader :children
22
+ #
23
+ # TODO: Check callers for compatibility w/ nil to avoid making an empty array
24
+ def children
25
+ @children || LayerChildrenSet.new
26
+ end
23
27
 
24
28
  # Time objects recording the start & stop times of this layer
25
29
  attr_reader :start_time, :stop_time
@@ -38,41 +42,31 @@ module ScoutApm
38
42
  # Known Keys:
39
43
  # :record_count - The number of rows returned by an AR query (From notification instantiation.active_record)
40
44
  # :class_name - The ActiveRecord class name (From notification instantiation.active_record)
45
+ #
46
+ # If no annotations are ever set, this will return nil
41
47
  attr_reader :annotations
42
48
 
43
- # ScoutProf - trace_index is an index into the Stack structure in the C
44
- # code, used to store captured traces.
45
- attr_reader :trace_index
46
-
47
- # ScoutProf - frame_index is an optimization to not capture a few frames
48
- # during scoutprof instrumentation
49
- attr_reader :frame_index
50
-
51
- # Captured backtraces from ScoutProf. This is distinct from the backtrace
52
- # attribute, which gets the ruby backtrace of any given layer. StackProf
53
- # focuses on Controller layers, and requires a native extension and a
54
- # reasonably recent Ruby.
55
- attr_reader :traces
56
-
57
49
  BACKTRACE_CALLER_LIMIT = 50 # maximum number of lines to send thru for backtrace analysis
58
50
 
59
51
  def initialize(type, name, start_time = Time.now)
60
52
  @type = type
61
53
  @name = name
62
- @annotations = {}
63
54
  @start_time = start_time
64
55
  @allocations_start = ScoutApm::Instruments::Allocations.count
65
56
  @allocations_stop = 0
66
- @children = [] # In order of calls
57
+
58
+ # initialize these only on first use
59
+ @children = nil
60
+ @annotations = nil
67
61
  @desc = nil
62
+ end
68
63
 
69
- @traces = ScoutApm::TraceSet.new
70
- @raw_frames = []
71
- @frame_index = ScoutApm::Instruments::Stacks.current_frame_index # For efficiency sake, try to skip the bottom X frames when collecting traces
72
- @trace_index = ScoutApm::Instruments::Stacks.current_trace_index
64
+ def limited?
65
+ false
73
66
  end
74
67
 
75
68
  def add_child(child)
69
+ @children ||= LayerChildrenSet.new
76
70
  @children << child
77
71
  end
78
72
 
@@ -91,6 +85,7 @@ module ScoutApm
91
85
 
92
86
  # This data is internal to ScoutApm, to add custom information, use the Context api.
93
87
  def annotate_layer(hsh)
88
+ @annotations ||= {}
94
89
  @annotations.merge!(hsh)
95
90
  end
96
91
 
@@ -102,14 +97,6 @@ module ScoutApm
102
97
  @subscopable
103
98
  end
104
99
 
105
- def traced!
106
- @traced = true
107
- end
108
-
109
- def traced?
110
- @traced
111
- end
112
-
113
100
  # This is the old style name. This function is used for now, but should be
114
101
  # removed, and the new type & name split should be enforced through the
115
102
  # app.
@@ -131,35 +118,6 @@ module ScoutApm
131
118
  end
132
119
  end
133
120
 
134
- # Set the name of the file that this action is coming from.
135
- # TraceSet uses this to more accurately filter backtraces
136
- def set_root_class(klass_name)
137
- @traces.set_root_class(klass_name)
138
- end
139
-
140
- def start_sampling
141
- if ScoutApm::Agent.instance.config.value('profile') && traced?
142
- ScoutApm::Instruments::Stacks.update_indexes(frame_index, trace_index)
143
- ScoutApm::Instruments::Stacks.start_sampling
144
- else
145
- ScoutApm::Instruments::Stacks.stop_sampling(false)
146
- end
147
- end
148
-
149
- def record_traces!
150
- if ScoutApm::Agent.instance.config.value('profile')
151
- ScoutApm::Instruments::Stacks.stop_sampling(false)
152
- if traced?
153
- traces.raw_traces = ScoutApm::Instruments::Stacks.profile_frames
154
- traces.skipped_in_gc = ScoutApm::Instruments::Stacks.skipped_in_gc
155
- traces.skipped_in_handler = ScoutApm::Instruments::Stacks.skipped_in_handler
156
- traces.skipped_in_job_registered = ScoutApm::Instruments::Stacks.skipped_in_job_registered
157
- traces.skipped_in_not_running = ScoutApm::Instruments::Stacks.skipped_in_not_running
158
- end
159
- end
160
- end
161
-
162
-
163
121
  ######################################
164
122
  # Debugging Helpers
165
123
  ######################################
@@ -200,6 +158,7 @@ module ScoutApm
200
158
  map { |child| child.total_call_time }.
201
159
  inject(0) { |sum, time| sum + time }
202
160
  end
161
+ private :child_time
203
162
 
204
163
  ######################################
205
164
  # Allocation Calculations
@@ -225,5 +184,6 @@ module ScoutApm
225
184
  map { |child| child.total_allocations }.
226
185
  inject(0) { |sum, obj| sum + obj }
227
186
  end
187
+ private :child_allocations
228
188
  end
229
189
  end