catpm 0.9.4 → 0.9.6

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.
data/lib/catpm/flusher.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  module Catpm
4
4
  class Flusher
5
5
  ERROR_LOG_BACKTRACE_LINES = 5
6
- PARTIAL_STALE_TIMEOUT = 600 # seconds — orphaned partial samples cleaned after 10 minutes
7
6
 
8
7
  attr_reader :running
9
8
 
@@ -182,8 +181,7 @@ module Catpm
182
181
  sample_type: sample_type,
183
182
  recorded_at: event.started_at,
184
183
  duration: event.duration,
185
- context: event.context || {},
186
- request_id: event.request_id
184
+ context: event.context || {}
187
185
  }
188
186
  sample_hash[:error_fingerprint] = error_fp if error_fp
189
187
  samples << sample_hash
@@ -221,8 +219,6 @@ module Catpm
221
219
  b
222
220
  end
223
221
 
224
- samples = merge_request_samples(samples)
225
-
226
222
  [ buckets, samples, error_groups.values ]
227
223
  end
228
224
 
@@ -350,7 +346,6 @@ module Catpm
350
346
  @last_cleanup_at = Time.now
351
347
  downsample_buckets
352
348
  cleanup_expired_data if Catpm.config.retention_period
353
- cleanup_orphaned_partials
354
349
  Collector.reset_sample_counts!
355
350
  end
356
351
 
@@ -398,83 +393,93 @@ module Catpm
398
393
  cutoff = age_threshold.ago
399
394
  target_seconds = target_interval.to_i
400
395
 
401
- # Process in batches to avoid loading all old buckets into memory
402
- Catpm::Bucket.where(bucket_start: ...cutoff)
403
- .select(:id, :kind, :target, :operation, :bucket_start)
404
- .group_by { |b| [b.kind, b.target, b.operation] }
405
- .each do |(_kind, _target, _operation), endpoint_buckets|
406
- groups = endpoint_buckets.group_by do |bucket|
407
- epoch = bucket.bucket_start.to_i
408
- aligned_epoch = epoch - (epoch % target_seconds)
409
- Time.at(aligned_epoch).utc
410
- end
396
+ # Get unique endpoint keys first (small set), then process per-endpoint
397
+ # to avoid loading all old buckets into memory at once
398
+ endpoint_keys = Catpm::Bucket.where(bucket_start: ...cutoff)
399
+ .distinct.pluck(:kind, :target, :operation)
411
400
 
