Module: PgHero

Extended by:
Forwardable
Defined in:
lib/pghero.rb,
lib/pghero/stats.rb,
lib/pghero/engine.rb,
lib/pghero/version.rb,
lib/pghero/database.rb,
lib/pghero/connection.rb,
lib/pghero/query_stats.rb,
lib/pghero/space_stats.rb,
lib/pghero/methods/kill.rb,
lib/pghero/methods/basic.rb,
lib/pghero/methods/space.rb,
lib/pghero/methods/users.rb,
lib/pghero/methods/system.rb,
lib/pghero/methods/tables.rb,
lib/pghero/methods/explain.rb,
lib/pghero/methods/indexes.rb,
lib/pghero/methods/queries.rb,
lib/pghero/methods/settings.rb,
lib/pghero/methods/sequences.rb,
lib/pghero/methods/connections.rb,
lib/pghero/methods/constraints.rb,
lib/pghero/methods/maintenance.rb,
lib/pghero/methods/query_stats.rb,
lib/pghero/methods/replication.rb,
app/helpers/pg_hero/home_helper.rb,
lib/pghero/methods/suggested_indexes.rb,
app/controllers/pg_hero/home_controller.rb

Defined Under Namespace

Modules: HomeHelper, Methods Classes: Connection, Database, Engine, Error, HomeController, NotEnabled, QueryStats, SpaceStats, Stats

Constant Summary collapse

MUTEX =
Mutex.new
VERSION =
"2.5.1"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.cache_hit_rate_thresholdObject

Returns the value of attribute cache_hit_rate_threshold.



41
42
43
# File 'lib/pghero.rb', line 41

def cache_hit_rate_threshold
  @cache_hit_rate_threshold
end

.config_pathObject

Returns the value of attribute config_path.



41
42
43
# File 'lib/pghero.rb', line 41

def config_path
  @config_path
end

.envObject

Returns the value of attribute env.



41
42
43
# File 'lib/pghero.rb', line 41

def env
  @env
end

.explain_timeout_secObject

Returns the value of attribute explain_timeout_sec.



41
42
43
# File 'lib/pghero.rb', line 41

def explain_timeout_sec
  @explain_timeout_sec
end

.filter_dataObject

Returns the value of attribute filter_data.



41
42
43
# File 'lib/pghero.rb', line 41

def filter_data
  @filter_data
end

.long_running_query_secObject

Returns the value of attribute long_running_query_sec.



41
42
43
# File 'lib/pghero.rb', line 41

def long_running_query_sec
  @long_running_query_sec
end

.show_migrationsObject

Returns the value of attribute show_migrations.



41
42
43
# File 'lib/pghero.rb', line 41

def show_migrations
  @show_migrations
end

.slow_query_callsObject

Returns the value of attribute slow_query_calls.



41
42
43
# File 'lib/pghero.rb', line 41

def slow_query_calls
  @slow_query_calls
end

.slow_query_msObject

Returns the value of attribute slow_query_ms.



41
42
43
# File 'lib/pghero.rb', line 41

def slow_query_ms
  @slow_query_ms
end

.total_connections_thresholdObject

Returns the value of attribute total_connections_threshold.



41
42
43
# File 'lib/pghero.rb', line 41

def total_connections_threshold
  @total_connections_threshold
end

Class Method Details

.analyze_all(**options) ⇒ Object



176
177
178
179
180
181
# File 'lib/pghero.rb', line 176

def analyze_all(**options)
  each_database do |database|
    next if database.replica?
    database.analyze_tables(**options)
  end
end

.autoindex_all(create: false, verbose: true) ⇒ Object



183
184
185
186
187
188
# File 'lib/pghero.rb', line 183

def autoindex_all(create: false, verbose: true)
  each_database do |database|
    puts "Autoindexing #{database.id}..." if verbose
    database.autoindex(create: create)
  end
end

.capture_query_stats(verbose: false) ⇒ Object



161
162
163
164
165
166
167
# File 'lib/pghero.rb', line 161

def capture_query_stats(verbose: false)
  each_database do |database|
    next unless database.capture_query_stats?
    puts "Capturing query stats for #{database.id}..." if verbose
    database.capture_query_stats(raise_errors: true)
  end
end

