This commit is contained in:
Andrey Antukh
2025-12-15 08:05:05 +01:00
parent 94f95ca6b8
commit 0da3e5b479

View File

@@ -19,59 +19,62 @@
(defonce enabled (atom true)) (defonce enabled (atom true))
(defn- send-mattermost-notification! (defn- send-mattermost-notification
[cfg {:keys [id public-uri] :as report}] [cfg text]
(let [resp (http/req! cfg
(let [text (str "Exception: " public-uri "/dbg/error/" id " "
(when-let [pid (:profile-id report)]
(str "(pid: #uuid-" pid ")"))
"\n"
"- host: #" (:host report) "\n"
"- tenant: #" (:tenant report) "\n"
"- logger: #" (:logger report) "\n"
"- request-path: `" (:request-path report) "`\n"
"- frontend-version: `" (:frontend-version report) "`\n"
"- backend-version: `" (:backend-version report) "`\n"
"\n"
"```\n"
"Trace:\n"
(:trace report)
"```")
resp (http/req! cfg
{:uri (cf/get :error-report-webhook) {:uri (cf/get :error-report-webhook)
:method :post :method :post
:headers {"content-type" "application/json"} :headers {"content-type" "application/json"}
:body (json/encode-str {:text text})} :body (json/encode-str {:text text})})]
{:sync? true})]
(when (not= 200 (:status resp)) (when (not= 200 (:status resp))
(l/warn :hint "error on sending data" (l/warn :hint "error on sending data to mattermost"
:response (pr-str resp))))) :response (pr-str resp)))))
(defn record->report (defn- log-record->report
[{:keys [::l/context ::l/id ::l/cause] :as record}] [{:keys [::l/context ::l/id ::l/cause] :as record}]
(assert (l/valid-record? record) "expectd valid log record") (assert (l/valid-record? record) "expectd valid log record")
{:id id (let [tenant (cf/get :tenant)
:tenant (cf/get :tenant) host (cf/get :host)
:host (cf/get :host) public-uri (cf/get :public-uri)
:public-uri (cf/get :public-uri) backend-version (or (:version/backend context) (:full cf/version))
:backend-version (or (:version/backend context) (:full cf/version)) frontend-version (:version/frontend context)
:frontend-version (:version/frontend context) profile-id (:request/profile-id context)
:profile-id (:request/profile-id context) request-path (:request/path context)
:request-path (:request/path context) logger (::l/logger record)
:logger (::l/logger record) trace (ex/format-throwable cause :detail? false :header? false)]
:trace (ex/format-throwable cause :detail? false :header? false)})
(defn handle-event (str "#exception => " public-uri "/dbg/error/" id " "
(when-let [pid (:profile-id report)]
(str "(pid: #uuid-" pid ")"))
"\n"
"- host: #" (:host report) "\n"
"- tenant: #" (:tenant report) "\n"
"- logger: #" (:logger report) "\n"
"- request-path: `" (:request-path report) "`\n"
"- frontend-version: `" (:frontend-version report) "`\n"
"- backend-version: `" (:backend-version report) "`\n"
"\n"
"```\n"
"Trace:\n"
(:trace report)
"```")))
(defn- process-log-record
[cfg record] [cfg record]
(when @enabled (when (ldb/error-record? record)
(try (try
(let [report (record->report record)] (let [report (record->report record)]
(send-mattermost-notification! cfg report)) (send-mattermost-notification! cfg report))
(catch Throwable cause (catch Throwable cause
(l/warn :hint "unhandled error" :cause cause))))) (l/warn :hint "error on processing log record" :cause cause)))))
(defn- process-event
[cfg [type event]]
(when @enabled
(case type
:log-record (process-log-record cfg event))))
;; :xf (filter ldb/error-record?))]
(defmethod ig/assert-key ::reporter (defmethod ig/assert-key ::reporter
[_ params] [_ params]
@@ -80,26 +83,28 @@
(defmethod ig/init-key ::reporter (defmethod ig/init-key ::reporter
[_ cfg] [_ cfg]
(when-let [uri (cf/get :error-report-webhook)] (when-let [uri (cf/get :error-report-webhook)]
(px/thread (let [input (sp/chan :buf (sp/sliding-buffer 128)
{:name "penpot/mattermost-reporter" :xf (keep process-event))
:virtual true} thread (px/thread
(l/info :hint "initializing error reporter" :uri uri) {:name "penpot/mattermost-reporter"}
(let [input (sp/chan :buf (sp/sliding-buffer 128) (l/info :hint "initializing mattermost reporter thread" :uri uri)
:xf (filter ldb/error-record?))] (try
(add-watch l/log-record ::reporter #(sp/put! input %4)) (loop []
(try (when-let [msg (sp/take! input)]
(loop [] (handle-event cfg msg)
(when-let [msg (sp/take! input)] (recur)))
(handle-event cfg msg) (catch InterruptedException _
(recur))) (l/debug :hint "mattermost reporter interrupted"))
(catch InterruptedException _ (catch Throwable cause
(l/debug :hint "reporter interrupted")) (l/error :hint "unexpected error on mattermost reporter" :cause cause))
(catch Throwable cause (finally
(l/error :hint "unexpected error" :cause cause)) (sp/close! input)
(finally (remove-watch l/log-record ::reporter)
(sp/close! input) (l/info :hint "mattermost reporter terminated"))))]
(remove-watch l/log-record ::reporter)
(l/info :hint "reporter terminated"))))))) (add-watch l/log-record ::reporter #(sp/put! input [:log-record %4]))
input)))
(defmethod ig/halt-key! ::reporter (defmethod ig/halt-key! ::reporter
[_ thread] [_ thread]