412
- groups.each do |aligned_start, stub_buckets|
413
- next if stub_buckets.size == 1 && stub_buckets.first.bucket_start.to_i % target_seconds == 0
414
-
415
- # Load full records only for groups that need merging
416
- bucket_ids = stub_buckets.map(&:id)
417
- buckets = Catpm::Bucket.where(id: bucket_ids).to_a
418
-
419
- merged = {
420
- kind: buckets.first.kind,
421
- target: buckets.first.target,
422
- operation: buckets.first.operation,
423
- bucket_start: aligned_start,
424
- count: buckets.sum(&:count),
425
- success_count: buckets.sum(&:success_count),
426
- failure_count: buckets.sum(&:failure_count),
427
- duration_sum: buckets.sum(&:duration_sum),
428
- duration_max: buckets.map(&:duration_max).max,
429
- duration_min: buckets.map(&:duration_min).min,
430
- metadata_sum: merge_bucket_metadata(buckets, adapter),
431
- p95_digest: merge_bucket_digests(buckets)
432
- }
433
-
434
- survivor = buckets.first
435
-
436
- # Reassign all samples to the survivor bucket
437
- Catpm::Sample.where(bucket_id: bucket_ids).update_all(bucket_id: survivor.id)
438
-
439
- # Delete non-survivor source buckets (now sample-free)
440
- Catpm::Bucket.where(id: bucket_ids - [survivor.id]).delete_all
441
-
442
- # Overwrite survivor with merged data
443
- survivor.update!(
444
- bucket_start: aligned_start,
445
- count: merged[:count],
446
- success_count: merged[:success_count],
447
- failure_count: merged[:failure_count],
448
- duration_sum: merged[:duration_sum],
449
- duration_max: merged[:duration_max],
450
- duration_min: merged[:duration_min],
451
- metadata_sum: merged[:metadata_sum],
452
- p95_digest: merged[:p95_digest]
453
- )
454
- end
401
+ endpoint_keys.each do |kind, target, operation|
402
+ endpoint_buckets = Catpm::Bucket
403
+ .where(kind: kind, target: target, operation: operation, bucket_start: ...cutoff)
404
+ .select(:id, :bucket_start).to_a
405
+
406
+ groups = endpoint_buckets.group_by do |bucket|
407
+ epoch = bucket.bucket_start.to_i
408
+ aligned_epoch = epoch - (epoch % target_seconds)
409
+ Time.at(aligned_epoch).utc
410
+ end
411
+
412
+ groups.each do |aligned_start, stub_buckets|
413
+ next if stub_buckets.size == 1 && stub_buckets.first.bucket_start.to_i % target_seconds == 0
414
+
415
+ # Load full records only for groups that need merging
416
+ bucket_ids = stub_buckets.map(&:id)
417
+ buckets = Catpm::Bucket.where(id: bucket_ids).to_a
418
+
419
+ merged = {
420
+ kind: buckets.first.kind,
421
+ target: buckets.first.target,
422
+ operation: buckets.first.operation,
423
+ bucket_start: aligned_start,
424
+ count: buckets.sum(&:count),
425
+ success_count: buckets.sum(&:success_count),
426
+ failure_count: buckets.sum(&:failure_count),
427
+ duration_sum: buckets.sum(&:duration_sum),
428
+ duration_max: buckets.map(&:duration_max).max,
429
+ duration_min: buckets.map(&:duration_min).min,
430
+ metadata_sum: merge_bucket_metadata(buckets, adapter),
431
+ p95_digest: merge_bucket_digests(buckets)
432
+ }
433
+
434
+ survivor = buckets.first
435
+
436
+ # Reassign all samples to the survivor bucket
437
+ Catpm::Sample.where(bucket_id: bucket_ids).update_all(bucket_id: survivor.id)
438
+
439
+ # Delete non-survivor source buckets (now sample-free)
440
+ Catpm::Bucket.where(id: bucket_ids - [survivor.id]).delete_all
441
+
442
+ # Overwrite survivor with merged data
443
+ survivor.update!(
444
+ bucket_start: aligned_start,
445
+ count: merged[:count],
446
+ success_count: merged[:success_count],
447
+ failure_count: merged[:failure_count],
448
+ duration_sum: merged[:duration_sum],
449
+ duration_max: merged[:duration_max],
450
+ duration_min: merged[:duration_min],
451
+ metadata_sum: merged[:metadata_sum],
452
+ p95_digest: merged[:p95_digest]
453
+ )
455
454
  end
455
+ end
456
456
  end
457
457
 
458
458
  def downsample_event_tier(target_interval:, age_threshold:, adapter:)
459
459
  cutoff = age_threshold.ago
460
460
  target_seconds = target_interval.to_i
461
461
 
462
- source_buckets = Catpm::EventBucket.where(bucket_start: ...cutoff).to_a
463
- return if source_buckets.empty?
462
+ # Process per-name to avoid loading all event buckets into memory
463
+ names = Catpm::EventBucket.where(bucket_start: ...cutoff).distinct.pluck(:name)
464
+ return if names.empty?
464
465
 
465
- groups = source_buckets.group_by do |bucket|
466
- epoch = bucket.bucket_start.to_i
467
- aligned_epoch = epoch - (epoch % target_seconds)
468
- aligned_start = Time.at(aligned_epoch).utc
469
- [bucket.name, aligned_start]
470
- end
466
+ names.each do |name|
467
+ buckets = Catpm::EventBucket.where(name: name, bucket_start: ...cutoff).to_a
468
+ next if buckets.empty?
471
469
 
