pg_insights 0.1.0 → 0.2.1

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/config/routes.rb CHANGED
@@ -1,14 +1,11 @@
1
1
  PgInsights::Engine.routes.draw do
2
2
  root "insights#index"
3
3
 
4
- # For running queries and loading the main UI
5
4
  post "/", to: "insights#index"
6
-
7
- # For the table name dropdown
8
5
  get :table_names, to: "insights#table_names"
9
6
 
10
- # For managing user-saved queries
11
- resources :queries, only: [ :create, :update, :destroy ] # For the health dashboard
7
+ resources :queries, only: [ :create, :update, :destroy ]
8
+
12
9
  get :health, to: "health#index"
13
10
  namespace :health do
14
11
  get :unused_indexes
@@ -19,4 +16,11 @@ PgInsights::Engine.routes.draw do
19
16
  get :parameter_settings
20
17
  post :refresh
21
18
  end
19
+
20
+ get :timeline, to: "timeline#index"
21
+ get "timeline/compare", to: "timeline#compare", as: :timeline_compare
22
+ get "timeline/export", to: "timeline#export", as: :timeline_export
23
+ get "timeline/status", to: "timeline#status", as: :timeline_status
24
+ post "timeline/refresh", to: "timeline#refresh", as: :timeline_refresh
25
+ get "timeline/:id", to: "timeline#show", as: :timeline_show
22
26
  end
@@ -7,7 +7,7 @@ module PgInsights
7
7
  class InstallGenerator < Rails::Generators::Base
8
8
  include Rails::Generators::Migration
9
9
 
10
- source_root File.expand_path("../../../..", __FILE__)
10
+ source_root File.expand_path("templates", __dir__)
11
11
 
12
12
  def self.next_migration_number(dirname)
13
13
  ActiveRecord::Generators::Base.next_migration_number(dirname)
@@ -47,11 +47,28 @@ module PgInsights
47
47
  puts "Next steps:"
48
48
  puts "1. Run 'rails db:migrate' to create the necessary tables"
49
49
  puts "2. Review and customize 'config/initializers/pg_insights.rb'"
50
- puts "3. Configure background jobs (optional, see initializer comments)"
51
- puts "4. Visit '/pg_insights' in your browser to start using the dashboard"
50
+ puts "3. Test your setup: rails pg_insights:status"
51
+ puts "4. Configure background jobs (optional, see initializer comments)"
52
+ puts "5. Visit '/pg_insights' in your browser to start using the dashboard"
52
53
  puts ""
53
- puts "For background job integration, see: config/initializers/pg_insights.rb"
54
- puts "To check status: rails pg_insights:status"
54
+ puts "Features available:"
55
+ puts " Health Dashboard: '/pg_insights/health' - Monitor database health"
56
+ puts "• Query Runner: '/pg_insights' - Run SQL queries with charts"
57
+ puts "• Timeline: '/pg_insights/timeline' - Track parameter changes over time"
58
+ puts ""
59
+ puts "Useful commands:"
60
+ puts "• Status check: rails pg_insights:status"
61
+ puts "• Test setup: rails pg_insights:test_jobs"
62
+ puts "• Collect snapshot: rails pg_insights:collect_snapshot"
63
+ puts "• Start snapshots: rails pg_insights:start_snapshots"
64
+ puts "• Snapshot status: rails pg_insights:snapshot_status"
65
+ puts ""
66
+ puts "For development/testing:"
67
+ puts "• Generate test data: rails pg_insights:seed_timeline"
68
+ puts "• View all commands: rails -T pg_insights"
69
+ puts ""
70
+ puts "Configuration: config/initializers/pg_insights.rb"
71
+ puts "Documentation: https://github.com/mezbahalam/pg_insights"
55
72
  puts "To uninstall: rails generate pg_insights:clean"
56
73
  end
57
74
 
@@ -81,7 +98,6 @@ module PgInsights
81
98
  config.background_job_queue = :pg_insights_health
82
99
 
83
100
  # === Cache and Timeout Settings ===
84
- #{' '}
85
101
  # How long to cache health check results before considering them stale
86
102
  # Stale results will trigger background refresh when accessed
87
103
  #
@@ -91,40 +107,75 @@ module PgInsights
91
107
  # Timeout for individual health check queries to prevent long-running queries
