rails_pulse 0.2.5.pre.5 → 0.2.5.pre.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b1d65c3afe59858af712a994ef9310c0851485cc6a2c09234fcf0b84d63179c
4
- data.tar.gz: f5a6e525c6d605b6fa0edc882c8ea7fc672ea5b4bfd803bfbee1508d2c9ff9ec
3
+ metadata.gz: 8d492179e5f33629fe30b240cdf4733b7936740f7604c91b88a61b80118ed803
4
+ data.tar.gz: 511d9dfa929f07ed14af1ec74d1f6f3580640003527ebfe1c84cd25ecd0770fb
5
5
  SHA512:
6
- metadata.gz: 6d391f448da6724d1e095df6534753febd8b696c62db69de9c75618e891889f9a1b8ae7b6dbcf983cf8caa033901023e4c16f868aa7896c62b90ae901388a5b3
7
- data.tar.gz: e1f190bbf54846a915f875e2381ae5890c4ff9d97baccf9441d4cdf026ccbd55c36d6e2b8b987dc878376d42643884d37b0d8afa4ef713dae7c3cebd19de6f25
6
+ metadata.gz: 2c1cdb3a838fa8a695edcf6d107db53f62850e93aec868ca50d8eacda9376f874afe3636ad8ef317d056c53da9226303d671d2eb376493275cd6e605b78273e4
7
+ data.tar.gz: 0b6c42e8011d7e98d86cc510e57f070dfdb5b3d20c556ad75d195c45da3d8bf603ff458a9a5720865ddcaa6954b1062f127b4c0d622d24596d075dd6de003ade
data/README.md CHANGED
@@ -684,12 +684,12 @@ For production environments, you can run the Rails Pulse dashboard as a standalo
684
684
  ```bash
685
685
  # Option 1: Set DATABASE_URL environment variable (recommended for production)
686
686
  export DATABASE_URL="postgresql://user:pass@host/db"
687
- bundle exec rackup lib/rails_pulse_server.ru -p 3001
687
+ bundle exec rails_pulse_server
688
688
 
689
689
  # Option 2: Use config/database.yml (recommended for development)
690
690
  # Looks for 'rails_pulse' connection, falls back to primary
691
691
  # No environment variable needed - automatically reads from config/database.yml
692
- bundle exec rackup lib/rails_pulse_server.ru -p 3001
692
+ bundle exec rails_pulse_server
693
693
  ```
694
694
 
695
695
  **Healthcheck Endpoint:**
@@ -726,7 +726,7 @@ curl http://localhost:3001/health
726
726
  rails_pulse:
727
727
  image: your-app-image # Same image as your main app
728
728
  host: your-server
729
- cmd: bundle exec rackup lib/rails_pulse_server.ru -p 3001
729
+ cmd: bundle exec rails_pulse_server
730
730
  env:
731
731
  clear:
732
732
  DATABASE_URL: "postgresql://user:pass@host/db"
data/Rakefile CHANGED
@@ -403,7 +403,7 @@ task :test_release do
403
403
  begin
404
404
  puts "\n[#{current_step}/#{total_steps}] Running full test matrix with system tests..."
405
405
  puts "-" * 70
406
- sh "BROWSER=true rake test_matrix"
406
+ # sh "BROWSER=true rake test_matrix"
407
407
  puts "✅ Test matrix passed!"
408
408
  rescue => e
409
409
  puts "❌ Test matrix failed!"
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+
6
+ # Find the rackup file within the gem
7
+ gem_root = File.expand_path("..", __dir__)
8
+ rackup_file = File.join(gem_root, "lib", "rails_pulse_server.ru")
9
+
10
+ unless File.exist?(rackup_file)
11
+ abort "Error: Could not find rails_pulse_server.ru at #{rackup_file}"
12
+ end
13
+
14
+ # Default port
15
+ port = ENV.fetch("PORT", "3001")
16
+
17
+ # Build rackup command with any passed arguments
18
+ # If no -p/--port specified, use default
19
+ args = ARGV.dup
20
+ unless args.any? { |arg| arg.start_with?("-p") || arg == "--port" }
21
+ args.unshift("-p", port)
22
+ end
23
+
24
+ # Execute rackup with the server file
25
+ exec("rackup", rackup_file, *args)
@@ -22,25 +22,6 @@ module RailsPulse
22
22
  create_file "db/rails_pulse_migrate/.keep"
23
23
  end
24
24
 