472
- groups.each do |(name, aligned_start), buckets|
473
- next if buckets.size == 1 && buckets.first.bucket_start.to_i % target_seconds == 0
470
+ groups = buckets.group_by do |bucket|
471
+ epoch = bucket.bucket_start.to_i
472
+ aligned_epoch = epoch - (epoch % target_seconds)
473
+ Time.at(aligned_epoch).utc
474
+ end
475
+
476
+ groups.each do |aligned_start, group_buckets|
477
+ next if group_buckets.size == 1 && group_buckets.first.bucket_start.to_i % target_seconds == 0
474
478
 
475
- merged = { name: name, bucket_start: aligned_start, count: buckets.sum(&:count) }
476
- Catpm::EventBucket.where(id: buckets.map(&:id)).delete_all
477
- adapter.persist_event_buckets([merged])
479
+ merged = { name: name, bucket_start: aligned_start, count: group_buckets.sum(&:count) }
480
+ Catpm::EventBucket.where(id: group_buckets.map(&:id)).delete_all
481
+ adapter.persist_event_buckets([merged])
482
+ end
478
483
  end
479
484
  end
480
485
 
@@ -494,136 +499,6 @@ module Catpm
494
499
  combined.empty? ? nil : combined.serialize
495
500
  end
496
501
 
497
- def merge_request_samples(samples)
498
- return samples unless Catpm::Sample.request_id_supported?
499
-
500
- by_request = {} # request_id => { partials: [], final: nil }
501
- regular = []
502
-
503
- samples.each do |s|
504
- rid = s[:request_id]
505
- if rid
506
- entry = (by_request[rid] ||= { partials: [], final: nil })
507
- if s[:context].is_a?(Hash) && s[:context][:partial]
508
- entry[:partials] << s
509
- else
510
- entry[:final] = s
511
- end
512
- else
513
- regular << s
514
- end
515
- end
516
-
517
- merged = []
518
- by_request.each do |rid, entry|
519
- if entry[:final]
520
- # Merge in-batch partials
521
- if entry[:partials].any?
522
- merge_checkpoint_contexts(
523
- entry[:final][:context],
524
- entry[:partials].map { |p| p[:context] }
525
- )
526
- end
527
-
528
- # Merge cross-batch partials from DB
529
- db_partials = Catpm::Sample.where(request_id: rid)
530
- if db_partials.exists?
531
- merge_checkpoint_contexts(
532
- entry[:final][:context],
533
- db_partials.map(&:parsed_context)
534
- )
535
- db_partials.delete_all
536
- end
537
-
538
- # Clear request_id so persisted final sample won't be treated as orphan
539
- entry[:final][:request_id] = nil
540
- merged << entry[:final]
541
- else
542
- # Only partials, no final yet — persist as-is
543
- merged.concat(entry[:partials])
544
- end
545
- end
546
-
547
- regular + merged
548
- end
549
-
550
- def merge_checkpoint_contexts(final_ctx, checkpoint_ctxs)
551
- final_segments = final_ctx[:segments] || final_ctx['segments']
552
- return unless final_segments
553
-
554
- final_ctrl_idx = final_segments.index { |s|
555
- (s[:type] || s['type']) == 'controller'
556
- }
557
-
558
- sorted = checkpoint_ctxs.sort_by { |c|
559
- c[:checkpoint_number] || c['checkpoint_number'] || 0
560
- }
561
-
562
- sorted.each do |cp_ctx|
563
- cp_segments = cp_ctx[:segments] || cp_ctx['segments'] || []
564
-
565
- old_to_new = {}
566
- kept = []
567
-
568
- cp_segments.each_with_index do |seg, i|
569
- seg_type = seg[:type] || seg['type']
570
- next if seg_type == 'request'
571
- next if seg_type == 'controller'
572
- old_to_new[i] = final_segments.size + kept.size
573
- kept << seg.dup
574
- end
575
-
576
- kept.each do |seg|
577
- pi_key = seg.key?(:parent_index) ? :parent_index : 'parent_index'
578
- pi = seg[pi_key]
579
- next unless pi
580
-
581
- if old_to_new.key?(pi)
582
- seg[pi_key] = old_to_new[pi]
583
- else
584
- seg[pi_key] = final_ctrl_idx || 0
585
- end
586
- end
587
-
588
- final_segments.concat(kept)
589
-
590
- # Merge summary
591
- cp_summary = cp_ctx[:segment_summary] || cp_ctx['segment_summary']
592
- if cp_summary
593
- use_symbols = final_ctx.key?(:segment_summary)
594
- summary_key = use_symbols ? :segment_summary : 'segment_summary'
595
- final_summary = final_ctx[summary_key] ||= {}
596
- cp_summary.each do |k, v|
597
- nk = use_symbols ? k.to_sym : k.to_s
598
- final_summary[nk] = (final_summary[nk] || 0) + v.to_f
599
- end
600
- end
601
-
602
- # Merge capped flag
603
- capped_key = final_ctx.key?(:segments_capped) ? :segments_capped : 'segments_capped'
604
- cp_capped = cp_ctx[:segments_capped] || cp_ctx['segments_capped']
605
- final_ctx[capped_key] = true if cp_capped
606
- end
607
-
608
- # Clean up checkpoint markers
609
- final_ctx.delete(:partial)
610
- final_ctx.delete('partial')
611
- final_ctx.delete(:request_id)
612
- final_ctx.delete('request_id')
613
- final_ctx.delete(:checkpoint_number)
614
- final_ctx.delete('checkpoint_number')
615
- end
616
-
617
- def cleanup_orphaned_partials
618
- return unless Catpm::Sample.request_id_supported?
619
-
620
- Catpm::Sample.where.not(request_id: nil)
621
- .where(recorded_at: ..PARTIAL_STALE_TIMEOUT.seconds.ago)
622
- .delete_all
623
- rescue => e
624
- Catpm.config.error_handler&.call(e)
625
- end
626
-
627
502
  def cleanup_expired_data