92
108
  # from blocking the application
93
109
  #
94
- # Default: 10.seconds#{' '}
110
+ # Default: 10.seconds
95
111
  config.health_check_timeout = 10.seconds
96
112
 
97
113
  # Maximum execution time for user queries in the insights interface
98
114
  #
99
115
  # Default: 30.seconds
100
116
  config.max_query_execution_time = 30.seconds
117
+
118
+ # === Timeline & Snapshot Settings ===
119
+ #
120
+ # The timeline feature captures daily snapshots of your database's
121
+ # performance metrics and configuration parameters.
122
+
123
+ # Enable or disable the timeline feature entirely.
124
+ # Disabling this will hide the timeline UI and stop snapshot collection.
125
+ #
126
+ # Default: true
127
+ config.enable_snapshots = true
128
+
129
+ # How often to collect a new database snapshot.
130
+ # This setting is used by the recurring snapshot job.
131
+ #
132
+ # Default: 1.day
133
+ config.snapshot_frequency = 1.day
134
+
135
+ # How long to keep snapshots before they are automatically deleted.
136
+ # Older snapshots will be pruned to save database space.
137
+ #
138
+ # Default: 90 (days)
139
+ config.snapshot_retention_days = 90
140
+
141
+ # A master switch to enable or disable the snapshot collection job.
142
+ # This is useful if you want to temporarily pause snapshot collection
143
+ # without disabling the entire feature.
144
+ #
145
+ # Default: true
146
+ config.snapshot_collection_enabled = true
101
147
  end
102
148
 
103
149
  # === Background Job Integration ===
104
150
  #
105
- # If you want automatic recurring health checks, add one of these to your job scheduler:
151
+ # PgInsights works with or without background jobs:
152
+ # - WITH background jobs: Health checks run asynchronously (recommended)
153
+ # - WITHOUT background jobs: Health checks run synchronously (slower but works)
106
154
  #
107
- # ** Whenever (crontab) **
108
- # Add to config/schedule.rb:
155
+ # ** Test Your Setup **
156
+ # Check if background jobs are working:
157
+ # rails pg_insights:status
158
+ # rails pg_insights:test_jobs
159
+ #
160
+ # ** Automatic Recurring Health Checks (Optional) **
161
+ # If you want health checks to run automatically, add one of these to your job scheduler:
162
+ #
163
+ # Whenever (crontab) - Add to config/schedule.rb:
109
164
  # every 1.hour do
110
165
  # runner "PgInsights::RecurringHealthChecksJob.perform_later"
111
166
  # end
112
167
  #
113
- # ** Sidekiq-Cron **
114
- # Add to config/initializers/sidekiq.rb:
168
+ # Sidekiq-Cron - Add to config/initializers/sidekiq.rb:
115
169
  # Sidekiq::Cron::Job.create(
116
170
  # name: 'PgInsights Health Checks',
117
171
  # cron: '0 * * * *',
118
172
  # class: 'PgInsights::RecurringHealthChecksJob'
119
173
  # )
120
174
  #
121
- # ** Manual Trigger **
122
- # You can also trigger health checks manually:
123
- # PgInsights::HealthCheckService.refresh_all!
124
- #
125
- # ** Check Status **
126
- # To verify your configuration:
127
- # rails pg_insights:status
175
+ # ** Manual Commands **
176
+ # Run health checks manually: rails pg_insights:health_check
177
+ # Collect snapshot now: rails pg_insights:collect_snapshot
178
+ # Start recurring snapshots: rails pg_insights:start_snapshots
128
179
 
129
180
  # === Environment-Specific Settings ===
130
181
  #
@@ -0,0 +1,16 @@
1
+ class CreatePgInsightsHealthCheckResults < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :pg_insights_health_check_results do |t|
4
+ t.string :check_type, null: false, limit: 50
5
+ t.json :result_data
6
+ t.string :status, null: false, default: "pending", limit: 20
7
+ t.text :error_message
8
+ t.datetime :executed_at
9
+ t.integer :execution_time_ms
10
+ t.timestamps
11
+
12
+ t.index [ :check_type, :executed_at ], name: "idx_pg_insights_health_check_type_executed_at"
13
+ t.index [ :status, :executed_at ], name: "idx_pg_insights_health_status_executed_at"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ class CreatePgInsightsQueries < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :pg_insights_queries do |t|
4
+ t.string :name, null: false
5
+ t.text :sql, null: false
6
+ t.string :description
7
+ t.string :category, null: false, default: "saved"
8
+ t.timestamps
9
+ end
10
+ add_index :pg_insights_queries, :name, unique: true
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module PgInsights
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.1"
3
3
  end