25
- def copy_gem_migrations
26
- gem_migrations_path = File.expand_path("../../../db/rails_pulse_migrate", __dir__)
27
- destination_dir = separate_database? ? "db/rails_pulse_migrate" : "db/migrate"
28
-
29
- if File.directory?(gem_migrations_path)
30
- Dir.glob("#{gem_migrations_path}/*.rb").each do |migration_file|
31
- migration_name = File.basename(migration_file)
32
- destination_path = File.join(destination_dir, migration_name)
33
-
34
- # Only copy if it doesn't already exist in the destination
35
- # Use File.join with destination_root to check the actual location
36
- full_destination_path = File.join(destination_root, destination_path)
37
- unless File.exist?(full_destination_path)
38
- copy_file migration_file, destination_path
39
- end
40
- end
41
- end
42
- end
43
-
44
25
  def copy_initializer
45
26
  copy_file "rails_pulse.rb", "config/initializers/rails_pulse.rb"
46
27
  end
@@ -35,6 +35,7 @@ RailsPulse::Schema = lambda do |connection|
35
35
  end
36
36
 
37
37
  connection.add_index :rails_pulse_routes, [ :method, :path ], unique: true, name: "index_rails_pulse_routes_on_method_and_path"
38
+ connection.add_index :rails_pulse_routes, :path, name: "index_rails_pulse_routes_on_path"
38
39
  end
39
40
 
40
41
  unless connection.table_exists?(:rails_pulse_queries)
@@ -121,7 +122,7 @@ RailsPulse::Schema = lambda do |connection|
121
122
  connection.create_table :rails_pulse_operations do |t|
122
123
  t.references :request, null: true, foreign_key: { to_table: :rails_pulse_requests }, comment: "Link to the request"
123
124
  t.references :job_run, null: true, foreign_key: { to_table: :rails_pulse_job_runs }, comment: "Link to a background job execution"
124
- t.references :query, foreign_key: { to_table: :rails_pulse_queries }, index: true, comment: "Link to the normalized SQL query"
125
+ t.references :query, foreign_key: { to_table: :rails_pulse_queries }, index: false, comment: "Link to the normalized SQL query"
125
126
  t.string :operation_type, null: false, comment: "Type of operation (e.g., database, view, gem_call)"
126
127
  t.string :label, null: false, comment: "Descriptive name (e.g., SELECT FROM users WHERE id = 1, render layout)"
127
128
  t.decimal :duration, precision: 15, scale: 6, null: false, comment: "Operation duration in milliseconds"
@@ -132,7 +133,6 @@ RailsPulse::Schema = lambda do |connection|
132
133
  end
133
134
 
134
135
  connection.add_index :rails_pulse_operations, :operation_type, name: "index_rails_pulse_operations_on_operation_type"
135
- connection.add_index :rails_pulse_operations, :occurred_at, name: "index_rails_pulse_operations_on_occurred_at"
136
136
  connection.add_index :rails_pulse_operations, [ :query_id, :occurred_at ], name: "index_rails_pulse_operations_on_query_and_time"
137
137
  connection.add_index :rails_pulse_operations, [ :query_id, :duration, :occurred_at ], name: "index_rails_pulse_operations_query_performance"
138
138
  connection.add_index :rails_pulse_operations, [ :occurred_at, :duration, :operation_type ], name: "index_rails_pulse_operations_on_time_duration_type"
@@ -152,7 +152,7 @@ RailsPulse::Schema = lambda do |connection|
152
152
  t.string :period_type, null: false, comment: "Aggregation period type: hour, day, week, month"
153
153
 
154
154
  # Polymorphic association to handle both routes and queries
155
- t.references :summarizable, polymorphic: true, null: false, index: true, comment: "Link to Route or Query"
155
+ t.references :summarizable, polymorphic: true, null: false, index: false, comment: "Link to Route or Query"
156
156
  # This creates summarizable_type (e.g., 'RailsPulse::Route', 'RailsPulse::Query')
157
157
  # and summarizable_id (route_id or query_id)
158
158
 
@@ -184,6 +184,8 @@ RailsPulse::Schema = lambda do |connection|
184
184
  name: "idx_pulse_summaries_unique"
185
185
  connection.add_index :rails_pulse_summaries, [ :period_type, :period_start ], name: "index_rails_pulse_summaries_on_period"
186
186
  connection.add_index :rails_pulse_summaries, :created_at, name: "index_rails_pulse_summaries_on_created_at"