628
503
  cutoff = Catpm.config.retention_period.ago
629
504
  batch_size = Catpm.config.cleanup_batch_size
@@ -8,6 +8,7 @@ module Catpm
8
8
 
9
9
  initialize_buffer
10
10
  initialize_flusher
11
+ load_sample_counts
11
12
  apply_patches
12
13
 
13
14
  # Start the flusher in the current process.
@@ -24,6 +25,12 @@ module Catpm
24
25
 
25
26
  private
26
27
 
28
+ def load_sample_counts
29
+ Collector.load_sample_counts_eagerly!
30
+ rescue => e
31
+ Catpm.config.error_handler&.call(e)
32
+ end
33
+
27
34
  def apply_patches
28
35
  if Catpm.config.instrument_net_http
29
36
  if defined?(::Net::HTTP)
@@ -39,7 +46,7 @@ module Catpm
39
46
  end
40
47
 
41
48
  def initialize_buffer
42
- Catpm.buffer ||= Buffer.new(max_bytes: Catpm.config.max_buffer_memory)
49
+ Catpm.buffer ||= Buffer.new(max_bytes: Catpm.config.effective_max_buffer_memory)
43
50
  end
44
51
 
45
52
  def initialize_flusher
@@ -20,8 +20,7 @@ module Catpm
20
20
  max_segments: Catpm.config.max_segments_per_request,
21
21
  request_start: env['catpm.request_start'],
22
22
  stack_sample: use_sampler,
23
- call_tree: Catpm.config.instrument_call_tree,
24
- memory_limit: Catpm.config.max_request_memory
23
+ call_tree: Catpm.config.instrument_call_tree
25
24
  )
26
25
  env['catpm.segments'] = req_segments
27
26
  Thread.current[:catpm_request_segments] = req_segments
