PrajaktaC
PrajaktaC

Reputation: 51

How to check if postgres server is up through Rails App?

I am trying to create a health check page for my app. There are 3 different servers for back end, front end and database. I have created an API to check if services (sidekiq, redis) are running. Now, I want to check if postgres server is up or not. For this I have added a method

def database? ActiveRecord::Base.connection.active? end

This method returns true when postgres is running. If the Postgres server is stopped, and I try to hit my API I get

PG::ConnectionBad (could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432? ):

How to rescue this error?

Upvotes: 3

Views: 2408

Answers (2)

nattfodd
nattfodd

Reputation: 1890

To prevent rails guts to be loaded before you actually check the DB connection, I would suggest to create a simple rack middleware, and put in the very beginning of middlewares stack:

class StatusMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    return @app.call(env) unless status_request?(env)

    # Feel free to respond with JS here if needed
    if database_alive?
      [200, {}, []]
    else
      [503, {}, []]
    end
  end

  private

  def status_request?(env)
    # Change the route to whatever you like
    env['PATH_INFO'] == '/postgres_status' && env['REQUEST_METHOD'] == 'GET'
  end

  def database_alive?
    ::ActiveRecord::Base.connection.verify!
    true
  rescue StandardError
    false
  end
end

And in your config/application.rb:

config.middleware.insert_before 0, StatusMiddleware

Upvotes: 4

razvans
razvans

Reputation: 3251

I didn't do anything like it but here's how I'd do it.

Host a rails app (or sinatra, with no db or a dummy one) to status.myapp.com which is just a simple index page with a bunch of checks - db, redis, sidekiq. I'd make sure is hosted on the same machine as the production one.

  1. db - try to establish a connection to your production db - fails or not
  2. redis - try to see if it's a running process for redis-server
  3. sidekiq - try to see if it's a running process for sidekiq
  4. etc ...

Again, just an idea. Maybe someone did it differently.

Upvotes: 0

Related Questions