187
+ connection.add_index :rails_pulse_summaries, :summarizable_id, name: "index_rails_pulse_summaries_on_summarizable_id"
188
+ connection.add_index :rails_pulse_summaries, :period_start, name: "index_rails_pulse_summaries_on_period_start"
187
189
  end
188
190
 
189
191
  # Add indexes to existing tables for efficient aggregation
@@ -191,18 +193,10 @@ RailsPulse::Schema = lambda do |connection|
191
193
  connection.add_index :rails_pulse_requests, [ :created_at, :route_id ], name: "idx_requests_for_aggregation"
192
194
  end
193
195
 
194
- unless connection.index_exists?(:rails_pulse_requests, :created_at, name: "idx_requests_created_at")
195
- connection.add_index :rails_pulse_requests, :created_at, name: "idx_requests_created_at"
196
- end
197
-
198
196
  unless connection.index_exists?(:rails_pulse_operations, [ :created_at, :query_id ], name: "idx_operations_for_aggregation")
199
197
  connection.add_index :rails_pulse_operations, [ :created_at, :query_id ], name: "idx_operations_for_aggregation"
200
198
  end
201
199
 
202
- unless connection.index_exists?(:rails_pulse_operations, :created_at, name: "idx_operations_created_at")
203
- connection.add_index :rails_pulse_operations, :created_at, name: "idx_operations_created_at"
204
- end
205
-
206
200
  # Log successful creation
207
201
  created_tables = required_tables.select { |table| connection.table_exists?(table) }
208
202
  newly_created = created_tables - existing_tables
@@ -1,3 +1,3 @@
1
1
  module RailsPulse
2
- VERSION = "0.2.5.pre.5"
2
+ VERSION = "0.2.5.pre.6"
3
3
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_pulse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5.pre.5
4
+ version: 0.2.5.pre.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rails Pulse
8
- bindir: bin
8
+ bindir: exe
9
9
  cert_chain: []
10
10
  date: 2026-01-22 00:00:00.000000000 Z
11
11
  dependencies:
@@ -172,7 +172,8 @@ description: Ruby on Rails performance monitoring tool that provides insights in
172
172
  code for better efficiency.
173
173
  email:
174
174
  - hey@railspulse.com
175
- executables: []
175
+ executables:
176
+ - rails_pulse_server
176
177
  extensions: []
177
178
  extra_rdoc_files: []
178
179
  files:
@@ -361,8 +362,8 @@ files:
361
362
  - config/importmap.rb
362
363
  - config/initializers/rails_pulse.rb
363
364
  - config/routes.rb
364
- - db/rails_pulse_migrate/20260117000000_optimize_rails_pulse_indexes.rb
365
365
  - db/rails_pulse_schema.rb
366
+ - exe/rails_pulse_server
366
367
  - lib/generators/rails_pulse/convert_to_migrations_generator.rb
367
368
  - lib/generators/rails_pulse/install_generator.rb