@@ -47,10 +46,10 @@ module Catpm
47
46
  ev = Event.new(
48
47
  kind: :http,
49
48
  target: target_from_env(env),
50
- operation: env['REQUEST_METHOD'] || 'GET',
49
+ operation: env['REQUEST_METHOD'] || '',
51
50
  duration: elapsed_ms(env),
52
51
  started_at: Time.current,
53
- status: 500,
52
+ status: Collector::DEFAULT_ERROR_STATUS,
54
53
  sample_type: 'error',
55
54
  error_class: exception.class.name,
56
55
  error_message: exception.message,
@@ -17,7 +17,7 @@ module Catpm
17
17
  status = response.status rescue nil
18
18
  detail = "#{http_method} #{uri.host}#{uri.path}"
19
19
  detail += " (#{status})" if status
20
- source = duration >= Catpm.config.segment_source_threshold ? extract_catpm_source : nil
20
+ source = Catpm.segment_storable?(duration) ? extract_catpm_source : nil
21
21
 
22
22
  segments.add(
23
23
  type: :http, duration: duration, detail: detail,
@@ -12,7 +12,7 @@ module Catpm
12
12
  duration = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000.0
13
13
 
14
14
  detail = "#{req.method} #{@address}#{req.path} (#{response.code})"
15
- source = duration >= Catpm.config.segment_source_threshold ? extract_catpm_source : nil
15
+ source = Catpm.segment_storable?(duration) ? extract_catpm_source : nil
16
16
 
17
17
  segments.add(
18
18
  type: :http, duration: duration, detail: detail,
@@ -9,9 +9,9 @@ module Catpm
9
9
  SEGMENT_BASE_BYTES = Event::OBJECT_OVERHEAD + (6 * Event::HASH_ENTRY_SIZE)
10
10
  SEGMENT_STRING_OVERHEAD = Event::OBJECT_OVERHEAD # per-string overhead in segment values
11
11
 
12
- attr_reader :segments, :summary, :request_start, :estimated_bytes, :checkpoint_count, :request_id
12
+ attr_reader :segments, :summary, :request_start, :estimated_bytes, :segments_filtered
13
13
 
14
- def initialize(max_segments:, request_start: nil, stack_sample: false, call_tree: false, memory_limit: nil)
14
+ def initialize(max_segments:, request_start: nil, stack_sample: false, call_tree: false)
15
15
  @max_segments = max_segments
16
16
  @request_start = request_start || Process.clock_gettime(Process::CLOCK_MONOTONIC)
17
17
  @segments = []
@@ -20,11 +20,8 @@ module Catpm
20
20
  @span_stack = []
21
21
  @tracked_ranges = []
22
22
  @call_tree = call_tree
23
- @memory_limit = memory_limit
24
23
  @estimated_bytes = 0
25
- @checkpoint_callback = nil
26
- @checkpoint_count = 0
27
- @request_id = memory_limit ? SecureRandom.hex(8) : nil
24
+ @segments_filtered = 0
28
25
 
29
26
  if stack_sample
30
27
  @sampler = StackSampler.new(target_thread: Thread.current, request_start: @request_start, call_tree: call_tree)
@@ -32,16 +29,24 @@ module Catpm
32
29
  end
33
30
  end
34
31
 
35
- def on_checkpoint(&block)
36
- @checkpoint_callback = block
37
- end
38
-
39
32
  def add(type:, duration:, detail:, source: nil, started_at: nil)
40
33
  type_key = type.to_sym
41
34
  count_key, dur_key = SUMMARY_KEYS[type_key]
42
35
  @summary[count_key] += 1
43
36
  @summary[dur_key] += duration
44
37
 
38
+ # Record time range so sampler can skip already-tracked periods
39
+ if started_at && duration > 0
40
+ @tracked_ranges << [started_at, started_at + duration / 1000.0]
41
+ end
42
+
43
+ # Skip storing segment below minimum duration threshold —
44
+ # summary counters above are still updated for accurate Time Breakdown.
45
+ unless Catpm.segment_storable?(duration)
46
+ @segments_filtered += 1
47
+ return
48
+ end
49
+
45
50
  offset = started_at ? ((started_at - @request_start) * 1000.0).round(2) : nil
46
51
 
47
52
  segment = { type: type.to_s, duration: duration.round(2), detail: detail }
@@ -49,11 +54,6 @@ module Catpm
49
54
  segment[:source] = source if source
50
55
  segment[:parent_index] = @span_stack.last if @span_stack.any?
51
56
 
52
- # Record time range so sampler can skip already-tracked periods
53
- if started_at && duration > 0
54
- @tracked_ranges << [started_at, started_at + duration / 1000.0]
55
- end
56
-
57
57
  if @max_segments.nil? || @segments.size < @max_segments
58
58
  @segments << segment
59
59
  else
@@ -65,7 +65,6 @@ module Catpm
65
65
  end
66
66
 
67
67
  @estimated_bytes += estimate_segment_bytes(segment)
68
- maybe_checkpoint
69
68
  end
70
69
 
71
70
  def push_span(type:, detail:, started_at: nil)
@@ -132,6 +131,7 @@ module Catpm
132
131
  @tracked_ranges = []
133
132
  @sampler = nil
134
133
  @estimated_bytes = 0
134
+ @segments_filtered = 0
135
135
  end
136
136
 
137
137
  def overflowed?
@@ -142,7 +142,8 @@ module Catpm
142
142
  {
143
143
  segments: @segments,
144
144
  segment_summary: @summary,
145
- segments_capped: @overflow
145
+ segments_capped: @overflow,
146
+ segments_filtered: @segments_filtered
146
147
  }
147
148
  end
148
149
 
@@ -156,67 +157,5 @@ module Catpm
156
157
  bytes
157
158
  end
158
159
 
159
- def maybe_checkpoint
160
- return unless @memory_limit && @estimated_bytes > @memory_limit && @checkpoint_callback
161
-
162
- checkpoint_data = {
163
- segments: @segments,
164
- summary: @summary,
165
- overflow: @overflow,
166
- sampler_segments: @sampler ? sampler_segments_for_checkpoint : [],
167
- checkpoint_number: @checkpoint_count
168
- }
169
-
170
- @checkpoint_count += 1
171
- rebuild_after_checkpoint
172
- @checkpoint_callback.call(checkpoint_data)
173
- end
174
-
175
- def sampler_segments_for_checkpoint
176
- if @call_tree
177
- result = @sampler&.to_call_tree(tracked_ranges: @tracked_ranges) || []
178
- else
179
- result = @sampler&.to_segments(tracked_ranges: @tracked_ranges) || []
180
- end
181
- @sampler&.clear_samples!
182
- result
183
- end
184
-
185
- # After checkpoint: keep only active spans from @span_stack, reset everything else.
186
- def rebuild_after_checkpoint
187
- if @span_stack.any?
188
- # Clone active spans with corrected indices
189
- new_segments = []
190
- old_to_new = {}
191
-
192
- @span_stack.each do |old_idx|
193
- seg = @segments[old_idx]
194
- next unless seg
195
-
196
- new_idx = new_segments.size
197
- old_to_new[old_idx] = new_idx
198
- new_segments << seg.dup
199
- end
200
-
201
- # Fix parent_index references in cloned spans
202
- new_segments.each do |seg|
203
- if seg.key?(:parent_index) && old_to_new.key?(seg[:parent_index])
204
- seg[:parent_index] = old_to_new[seg[:parent_index]]
205
- else
206
- seg.delete(:parent_index)
207
- end
208
- end
209
-
210
- @span_stack = @span_stack.filter_map { |old_idx| old_to_new[old_idx] }
211
- @segments = new_segments
212
- else
213
- @segments = []
214
- end
215
-
216
- @summary = Hash.new(0)
217
- @tracked_ranges = []
218
- @overflow = false
219
- @estimated_bytes = 0
220
- end
221
160
  end
222
161
  end
@@ -155,7 +155,7 @@ module Catpm
155
155
  record_count = payload[:record_count] || 0
156
156
  class_name = payload[:class_name] || 'ActiveRecord'
157
157
  detail = "#{class_name} x#{record_count}"
158
- source = duration >= Catpm.config.segment_source_threshold ? extract_source_location : nil
158
+ source = Catpm.segment_storable?(duration) ? extract_source_location : nil
159
159
 
160
160
  # Fold into sql summary for cleaner breakdown
161
161
  req_segments.add(
@@ -176,7 +176,7 @@ module Catpm
176
176
  sql = payload[:sql].to_s
177
177
  max_len = Catpm.config.max_sql_length
178
178
  sql = sql.truncate(max_len) if max_len && sql.length > max_len
179
- source = duration >= Catpm.config.segment_source_threshold ? extract_source_location : nil
179
+ source = Catpm.segment_storable?(duration) ? extract_source_location : nil
180
180
 
181
181
  req_segments.add(
182
182
  type: :sql, duration: duration, detail: sql,
@@ -193,7 +193,7 @@ module Catpm
193
193
  hit = event.payload[:hit]
194
194
  detail = "cache.#{operation} #{key}"
195
195
  detail += hit ? ' (hit)' : ' (miss)' if operation == 'read' && !hit.nil?
196
- source = duration >= Catpm.config.segment_source_threshold ? extract_source_location : nil
196
+ source = Catpm.segment_storable?(duration) ? extract_source_location : nil
197
197
 
198
198
  req_segments.add(
199
199
  type: :cache, duration: duration, detail: detail,
@@ -209,7 +209,7 @@ module Catpm
209
209
  mailer = payload[:mailer].to_s
210
210
  to = Array(payload[:to]).first.to_s
211
211
  detail = to.empty? ? mailer : "#{mailer} to #{to}"
212
- source = event.duration >= Catpm.config.segment_source_threshold ? extract_source_location : nil
212
+ source = Catpm.segment_storable?(event.duration) ? extract_source_location : nil
213
213
 
214
214
  req_segments.add(
215
215
  type: :mailer, duration: event.duration, detail: detail,
@@ -224,7 +224,7 @@ module Catpm
224
224
  payload = event.payload
225
225
  key = payload[:key].to_s
226
226
  detail = "#{operation} #{key}"
227
- source = event.duration >= Catpm.config.segment_source_threshold ? extract_source_location : nil
227
+ source = Catpm.segment_storable?(event.duration) ? extract_source_location : nil
228
228
 
229
229
  req_segments.add(
230
230
  type: :storage, duration: event.duration, detail: detail,
data/lib/catpm/trace.rb CHANGED
@@ -47,7 +47,7 @@ module Catpm
47
47
 
48
48
  req_segments = Thread.current[:catpm_request_segments]
49
49
  if req_segments
50
- source = duration_ms >= config.segment_source_threshold ? extract_trace_source : nil
50
+ source = segment_storable?(duration_ms) ? extract_trace_source : nil
51
51
  req_segments.add(
52
52
  type: :custom, duration: duration_ms, detail: name,
53
53
  source: source, started_at: start_time
@@ -89,23 +89,10 @@ module Catpm
89
89
  max_segments: config.max_segments_per_request,
90
90
  request_start: start_time,
91
91
  stack_sample: use_sampler,
92
- call_tree: config.instrument_call_tree,
93
- memory_limit: config.max_request_memory
92
+ call_tree: config.instrument_call_tree
94
93
  )
95
94
  Thread.current[:catpm_request_segments] = req_segments
96
95
  owns_segments = true
97
-
98
- if config.max_request_memory
99
- req_segments.on_checkpoint do |checkpoint_data|
100
- Collector.process_checkpoint(
101
- kind: kind, target: target, operation: operation,
102
- context: context, metadata: metadata,
103
- checkpoint_data: checkpoint_data,
104
- request_start: start_time,
105
- request_id: req_segments.request_id
106
- )
107
- end
108
- end
109
96
  end
110
97
  end
111
98
 
@@ -162,7 +149,7 @@ module Catpm
162
149
 
163
150
  req_segments = Thread.current[:catpm_request_segments]
164
151
  if req_segments
165
- source = duration_ms >= Catpm.config.segment_source_threshold ? Catpm.send(:extract_trace_source) : nil
152
+ source = Catpm.segment_storable?(duration_ms) ? Catpm.send(:extract_trace_source) : nil
166
153
  req_segments.add(
167
154
  type: :custom, duration: duration_ms, detail: @name,
168
155
  source: source, started_at: @start_time
data/lib/catpm/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Catpm
4
- VERSION = '0.9.4'
4
+ VERSION = '0.9.6'
5
5
  end