data/lib/pg_insights.rb CHANGED
@@ -2,25 +2,27 @@ require "pg_insights/version"
2
2
  require "pg_insights/engine"
3
3
 
4
4
  module PgInsights
5
- # Configuration options
6
5
  mattr_accessor :enable_background_jobs, default: true
7
6
  mattr_accessor :health_cache_expiry, default: 5.minutes
8
7
  mattr_accessor :background_job_queue, default: :pg_insights_health
9
8
  mattr_accessor :max_query_execution_time, default: 30.seconds
10
9
  mattr_accessor :health_check_timeout, default: 10.seconds
11
10
 
11
+ mattr_accessor :enable_snapshots, default: true
12
+ mattr_accessor :snapshot_frequency, default: 1.day
13
+ mattr_accessor :snapshot_retention_days, default: 90
14
+ mattr_accessor :snapshot_collection_enabled, default: true
15
+
12
16
  def self.configure
13
17
  yield self
14
18
  end
15
19
 
16
- # Check if background jobs are available and properly configured
17
20
  def self.background_jobs_available?
18
21
  return false unless enable_background_jobs
19
22
  return false unless defined?(ActiveJob::Base)
20
23
  return false if ActiveJob::Base.queue_adapter.is_a?(ActiveJob::QueueAdapters::InlineAdapter)
21
24
  return false unless defined?(PgInsights::HealthCheckJob)
22
25
 
23
- # Verify the queue adapter can handle our jobs
24
26
  begin
25
27
  ActiveJob::Base.queue_adapter.respond_to?(:enqueue) ||
26
28
  ActiveJob::Base.queue_adapter.respond_to?(:enqueue_at)
@@ -30,7 +32,6 @@ module PgInsights
30
32
  end
31
33
  end
32
34
 
33
- # Safely execute background jobs with fallback
34
35
  def self.execute_with_fallback(job_class, method_name, *args, &fallback_block)
35
36
  if background_jobs_available?
36
37
  begin
@@ -41,14 +42,30 @@ module PgInsights
41
42
  end
42
43
  end
43
44
 
44
- # Execute fallback if provided
45
45
  fallback_block.call if fallback_block
46
46
  false
47
47
  end
48
48
 
49
- # Integration helpers for host applications
49
+ def self.snapshots_available?
50
+ return false unless enable_snapshots
51
+ return false unless snapshot_collection_enabled
52
+ return false unless defined?(PgInsights::HealthCheckResult)
53
+
54
+ true
55
+ end
56
+
57
+ def self.snapshot_interval_seconds
58
+ case snapshot_frequency
59
+ when ActiveSupport::Duration
60
+ snapshot_frequency.to_i
61
+ when Integer
62
+ snapshot_frequency
63
+ else
64
+ 1.day.to_i
65
+ end
66
+ end
67
+
50
68
  module Integration
51
- # Helper for host apps to check if they need to configure anything
52
69
  def self.status
53
70
  {
54
71
  background_jobs_available: PgInsights.background_jobs_available?,
@@ -61,15 +78,12 @@ module PgInsights
61
78
  }
62
79
  end
63
80
 
64
- # Helper for host apps to test job functionality
65
81
  def self.test_background_jobs
66
82
  return { success: false, error: "Background jobs disabled" } unless PgInsights.enable_background_jobs
67
83
  return { success: false, error: "ActiveJob not available" } unless defined?(ActiveJob::Base)
68
84
 
69
85
  begin
70
- # Try to enqueue a simple test
71
86
  if defined?(PgInsights::HealthCheckJob)
72
- # Don't actually run the job, just test enqueueing
73
87
  Rails.logger.info "PgInsights: Testing background job capability..."
74
88
  { success: true, message: "Background jobs appear to be working" }
75
89
  else