diff --git a/backend/src/app/http.clj b/backend/src/app/http.clj index 87448fefc..ab267e36b 100644 --- a/backend/src/app/http.clj +++ b/backend/src/app/http.clj @@ -16,6 +16,7 @@ [app.http.errors :as errors] [app.http.middleware :as middleware] [app.metrics :as mtx] + [app.util.log4j :refer [update-thread-context!]] [clojure.spec.alpha :as s] [clojure.tools.logging :as log] [integrant.core :as ig] @@ -103,7 +104,7 @@ (catch Throwable e (try (let [cdata (errors/get-error-context request e)] - (errors/update-thread-context! cdata) + (update-thread-context! cdata) (log/errorf e "Unhandled exception: %s (id: %s)" (ex-message e) (str (:id cdata))) {:status 500 :body "internal server error"}) diff --git a/backend/src/app/http/errors.clj b/backend/src/app/http/errors.clj index 17591da14..391962039 100644 --- a/backend/src/app/http/errors.clj +++ b/backend/src/app/http/errors.clj @@ -12,6 +12,7 @@ (:require [app.common.uuid :as uuid] [app.config :as cfg] + [app.util.log4j :refer [update-thread-context!]] [clojure.pprint :refer [pprint]] [clojure.tools.logging :as log] [cuerdas.core :as str] @@ -19,19 +20,6 @@ (:import org.apache.logging.log4j.ThreadContext)) -(defn update-thread-context! - [data] - (run! (fn [[key val]] - (ThreadContext/put - (name key) - (cond - (coll? val) - (binding [clojure.pprint/*print-right-margin* 120] - (with-out-str (pprint val))) - (instance? clojure.lang.Named val) (name val) - :else (str val)))) - data)) - (defn- explain-error [error] (with-out-str @@ -48,10 +36,8 @@ :version (:full cfg/version) :host (:public-uri cfg/config) :class (.getCanonicalName ^java.lang.Class (class error)) - :hint (ex-message error)} - - (when (map? edata) - edata) + :hint (ex-message error) + :data edata} (when (and (map? edata) (:data edata)) {:explain (explain-error edata)})))) diff --git a/backend/src/app/http/session.clj b/backend/src/app/http/session.clj index 98f3208ae..98ccb9ee0 100644 --- a/backend/src/app/http/session.clj +++ b/backend/src/app/http/session.clj @@ -10,7 +10,7 @@ (ns app.http.session (:require [app.db :as db] - [app.http.errors :refer [update-thread-context!]] + [app.util.log4j :refer [update-thread-context!]] [buddy.core.codecs :as bc] [buddy.core.nonce :as bn] [clojure.spec.alpha :as s] diff --git a/backend/src/app/util/log4j.clj b/backend/src/app/util/log4j.clj new file mode 100644 index 000000000..d46af289e --- /dev/null +++ b/backend/src/app/util/log4j.clj @@ -0,0 +1,28 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2021 UXBOX Labs SL + +(ns app.util.log4j + (:require + [clojure.pprint :refer [pprint]] + [clojure.tools.logging :as log]) + (:import + org.apache.logging.log4j.ThreadContext)) + +(defn update-thread-context! + [data] + (run! (fn [[key val]] + (ThreadContext/put + (name key) + (cond + (coll? val) + (binding [clojure.pprint/*print-right-margin* 120] + (with-out-str (pprint val))) + (instance? clojure.lang.Named val) (name val) + :else (str val)))) + data)) diff --git a/backend/src/app/worker.clj b/backend/src/app/worker.clj index 9e87a1ae9..d0ff046af 100644 --- a/backend/src/app/worker.clj +++ b/backend/src/app/worker.clj @@ -10,11 +10,13 @@ (ns app.worker "Async tasks abstraction (impl)." (:require + [app.config :as cfg] [app.common.spec :as us] [app.common.uuid :as uuid] [app.db :as db] [app.util.async :as aa] [app.util.time :as dt] + [app.util.log4j :refer [update-thread-context!]] [clojure.core.async :as a] [clojure.pprint :refer [pprint]] [clojure.spec.alpha :as s] @@ -205,6 +207,17 @@ (log/warn "no task handler found for" (pr-str name))) {:status :completed :task item})) +(defn get-error-context + [error item] + (let [edata (ex-data error)] + {:id (uuid/next) + :version (:full cfg/version) + :host (:public-uri cfg/config) + :class (.getCanonicalName ^java.lang.Class (class error)) + :hint (ex-message error) + :data edata + :params item})) + (defn- handle-exception [error item] (let [edata (ex-data error)] @@ -218,14 +231,9 @@ (= ::noop (:strategy edata)) (assoc :inc-by 0)) - (do - (log/errorf error - (str "Unhandled exception.\n" - "=> task: " (:name item) "\n" - "=> retry: " (:retry-num item) "\n" - "=> props: \n" - (with-out-str - (pprint (:props item))))) + (let [cdata (get-error-context error item)] + (update-thread-context! cdata) + (log/errorf error "Unhandled exception on task (id: %s)" (:id cdata)) (if (>= (:retry-num item) (:max-retries item)) {:status :failed :task item :error error} {:status :retry :task item :error error})))))