rails-profiler 0.27.0 → 0.28.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.
@@ -9,7 +9,7 @@ module Profiler
9
9
  :authorization_mode, :max_profiles, :extension_cors_enabled,
10
10
  :cors_allowed_origins,
11
11
  :track_ajax, :ajax_skip_paths,
12
- :track_http, :slow_http_threshold, :http_skip_hosts,
12
+ :track_http, :slow_http_threshold, :http_skip_hosts, :http_backtrace_depth,
13
13
  :track_jobs,
14
14
  :track_console,
15
15
  :track_tests,
@@ -43,6 +43,7 @@ module Profiler
43
43
  @track_http = true
44
44
  @slow_http_threshold = 500 # milliseconds
45
45
  @http_skip_hosts = []
46
+ @http_backtrace_depth = 40
46
47
  @track_jobs = true
47
48
  @track_console = true
48
49
  @track_tests = false
@@ -157,9 +157,11 @@ module Profiler
157
157
  end
158
158
 
159
159
  def self.extract_backtrace
160
- caller_locations(5, 40)
161
- .reject { |l| l.path.to_s.include?("net/http") || l.path.to_s.include?("profiler/instrumentation") }
162
- .map { |l| "#{l.path}:#{l.lineno}:in `#{l.label}`" }
160
+ depth = Profiler.configuration.http_backtrace_depth
161
+ frames = caller_locations(5, depth || 1000)
162
+ .reject { |l| l.path.to_s.include?("net/http") || l.path.to_s.include?("profiler/instrumentation") }
163
+ .map { |l| "#{l.path}:#{l.lineno}:in `#{l.label}`" }
164
+ depth ? frames.first(depth) : frames
163
165
  end
164
166
  end
165
167
  end
@@ -7,10 +7,13 @@ require_relative "../models/profile"
7
7
 
8
8
  module Profiler
9
9
  module Storage
10
+ # File-based profile storage backend. Persists each profile as a JSON file
11
+ # under tmp_path and evicts the oldest files when total size exceeds max_size.
10
12
  class FileStore < BaseStore
11
13
  def initialize(options = {})
14
+ super()
12
15
  @path = options[:path] || default_path
13
- @max_size = options[:max_size] || 100 * 1024 * 1024 # 100 MB
16
+ @max_size = options[:max_size] || (100 * 1024 * 1024) # 100 MB
14
17
  ensure_directory_exists
15
18
  end
16
19
 
@@ -27,7 +30,7 @@ module Profiler
27
30
 
28
31
  json_data = File.read(file_path)
29
32
  Models::Profile.from_json(json_data)
30
- rescue => e
33
+ rescue StandardError => e
31
34
  warn "Failed to load profile #{token}: #{e.message}"
32
35
  nil
33
36
  end
@@ -46,8 +49,8 @@ module Profiler
46
49
  cutoff_time = Time.now - older_than
47
50
  profile_files.each do |file|
48
51
  File.delete(file) if File.mtime(file) < cutoff_time
49
- rescue => e
50
- warn "Failed to delete profile file #{file}: #{e.message}"
52
+ rescue Errno::ENOENT
53
+ nil
51
54
  end
52
55
  end
53
56
 
@@ -56,22 +59,25 @@ module Profiler
56
59
  .map { |f| load(File.basename(f, ".json")) }
57
60
  .compact
58
61
  .select { |profile| profile.parent_token == parent_token }
59
- .sort_by { |profile| profile.started_at }
62
+ .sort_by(&:started_at)
60
63
  end
61
64
 
62
65
  def delete(token)
63
- file_path = profile_file_path(token)
64
- File.delete(file_path) if File.exist?(file_path)
66
+ FileUtils.rm_f(profile_file_path(token))
65
67
  end
66
68
 
67
- def clear(type: nil)
69
+ def clear(type: nil) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
68
70
  if type.nil?
69
- profile_files.each { |f| File.delete(f) rescue nil }
71
+ profile_files.each do |f|
72
+ File.delete(f)
73
+ rescue StandardError
74
+ nil
75
+ end
70
76
  else
71
77
  profile_files.each do |f|
72
78
  profile = load(File.basename(f, ".json"))
73
79
  File.delete(f) if profile&.profile_type == type.to_s
74
- rescue
80
+ rescue StandardError
75
81
  nil
76
82
  end
77
83
  end
@@ -95,20 +101,28 @@ module Profiler
95
101
  Dir.glob(File.join(@path, "*.json"))
96
102
  end
97
103
 
98
- def cleanup_if_needed
99
- total_size = profile_files.sum { |f| File.size(f) }
104
+ def cleanup_if_needed # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
105
+ total_size = profile_files.sum do |f|
106
+ File.size(f)
107
+ rescue Errno::ENOENT
108
+ 0
109
+ end
100
110
  return if total_size < @max_size
101
111
 
102
- # Delete oldest files until we're under the limit
103
- profile_files
104
- .sort_by { |f| File.mtime(f) }
105
- .each do |file|
106
- File.delete(file)
107
- total_size -= File.size(file)
108
- break if total_size < @max_size * 0.8
109
- rescue => e
110
- warn "Failed to delete profile file #{file}: #{e.message}"
111
- end
112
+ sorted = profile_files.sort_by do |f|
113
+ File.mtime(f)
114
+ rescue Errno::ENOENT
115
+ Time.now
116
+ end
117
+
118
+ sorted.each do |file|
119
+ file_size = File.size(file)
120
+ File.delete(file)
121
+ total_size -= file_size
122
+ break if total_size < @max_size * 0.8
123
+ rescue Errno::ENOENT
124
+ nil
125
+ end
112
126
  end
113
127
  end
114
128
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Profiler
4
- VERSION = "0.27.0"
4
+ VERSION = "0.28.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.27.0
4
+ version: 0.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sébastien Duplessy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-06-02 00:00:00.000000000 Z
11
+ date: 2026-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails