Skip to content

Commit

Permalink
Add PgHero gem for database monitoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Grigore-George-Mihai committed Oct 23, 2024
1 parent 47f08a1 commit e6ac62d
Show file tree
Hide file tree
Showing 25 changed files with 371 additions and 187 deletions.
22 changes: 19 additions & 3 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2024-10-22 20:34:39 UTC using RuboCop version 1.67.0.
# on 2024-10-23 16:09:59 UTC using RuboCop version 1.67.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 1
# Offense count: 3
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
# URISchemes: http, https
Layout/LineLength:
Exclude:
- 'config/initializers/devise.rb'
- 'config/initializers/simple_form.rb'

# Offense count: 3
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
# AllowedMethods: refine
Metrics/BlockLength:
Max: 43
Max: 273

# Offense count: 1
# Configuration parameters: Include.
# Include: db/**/*.rb
Rails/CreateTableWithTimestamps:
Exclude:
- 'db/migrate/20241023111240_create_pghero_query_stats.rb'
10 changes: 8 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,24 @@ gem "draper"
gem "font-awesome-sass", "~> 6.5.2"
gem "importmap-rails"
gem "jbuilder"
gem "pg", "~> 1.1"
gem "puma", ">= 5.0"
gem "rails", "~> 7.2.1"
gem "redis"
gem "sassc-rails"
gem "sidekiq"
gem "simple_form"
gem "sprockets-rails"
gem "stimulus-rails"
gem "turbo-rails"
gem "tzinfo-data", platforms: %i[windows jruby]

# BackgroundJob and Scheduling
gem "sidekiq"
gem "sidekiq-scheduler"

# Database and Performance Tracking
gem "pg", "~> 1.1"
gem "pghero"

# Authentication
gem "devise"

