rails_pulse 0.2.5.pre.11 → 0.2.5.pre.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce571d5ae696930e4885ac654389e354ef235f0b071046b95bfbd1089b92015d
4
- data.tar.gz: 1b77c49cc62356cc0faa30b641cde07998ce6252c6ef155386dbd2ac6dbbeea4
3
+ metadata.gz: 14471ad08eb69ba71cfa596ede0a58f1638a5d17cd6ff18c161ada4fc92524a8
4
+ data.tar.gz: d823c824b84c21b6b3b6b6eec433d1b7774b60c14e5ec6b1a4a54b32886499b4
5
5
  SHA512:
6
- metadata.gz: 7f2c84081607cc389a4098c3bd70c1df2a396aa2c569befff183f13d8dceb2b6e884559df26ac49b7c2cd10b79490e9e6d0366eb582450f85fdb02e938e1f75b
7
- data.tar.gz: 6d096ff11eca6bd80968118bcb041ffb4dbd13ff58bf1108a69dec4eaefef44e229dba5700039b43cb4f55532fc16f25ed6ca4eb96b7d3e2243f2bd038ca3279
6
+ metadata.gz: bb0ea2202d39365fe7a6751090a888909479336d7c3b1977b8095cb0cddae8f00d896be95d53c8c402e03ee34b477127192fc5f9873c008e8d4ca11944467fcc
7
+ data.tar.gz: c1db7e38744e0476a629be2d88e0e5adf66bbd23a2db93c0657512de19d7aefe003270eb39d53d61f7d9d9b72634afaf7de10e89d650a697e85d9abaed6a353f
data/README.md CHANGED
@@ -43,7 +43,6 @@
43
43
  - [Database Configuration](#database-configuration)
44
44
  - [Schema Loading](#schema-loading)
45
45
  - [Performance Impact](#performance-impact)
46
- - [Running Performance Benchmarks](#running-performance-benchmarks)
47
46
  - [Standalone Dashboard Deployment](#standalone-dashboard-deployment)
48
47
  - [Testing](#testing)
49
48
  - [Technology Stack](#technology-stack)
@@ -648,28 +647,6 @@ Rails Pulse uses **fiber-based async tracking** for minimal performance overhead
648
647
 
649
648
  This is handled automatically and requires no configuration.
650
649
 
651
- ### Running Performance Benchmarks
652
-
653
- Rails Pulse includes built-in benchmarking tools. To use them:
654
-
655
- ```ruby
656
- # Add to your Gemfile (development/test group)
657
- gem 'benchmark-ips'
658
- gem 'memory_profiler'
659
- ```
660
-
661
- ```bash
662
- bundle install
663
-
664
- # Run all benchmarks
665
- bundle exec rake rails_pulse:benchmark:all
666
-
667
- # Run specific benchmarks
668
- bundle exec rake rails_pulse:benchmark:memory
669
- bundle exec rake rails_pulse:benchmark:request_overhead
670
- bundle exec rake rails_pulse:benchmark:middleware
671
- ```
672
-
673
650
  ## Standalone Dashboard Deployment
674
651
 
675
652
  For production environments, you can run the Rails Pulse dashboard as a standalone application, separate from your main Rails app. This provides several benefits:
data/Rakefile CHANGED
@@ -261,9 +261,22 @@ task :test_release do
261
261
 
262
262
  failed_tasks = []
263
263
  current_step = 0
264
- total_steps = 11
264
+ total_steps = 12
265
265
 
266
- # Step 1: Sync test schema
266
+ # Step 1: Update appraisal gemfiles
267
+ current_step += 1
268
+ begin
269
+ puts "\n[#{current_step}/#{total_steps}] Updating appraisal gemfiles..."
270
+ puts "-" * 70
271
+ sh "bundle exec appraisal install"
272
+ puts "✅ Appraisal gemfiles updated!"
273
+ rescue => e
274
+ puts "❌ Appraisal update failed!"
275
+ puts " Error: #{e.message}"
276
+ failed_tasks << "appraisal_install"
277
+ end
278
+
279
+ # Step 3: Sync test schema
267
280
  current_step += 1
268
281
  begin
269
282
  puts "\n[#{current_step}/#{total_steps}] Syncing test schema..."
@@ -275,7 +288,7 @@ task :test_release do
275
288
  failed_tasks << "sync_test_schema"
276
289
  end
277
290
 
278
- # Step 2: Verify dummy migrations
291
+ # Step 4: Verify dummy migrations
279
292
  current_step += 1
280
293
  begin
281
294
  puts "\n[#{current_step}/#{total_steps}] Verifying dummy app migrations..."
@@ -287,7 +300,7 @@ task :test_release do
287
300
  failed_tasks << "verify_dummy_migrations"
288
301
  end
289
302
 
290
- # Step 3: Git status check
303
+ # Step 5: Git status check
291
304
  current_step += 1
292
305
  begin
293
306
  puts "\n[#{current_step}/#{total_steps}] Checking git status..."
@@ -307,7 +320,7 @@ task :test_release do
307
320
  puts "⚠️ Warning: Could not check git status (#{e.message})"
308
321
  end
309
322
 
310
- # Step 5: RuboCop linting
323
+ # Step 6: RuboCop linting
311
324
  current_step += 1
312
325
  begin
313
326
  puts "\n[#{current_step}/#{total_steps}] Running RuboCop linting..."
@@ -1,6 +1,6 @@
1
1
  # Rails Pulse Database Schema
2
2
  # This file contains the complete schema for Rails Pulse tables
3
- # Load with: rails db:schema:load:rails_pulse or db:prepare
3
+ # Load with: rails db:schema:load_rails_pulse or db:prepare
4
4
 
5
5
  RailsPulse::Schema = lambda do |connection|
6
6
  adapter = connection.adapter_name.downcase
@@ -1,6 +1,6 @@
1
1
  # Rails Pulse Database Schema
2
2
  # This file contains the complete schema for Rails Pulse tables
3
- # Load with: rails db:schema:load:rails_pulse or db:prepare
3
+ # Load with: rails db:schema:load_rails_pulse or db:prepare
4
4
 
5
5
  RailsPulse::Schema = lambda do |connection|
6
6
  adapter = connection.adapter_name.downcase
@@ -1,3 +1,3 @@
1
1
  module RailsPulse
2
- VERSION = "0.2.5.pre.11"
2
+ VERSION = "0.2.5.pre.12"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_pulse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5.pre.11
4
+ version: 0.2.5.pre.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rails Pulse
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-02-18 00:00:00.000000000 Z
11
+ date: 2026-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -370,7 +370,6 @@ files:
370
370
  - lib/rails_pulse/version.rb
371
371
  - lib/rails_pulse_server.ru
372
372
  - lib/tasks/rails_pulse.rake
373
- - lib/tasks/rails_pulse_benchmark.rake
374
373
  - lib/tasks/rails_pulse_tasks.rake
375
374
  - public/rails-pulse-assets/csp-test.js
376
375
  - public/rails-pulse-assets/rails-pulse-icons.js
@@ -1,382 +0,0 @@
1
- begin
2
- require "benchmark"
3
- require "benchmark/ips"
4
- require "memory_profiler"
5
- rescue LoadError => e
6
- # Benchmark gems not available - tasks will show error if run
7
- end
8
-
9
- namespace :rails_pulse do
10
- namespace :benchmark do
11
- desc "Run comprehensive performance benchmarks for Rails Pulse"
12
- task all: :environment do
13
- unless defined?(Benchmark::IPS) && defined?(MemoryProfiler)
14
- puts "❌ Benchmark gems not installed. Add to your Gemfile:"
15
- puts " gem 'benchmark-ips'"
16
- puts " gem 'memory_profiler'"
17
- puts "\nThen run: bundle install"
18
- exit 1
19
- end
20
-
21
- puts "\n" + "=" * 80
22
- puts "Rails Pulse Performance Benchmark Suite"
23
- puts "=" * 80
24
- puts "\nEnvironment:"
25
- puts " Ruby: #{RUBY_VERSION}"
26
- puts " Rails: #{Rails.version}"
27
- puts " Database: #{ActiveRecord::Base.connection.adapter_name}"
28
- puts " Rails Pulse: #{RailsPulse::VERSION}"
29
- puts "\n"
30
-
31
- # Run all benchmarks
32
- Rake::Task["rails_pulse:benchmark:memory"].invoke
33
- Rake::Task["rails_pulse:benchmark:request_overhead"].invoke
34
- Rake::Task["rails_pulse:benchmark:middleware"].invoke
35
- Rake::Task["rails_pulse:benchmark:job_tracking"].invoke
36
- Rake::Task["rails_pulse:benchmark:database_queries"].invoke
37
-
38
- puts "\n" + "=" * 80
39
- puts "Benchmark suite completed!"
40
- puts "=" * 80
41
- end
42
-
43
- desc "Benchmark memory usage with and without Rails Pulse"
44
- task memory: :environment do
45
- puts "\n" + "-" * 80
46
- puts "Memory Usage Benchmark"
47
- puts "-" * 80
48
-
49
- # Ensure Rails Pulse is enabled
50
- original_enabled = RailsPulse.configuration.enabled
51
- RailsPulse.configuration.enabled = true
52
-
53
- # Baseline memory (Rails Pulse disabled)
54
- RailsPulse.configuration.enabled = false
55
- GC.start
56
- baseline_memory = GC.stat(:total_allocated_objects)
57
-
58
- # Create some test data
59
- route = RailsPulse::Route.find_or_create_by!(
60
- method: "GET",
61
- path: "/benchmark/test"
62
- )
63
-
64
- # Memory with Rails Pulse enabled
65
- RailsPulse.configuration.enabled = true
66
- GC.start
67
- enabled_memory = GC.stat(:total_allocated_objects)
68
-
69
- # Profile memory for creating a request
70
- report = MemoryProfiler.report do
71
- 10.times do
72
- RailsPulse::Request.create!(
73
- route: route,
74
- occurred_at: Time.current,
75
- duration: rand(50..500),
76
- status: 200,
77
- request_uuid: SecureRandom.uuid
78
- )
79
- end
80
- end
81
-
82
- puts "\nMemory Allocation Summary:"
83
- puts " Total allocated: #{report.total_allocated_memsize / 1024.0} KB"
84
- puts " Total retained: #{report.total_retained_memsize / 1024.0} KB"
85
- puts " Allocated objects: #{report.total_allocated}"
86
- puts " Retained objects: #{report.total_retained}"
87
-
88
- puts "\nPer-Request Memory Overhead:"
89
- puts " ~#{(report.total_allocated_memsize / 10.0 / 1024.0).round(2)} KB per request"
90
-
91
- # Restore original state
92
- RailsPulse.configuration.enabled = original_enabled
93
- end
94
-
95
- desc "Benchmark request processing overhead"
96
- task request_overhead: :environment do
97
- puts "\n" + "-" * 80
98
- puts "Request Processing Overhead Benchmark"
99
- puts "-" * 80
100
-
101
- # Setup test data
102
- route = RailsPulse::Route.find_or_create_by!(
103
- method: "GET",
104
- path: "/benchmark/test"
105
- )
106
-
107
- query = RailsPulse::Query.find_or_create_by!(
108
- normalized_sql: "SELECT * FROM users WHERE id = ?"
109
- )
110
-
111
- puts "\nIterations per second (higher is better):\n"
112
-
113
- Benchmark.ips do |x|
114
- x.config(time: 5, warmup: 2)
115
-
116
- x.report("Request creation (baseline)") do
117
- RailsPulse::Request.new(
118
- route: route,
119
- occurred_at: Time.current,
120
- duration: 100,
121
- status: 200,
122
- request_uuid: SecureRandom.uuid
123
- )
124
- end
125
-
126
- x.report("Request creation + save") do
127
- req = RailsPulse::Request.create!(
128
- route: route,
129
- occurred_at: Time.current,
130
- duration: 100,
131
- status: 200,
132
- request_uuid: SecureRandom.uuid
133
- )
134
- req.destroy
135
- end
136
-
137
- x.report("Request + Operation") do
138
- req = RailsPulse::Request.create!(
139
- route: route,
140
- occurred_at: Time.current,
141
- duration: 100,
142
- status: 200,
143
- request_uuid: SecureRandom.uuid
144
- )
145
- RailsPulse::Operation.create!(
146
- request: req,
147
- query: query,
148
- operation_type: "sql",
149
- label: "User Load",
150
- occurred_at: Time.current,
151
- duration: 10
152
- )
153
- req.destroy
154
- end
155
-
156
- x.compare!
157
- end
158
-
159
- puts "\nAbsolute timing comparison:\n"
160
- result = Benchmark.measure do
161
- 1000.times do
162
- req = RailsPulse::Request.create!(
163
- route: route,
164
- occurred_at: Time.current,
165
- duration: 100,
166
- status: 200,
167
- request_uuid: SecureRandom.uuid
168
- )
169
- req.destroy
170
- end
171
- end
172
-
173
- puts " 1000 requests: #{(result.real * 1000).round(2)}ms total"
174
- puts " Average per request: #{result.real.round(5)}ms"
175
- end
176
-
177
- desc "Benchmark middleware overhead"
178
- task middleware: :environment do
179
- puts "\n" + "-" * 80
180
- puts "Middleware Overhead Benchmark"
181
- puts "-" * 80
182
-
183
- # Create mock request environment
184
- env = {
185
- "REQUEST_METHOD" => "GET",
186
- "PATH_INFO" => "/test",
187
- "QUERY_STRING" => "",
188
- "rack.input" => StringIO.new,
189
- "rack.errors" => $stderr,
190
- "action_dispatch.request_id" => SecureRandom.uuid
191
- }
192
-
193
- app = ->(env) { [ 200, { "Content-Type" => "text/plain" }, [ "OK" ] ] }
194
- middleware = RailsPulse::Middleware::RequestCollector.new(app)
195
-
196
- puts "\nMiddleware performance:\n"
197
-
198
- # Benchmark with Rails Pulse enabled
199
- RailsPulse.configuration.enabled = true
200
- enabled_time = Benchmark.measure do
201
- 1000.times do
202
- test_env = env.dup
203
- test_env["action_dispatch.request_id"] = SecureRandom.uuid
204
- middleware.call(test_env)
205
- end
206
- end
207
-
208
- # Benchmark with Rails Pulse disabled
209
- RailsPulse.configuration.enabled = false
210
- disabled_time = Benchmark.measure do
211
- 1000.times do
212
- test_env = env.dup
213
- test_env["action_dispatch.request_id"] = SecureRandom.uuid
214
- middleware.call(test_env)
215
- end
216
- end
217
-
218
- # Benchmark without middleware
219
- baseline_time = Benchmark.measure do
220
- 1000.times { app.call(env.dup) }
221
- end
222
-
223
- overhead_enabled = (enabled_time.real - baseline_time.real) * 1000 / 1000
224
- overhead_disabled = (disabled_time.real - baseline_time.real) * 1000 / 1000
225
-
226
- puts " Baseline (no middleware): #{(baseline_time.real * 1000).round(2)}ms (1000 requests)"
227
- puts " With Rails Pulse enabled: #{(enabled_time.real * 1000).round(2)}ms (1000 requests)"
228
- puts " With Rails Pulse disabled: #{(disabled_time.real * 1000).round(2)}ms (1000 requests)"
229
- puts "\n Overhead per request (enabled): #{overhead_enabled.round(3)}ms"
230
- puts " Overhead per request (disabled): #{overhead_disabled.round(3)}ms"
231
-
232
- # Restore
233
- RailsPulse.configuration.enabled = true
234
- end
235
-
236
- desc "Benchmark job tracking overhead"
237
- task job_tracking: :environment do
238
- puts "\n" + "-" * 80
239
- puts "Background Job Tracking Overhead Benchmark"
240
- puts "-" * 80
241
-
242
- # Skip if job tracking is disabled
243
- unless RailsPulse.configuration.track_jobs
244
- puts "\n ⚠️ Job tracking is disabled - skipping benchmark"
245
- next
246
- end
247
-
248
- # Create a simple test job
249
- test_job_class = Class.new(ApplicationJob) do
250
- def perform(value)
251
- # Simulate some work
252
- sleep(0.001)
253
- value * 2
254
- end
255
- end
256
-
257
- puts "\nJob execution overhead:\n"
258
-
259
- # Benchmark with job tracking enabled
260
- RailsPulse.configuration.track_jobs = true
261
- enabled_time = Benchmark.measure do
262
- 100.times do |i|
263
- test_job_class.new.perform(i)
264
- end
265
- end
266
-
267
- # Benchmark with job tracking disabled
268
- RailsPulse.configuration.track_jobs = false
269
- disabled_time = Benchmark.measure do
270
- 100.times do |i|
271
- test_job_class.new.perform(i)
272
- end
273
- end
274
-
275
- overhead = (enabled_time.real - disabled_time.real) * 1000 / 100
276
-
277
- puts " With tracking enabled: #{(enabled_time.real * 1000).round(2)}ms (100 jobs)"
278
- puts " With tracking disabled: #{(disabled_time.real * 1000).round(2)}ms (100 jobs)"
279
- puts "\n Overhead per job: #{overhead.round(3)}ms"
280
-
281
- # Restore
282
- RailsPulse.configuration.track_jobs = true
283
- end
284
-
285
- desc "Benchmark database query overhead"
286
- task database_queries: :environment do
287
- puts "\n" + "-" * 80
288
- puts "Database Query Overhead Benchmark"
289
- puts "-" * 80
290
-
291
- # Create test route for queries
292
- route = RailsPulse::Route.find_or_create_by!(
293
- method: "GET",
294
- path: "/benchmark/queries"
295
- )
296
-
297
- puts "\nQuery performance comparison:\n"
298
-
299
- # Test 1: Simple aggregation query
300
- puts " 1. Average request duration calculation:"
301
- time_enabled = Benchmark.measure do
302
- 100.times { RailsPulse::Request.average(:duration) }
303
- end
304
-
305
- RailsPulse.configuration.enabled = false
306
- time_disabled = Benchmark.measure do
307
- 100.times { RailsPulse::Request.average(:duration) }
308
- end
309
- RailsPulse.configuration.enabled = true
310
-
311
- puts " Enabled: #{(time_enabled.real * 1000).round(2)}ms (100 queries)"
312
- puts " Disabled: #{(time_disabled.real * 1000).round(2)}ms (100 queries)"
313
- puts " Overhead: #{((time_enabled.real - time_disabled.real) * 10).round(3)}ms per query"
314
-
315
- # Test 2: Complex joins and grouping
316
- puts "\n 2. Requests grouped by hour with joins:"
317
- time_complex = Benchmark.measure do
318
- 10.times do
319
- RailsPulse::Request
320
- .joins(:route)
321
- .group("DATE_TRUNC('hour', occurred_at)")
322
- .average(:duration)
323
- end
324
- end
325
-
326
- puts " Time: #{(time_complex.real * 1000).round(2)}ms (10 queries)"
327
- puts " Average: #{(time_complex.real * 100).round(3)}ms per query"
328
-
329
- # Test 3: Summary aggregation
330
- puts "\n 3. Summary data aggregation:"
331
- time_summary = Benchmark.measure do
332
- 10.times do
333
- RailsPulse::Summary
334
- .where("period_start > ?", 24.hours.ago)
335
- .group(:period_type)
336
- .average(:avg_duration)
337
- end
338
- end
339
-
340
- puts " Time: #{(time_summary.real * 1000).round(2)}ms (10 queries)"
341
- puts " Average: #{(time_summary.real * 100).round(3)}ms per query"
342
- end
343
-
344
- desc "Generate benchmark report and save to docs"
345
- task report: :environment do
346
- require "fileutils"
347
-
348
- puts "\n" + "=" * 80
349
- puts "Generating Performance Benchmark Report"
350
- puts "=" * 80
351
-
352
- output_file = Rails.root.join("../../docs/benchmark_results.md")
353
- FileUtils.mkdir_p(File.dirname(output_file))
354
-
355
- File.open(output_file, "w") do |f|
356
- f.puts "# Rails Pulse Performance Benchmark Results"
357
- f.puts ""
358
- f.puts "**Generated:** #{Time.current.strftime('%Y-%m-%d %H:%M:%S %Z')}"
359
- f.puts ""
360
- f.puts "## Environment"
361
- f.puts ""
362
- f.puts "- **Ruby:** #{RUBY_VERSION}"
363
- f.puts "- **Rails:** #{Rails.version}"
364
- f.puts "- **Database:** #{ActiveRecord::Base.connection.adapter_name}"
365
- f.puts "- **Rails Pulse:** #{RailsPulse::VERSION}"
366
- f.puts ""
367
- f.puts "## Summary"
368
- f.puts ""
369
- f.puts "This report contains automated performance benchmarks measuring Rails Pulse's overhead."
370
- f.puts ""
371
- f.puts "---"
372
- f.puts ""
373
- f.puts "*For full benchmark output, run:* `rails rails_pulse:benchmark:all`"
374
- end
375
-
376
- puts "\n✅ Report saved to: #{output_file}"
377
-
378
- # Run full benchmark suite
379
- Rake::Task["rails_pulse:benchmark:all"].invoke
380
- end
381
- end
382
- end