.capture_space_stats(verbose: false) ⇒ Object



169
170
171
172
173
174
# File 'lib/pghero.rb', line 169

def capture_space_stats(verbose: false)
  each_database do |database|
    puts "Capturing space stats for #{database.id}..." if verbose
    database.capture_space_stats
  end
end

.clean_query_statsObject

delete previous stats go database by database to use an index stats for old databases are not cleaned up since we can’t use an index



197
198
199
200
201
# File 'lib/pghero.rb', line 197

def clean_query_stats
  each_database do |database|
    PgHero::QueryStats.where(database: database.id).where("captured_at < ?", 14.days.ago).delete_all
  end
end

.clean_space_statsObject



203
204
205
206
207
# File 'lib/pghero.rb', line 203

def clean_space_stats
  each_database do |database|
    PgHero::SpaceStats.where(database: database.id).where("captured_at < ?", 90.days.ago).delete_all
  end
end

.configObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/pghero.rb', line 93

def config
  @config ||= begin
    require "erb"
    require "yaml"

    path = config_path

    config_file_exists = File.exist?(path)

    config = YAML.load(ERB.new(File.read(path)).result) if config_file_exists
    config ||= {}

    if config[env]
      config[env]
    elsif config["databases"] # preferred format
      config
    elsif config_file_exists
      raise "Invalid config file"
    else
      databases = {}

      if !ENV["PGHERO_DATABASE_URL"] && spec_supported?
        ActiveRecord::Base.configurations.configs_for(env_name: env, include_replicas: true).each do |db|
          databases[db.spec_name] = {"spec" => db.spec_name}
        end
      end

      if databases.empty?
        databases["primary"] = {
          "url" => ENV["PGHERO_DATABASE_URL"] || ActiveRecord::Base.connection_config
        }
      end

      if databases.size == 1
        databases.values.first.merge!(
          "db_instance_identifier" => ENV["PGHERO_DB_INSTANCE_IDENTIFIER"],
          "gcp_database_id" => ENV["PGHERO_GCP_DATABASE_ID"],
          "azure_resource_id" => ENV["PGHERO_AZURE_RESOURCE_ID"]
        )
      end

      {
        "databases" => databases
      }
    end
  end
end

.databasesObject

ensure we only have one copy of databases so there’s only one connection pool per database



143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/pghero.rb', line 143

def databases
  unless defined?(@databases)
    # only use mutex on initialization
    MUTEX.synchronize do
      # return if another process initialized while we were waiting
      return @databases if defined?(@databases)

      @databases = config["databases"].map { |id, c| [id.to_sym, Database.new(id, c)] }.to_h
    end
  end

  @databases
end

.passwordObject

use method instead of attr_accessor to ensure this works if variable set after PgHero is loaded



85
86
87
# File 'lib/pghero.rb', line 85

def password
  @password ||= config["password"] || ENV["PGHERO_PASSWORD"]
end

.pretty_size(value) ⇒ Object



190
191
192
# File 'lib/pghero.rb', line 190

def pretty_size(value)
  ActiveSupport::NumberHelper.number_to_human_size(value, precision: 3)
end

.primary_databaseObject



157
158
159
# File 'lib/pghero.rb', line 157

def primary_database
  databases.values.first
end

.spec_supported?Boolean

private

Returns:

  • (Boolean)


210
211
212
# File 'lib/pghero.rb', line 210

def spec_supported?
  ActiveRecord::VERSION::MAJOR >= 6
end

.stats_database_urlObject



89
90
91
# File 'lib/pghero.rb', line 89

def stats_database_url
  @stats_database_url ||= config["stats_database_url"] || ENV["PGHERO_STATS_DATABASE_URL"]
end

.time_zoneObject



73
74
75
# File 'lib/pghero.rb', line 73

def time_zone
  @time_zone || Time.zone
end

.time_zone=(time_zone) ⇒ Object



69
70
71
# File 'lib/pghero.rb', line 69

def time_zone=(time_zone)
  @time_zone = time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone[time_zone.to_s]
end

.usernameObject

use method instead of attr_accessor to ensure this works if variable set after PgHero is loaded



79
80
81
# File 'lib/pghero.rb', line 79

def username
  @username ||= config["username"] || ENV["PGHERO_USERNAME"]
end