From 0064e01c19bdc989622027ec1c4ab2e8c9cb513d Mon Sep 17 00:00:00 2001 From: dpsutton <dan@dpsutton.com> Date: Wed, 11 May 2022 10:47:26 -0500 Subject: [PATCH] Verify active database for `GET api/health` (#22606) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Verify active database for `GET api/health` Previously unconditionally responded with 200, status "ok" if we were done initializing, even when we had 1500 stale db connections somehow (:scream:). Now attempt to connect to the database: ```shell ⯠http get localhost:3000/api/health -pb { "status": "ok" } ⯠http get localhost:3000/api/health HTTP/1.1 503 Service Unavailable ... { "status": "Error getting db connection" } ``` and logging to the server ``` 2022-05-10 22:05:16,911 WARN server.routes :: Error in api/health database check java.lang.ArithmeticException: Divide by zero at clojure.lang.Numbers.divide(Numbers.java:190) at clojure.lang.Numbers.divide(Numbers.java:3911) at metabase.server.routes$fn__122320.invokeStatic(routes.clj:51) ``` * Reuse `sql-jdbc.conn/can-connect-with-spec?` for api/health --- src/metabase/server/routes.clj | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/metabase/server/routes.clj b/src/metabase/server/routes.clj index 6f57f892ee3..8e8dce24446 100644 --- a/src/metabase/server/routes.clj +++ b/src/metabase/server/routes.clj @@ -1,15 +1,19 @@ (ns metabase.server.routes "Main Compojure routes tables. See https://github.com/weavejester/compojure/wiki/Routes-In-Detail for details about how these work. `/api/` routes are in `metabase.api.routes`." - (:require [compojure.core :refer [context defroutes GET]] + (:require [clojure.tools.logging :as log] + [compojure.core :refer [context defroutes GET]] [compojure.route :as route] [metabase.api.dataset :as api.dataset] [metabase.api.routes :as api] [metabase.core.initialization-status :as init-status] + [metabase.db.connection :as mdb.connection] + [metabase.driver.sql-jdbc.connection :as sql-jdbc.conn] [metabase.plugins.classloader :as classloader] [metabase.public-settings :as public-settings] [metabase.server.routes.index :as index] [metabase.util :as u] + [metabase.util.i18n :refer [trs]] [ring.util.response :as response])) (u/ignore-exceptions (classloader/require '[metabase-enterprise.sso.api.routes :as ee.sso.routes])) @@ -43,9 +47,15 @@ (GET "/" [] index/index) (GET "/favicon.ico" [] (response/resource-response (public-settings/application-favicon-url))) ;; ^/api/health -> Health Check Endpoint - (GET "/api/health" [] (if (init-status/complete?) - {:status 200, :body {:status "ok"}} - {:status 503, :body {:status "initializing", :progress (init-status/progress)}})) + (GET "/api/health" [] + (if (init-status/complete?) + (try (if (sql-jdbc.conn/can-connect-with-spec? {:datasource (mdb.connection/data-source)}) + {:status 200, :body {:status "ok"}} + {:status 503 :body {:status "Unable to get app-db connection"}}) + (catch Exception e + (log/warn e (trs "Error in api/health database check")) + {:status 503 :body {:status "Error getting app-db connection"}})) + {:status 503, :body {:status "initializing", :progress (init-status/progress)}})) ;; ^/api/ -> All other API routes (context "/api" [] (fn [& args] ;; Redirect naughty users who try to visit a page other than setup if setup is not yet complete -- GitLab