Expand Down
20 changes: 18 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ GEM
ruby2_keywords
drb (2.2.1)
erubi (1.13.0)
execjs (2.9.1)
et-orbi (1.2.11)
tzinfo
execjs (2.10.0)
factory_bot (6.5.0)
activesupport (>= 5.0.0)
factory_bot_rails (6.4.3)
Expand All @@ -178,6 +180,9 @@ GEM
formtastic (5.0.0)
actionpack (>= 6.0.0)
formtastic_i18n (0.7.0)
fugit (1.11.1)
et-orbi (~> 1, >= 1.2.11)
raabro (~> 1.4)
globalid (1.2.1)
activesupport (>= 6.1)
has_scope (0.8.2)
Expand Down Expand Up @@ -261,12 +266,15 @@ GEM
ast (~> 2.4.1)
racc
pg (1.5.8)
pghero (3.6.1)
activerecord (>= 6.1)
popper_js (2.11.8)
psych (5.1.2)
stringio
public_suffix (6.0.1)
puma (6.4.3)
nio4r (~> 2.0)
raabro (1.4.0)
racc (1.8.1)
rack (3.1.8)
rack-mini-profiler (3.3.1)
Expand Down Expand Up @@ -378,7 +386,7 @@ GEM
rack (>= 1.1)
rubocop (>= 1.52.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rails-suite (1.1.1)
rubocop-rails-suite (1.1.2)
rubocop (>= 1.67, < 2.0)
rubocop-factory_bot (>= 2.26.1, < 3.0)
rubocop-faker (>= 1.1.0, < 2.0)
Expand All @@ -390,6 +398,8 @@ GEM
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
rufus-scheduler (3.9.2)
fugit (~> 1.1, >= 1.11.1)
sassc (2.4.0)
ffi (~> 1.9)
sassc-rails (2.1.2)
Expand All @@ -415,6 +425,10 @@ GEM
logger
rack (>= 2.2.4)
redis-client (>= 0.22.2)
sidekiq-scheduler (5.0.6)
rufus-scheduler (~> 3.2)
sidekiq (>= 6, < 8)
tilt (>= 1.4.0, < 3)
simple_form (5.3.1)
actionpack (>= 5.2)
activemodel (>= 5.2)
Expand Down Expand Up @@ -492,6 +506,7 @@ DEPENDENCIES
importmap-rails
jbuilder
pg (~> 1.1)
pghero
puma (>= 5.0)
rack-mini-profiler
rails (~> 7.2.1)
Expand All @@ -505,6 +520,7 @@ DEPENDENCIES
selenium-webdriver
shoulda-matchers
sidekiq
sidekiq-scheduler
simple_form
simplecov
sprockets-rails
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ git clone https://github.com/Grigore-George-Mihai/default_template

- Update the project name to reflect your application.
- Customize the [Devise](https://github.com/heartcombo/devise) configuration as only basic setup is included; adjust it to suit your specific authentication requirements.
- Modify the [Scout APM](https://github.com/scoutapp/scout_apm_ruby) settings as needed, or remove it if performance tracking is not required.
- Modify the [Rollbar](https://github.com/rollbar/rollbar-gem) settings as needed, or remove it if error tracking is not required.
- Modify or remove the settings for [Scout APM](https://github.com/scoutapp/scout_apm_ruby), [Rollbar](https://github.com/rollbar/rollbar-gem), and [PgHero](https://github.com/ankane/pghero) as needed, based on your performance, error tracking, and database monitoring requirements.
- Run the following rake task to create your environment files:
```bash
rake env:setup
Expand All @@ -37,11 +36,20 @@ git clone https://github.com/Grigore-George-Mihai/default_template
## Gems
### Database and Monitoring
- [pg](https://github.com/ged/ruby-pg): PostgreSQL driver for Ruby, providing fast and efficient database connectivity.
- [PgHero](https://github.com/ankane/pghero): A tool for monitoring PostgreSQL database performance, including query insights, index suggestions, and table size analysis.
### Authentication
- [Devise](https://github.com/heartcombo/devise): Flexible authentication solution for Rails based on Warden.
### Admin Interface
- [ActiveAdmin](https://github.com/activeadmin/activeadmin): A flexible and extensible admin framework for Ruby on Rails applications, making it easy to build custom admin panels.
- [ActiveAdmin Addons](https://github.com/platanus/activeadmin_addons): Enhances ActiveAdmin with additional features like input widgets, searchable selects, and improved UI components for better admin interfaces.
### Background Processing
- [Sidekiq](https://github.com/mperham/sidekiq): Efficient background processing for Ruby applications.
- [Sidekiq-Scheduler](https://github.com/moove-it/sidekiq-scheduler): Extends Sidekiq to support scheduled and recurring jobs using a simple configuration.
- [Redis](https://github.com/redis/redis-rb): In-memory data structure store used by Sidekiq for managing background job queues, scheduling, and retries.
### Decorator and Forms
Expand Down
15 changes: 15 additions & 0 deletions app/sidekiq/pg/capture_query_stats_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require "sidekiq-scheduler"

module Pg
class CaptureQueryStatsJob
include Sidekiq::Job

def perform
Rake::Task.clear
Rails.application.load_tasks
Rake::Task["pghero:capture_query_stats"].invoke
end
end
end
15 changes: 15 additions & 0 deletions app/sidekiq/pg/clear_query_stats_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require "sidekiq-scheduler"

module Pg
class ClearQueryStatsJob
include Sidekiq::Job

def perform
Rake::Task.clear
Rails.application.load_tasks
Rake::Task["pghero:clean_query_stats"].invoke
end
end
end
4 changes: 2 additions & 2 deletions config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ default: &default
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV['POSTGRES_USER'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
username: <%= ENV["POSTGRES_USER"] %>
password: <%= ENV["POSTGRES_PASSWORD"] %>

development:
<<: *default
Expand Down
8 changes: 4 additions & 4 deletions config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@
# config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }

# Log to STDOUT by default
config.logger = ActiveSupport::Logger.new(STDOUT)
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
config.logger = ActiveSupport::Logger.new($stdout)
.tap { |logger| logger.formatter = Logger::Formatter.new }
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }

# Prepend all log lines with the following tags.
config.log_tags = [ :request_id ]
config.log_tags = [:request_id]

# "info" includes generic and useful information about system operation, but avoids logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
Expand Down
8 changes: 4 additions & 4 deletions config/initializers/active_admin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
# roots for each namespace.
#
# Default:
config.root_to = 'users#index'
config.root_to = "users#index"

# == Admin Comments
#
Expand Down Expand Up @@ -168,7 +168,7 @@
# Active Admin resources and pages from here.
#
config.before_action do
redirect_to root_path, alert: I18n.t('active_admin.flash.unauthorized') unless current_user&.admin?
redirect_to root_path, alert: I18n.t("active_admin.flash.unauthorized") unless current_user&.admin?
end

# == Attribute Filters
Expand All @@ -194,7 +194,7 @@
# config.favicon = 'favicon.ico'

# == Meta Tags
meta_tags_options = { viewport: 'width=device-width, initial-scale=1' }
meta_tags_options = { viewport: "width=device-width, initial-scale=1" }

# Add additional meta tags to the head element of active admin pages.
#
Expand Down Expand Up @@ -337,7 +337,7 @@
# By default, the footer shows the current Active Admin version. You can
# override the content of the footer here.
#
config.footer = 'Default Template'
config.footer = "Default Template"

# == Sorting
#
Expand Down
2 changes: 1 addition & 1 deletion config/initializers/assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
Rails.application.config.assets.precompile += %w(bootstrap.min.js popper.js)
Rails.application.config.assets.precompile += %w[bootstrap.min.js popper.js]
8 changes: 4 additions & 4 deletions config/initializers/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"

# Configure the class responsible to send e-mails.
# config.mailer = 'Devise::Mailer'
# config.mailer = "Devise::Mailer"

# Configure the parent class responsible to send e-mails.
# config.parent_mailer = 'ActionMailer::Base'
# config.parent_mailer = "ActionMailer::Base"

# ==> ORM configuration
# Load and configure the ORM. Supports :active_record (default) and
# :mongoid (bson_ext recommended) by default. Other ORMs may be
# available as additional gems.
require 'devise/orm/active_record'
require "devise/orm/active_record"

# ==> Configuration for any authentication mechanism
# Configure which keys are used when authenticating a user. The default is
Expand Down
4 changes: 2 additions & 2 deletions config/initializers/filter_parameter_logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
# Use this to limit dissemination of sensitive information.
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
Rails.application.config.filter_parameters += [
:passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
Rails.application.config.filter_parameters += %i[
passw email secret token _key crypt salt certificate otp ssn
]
2 changes: 1 addition & 1 deletion config/initializers/rack_mini_profiler.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

if Rails.env.development?
require 'rack-mini-profiler'
require "rack-mini-profiler"

# The initializer was required late, so initialize it manually.
Rack::MiniProfilerRails.initialize!(Rails.application)
Expand Down
8 changes: 3 additions & 5 deletions config/initializers/rollbar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
# Without configuration, Rollbar is enabled in all environments.
# To disable in specific environments, set config.enabled=false.

config.access_token = ENV.fetch('ROLLBAR_ACCESS_TOKEN', nil)
config.access_token = ENV.fetch("ROLLBAR_ACCESS_TOKEN", nil)

# Here we'll disable in 'test':
if Rails.env.test?
config.enabled = false
end
config.enabled = false if Rails.env.test?

# By default, Rollbar will try to call the `current_user` controller method
# to fetch the logged-in user object, and then call that object's `id`
Expand Down Expand Up @@ -67,5 +65,5 @@
# environment variable like this: `ROLLBAR_ENV=staging`. This is a recommended
# setup for Heroku. See:
# https://devcenter.heroku.com/articles/deploying-to-a-custom-rails-environment
config.environment = ENV['ROLLBAR_ENV'].presence || Rails.env
config.environment = ENV["ROLLBAR_ENV"].presence || Rails.env
end
4 changes: 2 additions & 2 deletions config/initializers/sidekiq.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
sidekiq_config = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }
sidekiq_config = { url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0") }

Sidekiq.configure_server do |config|
config.redis = sidekiq_config

config.concurrency = 5
config.queues = ['critical', 'default', 'mailers']
config.queues = %w[critical default mailers]
end

Sidekiq.configure_client do |config|
Expand Down
6 changes: 3 additions & 3 deletions config/initializers/simple_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
config.boolean_style = :nested

# Default class for buttons
config.button_class = 'btn'
config.button_class = "btn"

# Method used to tidy up errors. Specify any Rails Array method.
# :first lists the first message for each field.
Expand All @@ -86,7 +86,7 @@
config.error_notification_tag = :div

# CSS class to add for error notification helper.
config.error_notification_class = 'error_notification'
config.error_notification_class = "error_notification"

# Series of attempts to detect a default label method for collection.
# config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
Expand Down Expand Up @@ -162,7 +162,7 @@
# config.input_class = nil

# Define the default class of the input wrapper of the boolean input.
config.boolean_label_class = 'checkbox'
config.boolean_label_class = "checkbox"

# Defines if the default input wrapper class should be included in radio
# collection wrappers.
Expand Down
Loading

0 comments on commit e6ac62d

Please sign in to comment.