Reputation: 51
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
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
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.
db
- try to establish a connection to your production db - fails or notredis
- try to see if it's a running process for redis-server
sidekiq
- try to see if it's a running process for sidekiq
etc ...
Again, just an idea. Maybe someone did it differently.
Upvotes: 0