🐛 Fix issues on database logger

This commit is contained in:
Andrey Antukh 2023-01-05 13:21:45 +01:00
parent b235d3f0f2
commit 853be27780
5 changed files with 54 additions and 47 deletions

View file

@ -11,12 +11,12 @@
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cf] [app.config :as cf]
[app.db :as db] [app.db :as db]
[app.util.async :as aa] [app.loggers.zmq :as lzmq]
[app.worker :as wrk]
[clojure.core.async :as a] [clojure.core.async :as a]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[cuerdas.core :as str] [cuerdas.core :as str]
[integrant.core :as ig])) [integrant.core :as ig]
[promesa.exec :as px]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Error Listener ;; Error Listener
@ -27,7 +27,7 @@
(defonce enabled (atom true)) (defonce enabled (atom true))
(defn- persist-on-database! (defn- persist-on-database!
[{:keys [pool] :as cfg} {:keys [id] :as event}] [{:keys [::db/pool] :as cfg} {:keys [id] :as event}]
(when-not (db/read-only? pool) (when-not (db/read-only? pool)
(db/insert! pool :server-error-report {:id id :content (db/tjson event)}))) (db/insert! pool :server-error-report {:id id :content (db/tjson event)})))
@ -53,9 +53,8 @@
(assoc :version (:full cf/version)) (assoc :version (:full cf/version))
(update :id #(or % (uuid/next))))) (update :id #(or % (uuid/next)))))
(defn handle-event (defn- handle-event
[{:keys [executor] :as cfg} event] [cfg event]
(aa/with-thread executor
(try (try
(let [event (parse-event event) (let [event (parse-event event)
uri (cf/get :public-uri)] uri (cf/get :public-uri)]
@ -64,30 +63,39 @@
:uri (str uri "/dbg/error/" (:id event))) :uri (str uri "/dbg/error/" (:id event)))
(persist-on-database! cfg event)) (persist-on-database! cfg event))
(catch Exception cause (catch Throwable cause
(l/warn :hint "unexpected exception on database error logger" :cause cause))))) (l/warn :hint "unexpected exception on database error logger" :cause cause))))
(defmethod ig/pre-init-spec ::reporter [_] (defn- error-event?
(s/keys :req-un [::wrk/executor ::db/pool ::receiver]))
(defn error-event?
[event] [event]
(= "error" (:logger/level event))) (= "error" (:logger/level event)))
(defmethod ig/pre-init-spec ::reporter [_]
(s/keys :req [::db/pool ::lzmq/receiver]))
(defmethod ig/init-key ::reporter (defmethod ig/init-key ::reporter
[_ {:keys [receiver] :as cfg}] [_ {:keys [::lzmq/receiver] :as cfg}]
(l/info :msg "initializing database error persistence") (px/thread
(let [output (a/chan (a/sliding-buffer 5) (filter error-event?))] {:name "penpot/database-reporter"}
(receiver :sub output) (l/info :hint "initializing database error persistence")
(a/go-loop []
(let [msg (a/<! output)] (let [input (a/chan (a/sliding-buffer 5)
(if (nil? msg) (filter error-event?))]
(l/info :msg "stopping error reporting loop") (try
(do (lzmq/sub! receiver input)
(a/<! (handle-event cfg msg)) (loop []
(recur))))) (when-let [msg (a/<!! input)]
output)) (handle-event cfg msg))
(recur))
(catch InterruptedException _
(l/debug :hint "reporter interrupted"))
(catch Throwable cause
(l/error :hint "unexpected error" :cause cause))
(finally
(a/close! input)
(l/info :hint "reporter terminated"))))))
(defmethod ig/halt-key! ::reporter (defmethod ig/halt-key! ::reporter
[_ output] [_ thread]
(a/close! output)) (some-> thread px/interrupt!))

View file

@ -38,13 +38,13 @@
(defn handle-event (defn handle-event
[cfg event] [cfg event]
(when @enabled
(try (try
(let [event (ldb/parse-event event)] (let [event (ldb/parse-event event)]
(when @enabled (send-mattermost-notification! cfg event))
(send-mattermost-notification! cfg event)))
(catch Throwable cause (catch Throwable cause
(l/warn :hint "unhandled error" (l/warn :hint "unhandled error"
:cause cause)))) :cause cause)))))
(defmethod ig/pre-init-spec ::reporter [_] (defmethod ig/pre-init-spec ::reporter [_]
(s/keys :req [::http/client (s/keys :req [::http/client

View file

@ -450,9 +450,8 @@
::http.client/client (ig/ref ::http.client/client)} ::http.client/client (ig/ref ::http.client/client)}
:app.loggers.database/reporter :app.loggers.database/reporter
{:receiver (ig/ref :app.loggers.zmq/receiver) {::lzmq/receiver (ig/ref :app.loggers.zmq/receiver)
:pool (ig/ref ::db/pool) ::db/pool (ig/ref ::db/pool)}
:executor (ig/ref ::wrk/executor)}
::sto/storage ::sto/storage
{:pool (ig/ref ::db/pool) {:pool (ig/ref ::db/pool)

View file

@ -23,7 +23,7 @@
com.cognitect/transit-cljs {:mvn/version "0.8.280"} com.cognitect/transit-cljs {:mvn/version "0.8.280"}
java-http-clj/java-http-clj {:mvn/version "0.4.3"} java-http-clj/java-http-clj {:mvn/version "0.4.3"}
funcool/promesa {:mvn/version "10.0.571"} funcool/promesa {:mvn/version "10.0.594"}
funcool/cuerdas {:mvn/version "2022.06.16-403"} funcool/cuerdas {:mvn/version "2022.06.16-403"}
lambdaisland/uri {:mvn/version "1.13.95" lambdaisland/uri {:mvn/version "1.13.95"

View file

@ -89,9 +89,9 @@
(contains? data :explain)) (contains? data :explain))
(explain (:explain data) opts) (explain (:explain data) opts)
(and (::s/problems data) (and (contains? data ::s/problems)
(::s/value data) (contains? data ::s/value)
(::s/spec data)) (contains? data ::s/spec))
(binding [s/*explain-out* expound/printer] (binding [s/*explain-out* expound/printer]
(with-out-str (with-out-str
(s/explain-out (update data ::s/problems #(take max-problems %)))))))) (s/explain-out (update data ::s/problems #(take max-problems %))))))))