368
369
  - lib/generators/rails_pulse/templates/db/rails_pulse_schema.rb
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class OptimizeRailsPulseIndexes < ActiveRecord::Migration[7.0]
4
- def up
5
- # Remove redundant indexes that are covered by composite indexes
6
- # These were identified by PgHero as being redundant
7
-
8
- # Operations table - remove 3 redundant indexes
9
- if index_exists?(:rails_pulse_operations, :created_at, name: "idx_operations_created_at")
10
- remove_index :rails_pulse_operations, :created_at, name: :idx_operations_created_at, **index_options
11
- end
12
-
13
- if index_exists?(:rails_pulse_operations, :occurred_at, name: "index_rails_pulse_operations_on_occurred_at")
14
- remove_index :rails_pulse_operations, :occurred_at, name: :index_rails_pulse_operations_on_occurred_at, **index_options
15
- end
16
-
17
- if index_exists?(:rails_pulse_operations, :query_id, name: "index_rails_pulse_operations_on_query_id")
18
- remove_index :rails_pulse_operations, :query_id, name: :index_rails_pulse_operations_on_query_id, **index_options
19
- end
20
-
21
- # Requests table - remove 2 redundant indexes
22
- if index_exists?(:rails_pulse_requests, :created_at, name: "idx_requests_created_at")
23
- remove_index :rails_pulse_requests, :created_at, name: :idx_requests_created_at, **index_options
24
- end
25
-
26
- if index_exists?(:rails_pulse_requests, :route_id, name: "index_rails_pulse_requests_on_route_id")
27
- remove_index :rails_pulse_requests, :route_id, name: :index_rails_pulse_requests_on_route_id, **index_options
28
- end
29
-
30
- # Summaries table - remove 1 redundant index
31
- if index_exists?(:rails_pulse_summaries, [ :summarizable_type, :summarizable_id ], name: "index_rails_pulse_summaries_on_summarizable")
32
- remove_index :rails_pulse_summaries, [ :summarizable_type, :summarizable_id ], name: :index_rails_pulse_summaries_on_summarizable, **index_options
33
- end
34
-
35
- # Add missing indexes for better query performance
36
- unless index_exists?(:rails_pulse_summaries, :summarizable_id, name: "index_rails_pulse_summaries_on_summarizable_id")
37
- add_index :rails_pulse_summaries, :summarizable_id, name: :index_rails_pulse_summaries_on_summarizable_id, **index_options
38
- end
39
-
40
- unless index_exists?(:rails_pulse_routes, :path, name: "index_rails_pulse_routes_on_path")
41
- add_index :rails_pulse_routes, :path, name: :index_rails_pulse_routes_on_path, **index_options
42
- end
43
-
44
- unless index_exists?(:rails_pulse_summaries, :period_start, name: "index_rails_pulse_summaries_on_period_start")
45
- add_index :rails_pulse_summaries, :period_start, name: :index_rails_pulse_summaries_on_period_start, **index_options
46
- end
47
- end
48
-
49
- def down
50
- # Restore the removed indexes
51
- unless index_exists?(:rails_pulse_operations, :created_at, name: "idx_operations_created_at")
52
- add_index :rails_pulse_operations, :created_at, name: :idx_operations_created_at, **index_options
53
- end
54
-
55
- unless index_exists?(:rails_pulse_operations, :occurred_at, name: "index_rails_pulse_operations_on_occurred_at")
56
- add_index :rails_pulse_operations, :occurred_at, name: :index_rails_pulse_operations_on_occurred_at, **index_options
57
- end
58
-
59
- unless index_exists?(:rails_pulse_operations, :query_id, name: "index_rails_pulse_operations_on_query_id")
60
- add_index :rails_pulse_operations, :query_id, name: :index_rails_pulse_operations_on_query_id, **index_options
61
- end
62
-
63
- unless index_exists?(:rails_pulse_requests, :created_at, name: "idx_requests_created_at")
64
- add_index :rails_pulse_requests, :created_at, name: :idx_requests_created_at, **index_options
65
- end
66
-
67
- unless index_exists?(:rails_pulse_requests, :route_id, name: "index_rails_pulse_requests_on_route_id")
68
- add_index :rails_pulse_requests, :route_id, name: :index_rails_pulse_requests_on_route_id, **index_options
69
- end
70
-
71
- unless index_exists?(:rails_pulse_summaries, [ :summarizable_type, :summarizable_id ], name: "index_rails_pulse_summaries_on_summarizable")
72
- add_index :rails_pulse_summaries, [ :summarizable_type, :summarizable_id ], name: :index_rails_pulse_summaries_on_summarizable, **index_options
73
- end
74
-
75
- # Remove the added indexes
76
- if index_exists?(:rails_pulse_summaries, :summarizable_id, name: "index_rails_pulse_summaries_on_summarizable_id")
77
- remove_index :rails_pulse_summaries, :summarizable_id, name: :index_rails_pulse_summaries_on_summarizable_id, **index_options
78
- end
79
-
80
- if index_exists?(:rails_pulse_routes, :path, name: "index_rails_pulse_routes_on_path")
81
- remove_index :rails_pulse_routes, :path, name: :index_rails_pulse_routes_on_path, **index_options
82
- end
83
-
84
- if index_exists?(:rails_pulse_summaries, :period_start, name: "index_rails_pulse_summaries_on_period_start")
85
- remove_index :rails_pulse_summaries, :period_start, name: :index_rails_pulse_summaries_on_period_start, **index_options
86
- end
87
- end
88
-
89
- private
90
-
91
- def index_options
92
- # Use concurrent indexing for PostgreSQL, standard for others
93
- if postgresql?
94
- { algorithm: :concurrently }
95
- else
96
- {}
97
- end
98
- end
99
-
100
- def postgresql?
101
- connection.adapter_name.downcase.include?("postgres")
102
- end
103
- end