Module: PgReports

Defined in:
lib/pg_reports.rb,
lib/pg_reports/error.rb,
lib/pg_reports/engine.rb,
lib/pg_reports/filter.rb,
lib/pg_reports/report.rb,
lib/pg_reports/version.rb,
lib/pg_reports/executor.rb,
lib/pg_reports/sql_loader.rb,
lib/pg_reports/compatibility.rb,
lib/pg_reports/configuration.rb,
lib/pg_reports/query_monitor.rb,
lib/pg_reports/report_loader.rb,
lib/pg_reports/modules/system.rb,
lib/pg_reports/modules/tables.rb,
lib/pg_reports/modules/indexes.rb,
lib/pg_reports/modules/queries.rb,
lib/pg_reports/telegram_sender.rb,
lib/pg_reports/explain_analyzer.rb,
lib/pg_reports/grafana/exporter.rb,
lib/pg_reports/module_generator.rb,
lib/pg_reports/annotation_parser.rb,
lib/pg_reports/connection/target.rb,
lib/pg_reports/report_definition.rb,
lib/pg_reports/connection/registry.rb,
lib/pg_reports/modules/connections.rb,
lib/pg_reports/modules/schema_analysis.rb,
lib/pg_reports/grafana/dashboard_builder.rb,
lib/pg_reports/dashboard/reports_registry.rb,
lib/pg_reports/connection/error_translator.rb,
app/controllers/pg_reports/metrics_controller.rb,
app/controllers/pg_reports/dashboard_controller.rb

Defined Under Namespace

Modules: AnnotationParser, Compatibility, Connection, Dashboard, Grafana, Modules, SqlLoader, TelegramSender Classes: Configuration, ConnectionError, DashboardController, Engine, Error, Executor, ExplainAnalyzer, Filter, MetricsController, ModuleGenerator, QueryMonitor, Report, ReportDefinition, ReportLoader, SqlFileNotFoundError, TelegramNotConfiguredError

Constant Summary collapse

VERSION =
"0.8.0"

Class Method Summary collapse

Class Method Details

.configObject



150
151
152
# File 'lib/pg_reports/configuration.rb', line 150

def config
  configuration
end

.configurationObject



142
143
144
# File 'lib/pg_reports/configuration.rb', line 142

def configuration
  @configuration ||= Configuration.new
end

.configure {|configuration| ... } ⇒ Object

Yields:



146
147
148
# File 'lib/pg_reports/configuration.rb', line 146

def configure
  yield(configuration)
end

.connection_registryObject

Connection registry — multi-target / multi-database support. The :primary target is auto-discovered from ActiveRecord on first access.



147
148
149
# File 'lib/pg_reports.rb', line 147

def connection_registry
  @connection_registry ||= Connection::Registry.new
end

.connectionsObject



127
128
129
# File 'lib/pg_reports.rb', line 127

def connections
  Modules::Connections
end

.current_database_nameObject

Name of the currently effective database (taking with_database into account).



176
177
178
# File 'lib/pg_reports.rb', line 176

def current_database_name
  connection_registry.current_database_name
end

.current_target_nameObject

Name of the currently effective target (taking with_target into account).



171
172
173
# File 'lib/pg_reports.rb', line 171

def current_target_name
  connection_registry.current_name || connection_registry.default_name
end

.health_reportReport

Generate a comprehensive database health report

Returns:

  • (Report)

    Combined health report



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/pg_reports.rb', line 82

def health_report
  # Collect all reports
  reports = {
    "Slow Queries" => slow_queries(limit: 10),
    "Expensive Queries" => expensive_queries(limit: 10),
    "Unused Indexes" => unused_indexes(limit: 10),
    "Tables Needing Vacuum" => vacuum_needed(limit: 10),
    "Long Running Queries" => long_running_queries,
    "Blocking Queries" => blocking_queries
  }

  # Build combined data
  combined_data = reports.map do |name, report|
    {
      "section" => name,
      "items_count" => report.size,
      "has_issues" => report.size.positive?
    }
  end

  Report.new(
    title: "Database Health Report",
    data: combined_data,
    columns: %w[section items_count has_issues]
  )
end

.indexesObject



119
120
121
# File 'lib/pg_reports.rb', line 119

def indexes
  Modules::Indexes
end

.list_databasesObject

List databases on the currently active target’s cluster. Each row: { “name” => String, “size” => String, “current” => Boolean }



182
183
184
185
# File 'lib/pg_reports.rb', line 182

def list_databases
  target = connection_registry.fetch
  target.list_databases(current: current_database_name)
end

.list_targetsObject

List of registered targets, each as { name:, default_database:, current: }.



188
189
190
191
192
193
# File 'lib/pg_reports.rb', line 188

def list_targets
  current = current_target_name
  connection_registry.targets.map do |t|
    {name: t.name, default_database: t.default_database, current: t.name == current}
  end
end

.queriesObject

Shorthand for accessing modules directly



115
116
117
# File 'lib/pg_reports.rb', line 115

def queries
  Modules::Queries
end

.reload_definitions!Object

Reload YAML report definitions and regenerate module methods



140
141
142
143
# File 'lib/pg_reports.rb', line 140

def reload_definitions!
  ReportLoader.reload!
  ModuleGenerator.generate!
end

.reset_configuration!Object



154
155
156
# File 'lib/pg_reports/configuration.rb', line 154

def reset_configuration!
  @configuration = Configuration.new
end

.schema_analysisObject



135
136
137
# File 'lib/pg_reports.rb', line 135

def schema_analysis
  Modules::SchemaAnalysis
end

.send_health_report_to_telegramObject

Run all reports and send summary to Telegram



110
111
112
# File 'lib/pg_reports.rb', line 110

def send_health_report_to_telegram
  health_report.send_to_telegram
end

.systemObject



131
132
133
# File 'lib/pg_reports.rb', line 131

def system
  Modules::System
end

.tablesObject



123
124
125
# File 'lib/pg_reports.rb', line 123

def tables
  Modules::Tables
end

.with_database(database, &block) ⇒ Object

Switch only the database on whatever target is currently active (defaults to the registry’s default target).

PgReports.with_database("reporting") { PgReports.database_sizes }


165
166
167
168
# File 'lib/pg_reports.rb', line 165

def with_database(database, &block)
  target = connection_registry.current_name || connection_registry.default_name
  connection_registry.with_context(target: target, database: database, &block)
end

.with_target(name, database: nil, &block) ⇒ Object

Run a block against a specific target (and optionally a specific database on that target). Honored by Executor and any code routing through PgReports.config.connection.

PgReports.with_target(:analytics) { PgReports.slow_queries }
PgReports.with_target(:primary, database: "logs") { PgReports.table_sizes }


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

def with_target(name, database: nil, &block)
  connection_registry.with_context(target: name, database: database, &block)
end