mirror of
https://github.com/penpot/penpot.git
synced 2025-03-28 15:41:25 -05:00
🎉 Add prometheus metrics.
This commit is contained in:
parent
ccb79f7188
commit
b532e74310
20 changed files with 359 additions and 82 deletions
|
@ -9,11 +9,15 @@
|
|||
|
||||
;; Logging
|
||||
org.clojure/tools.logging {:mvn/version "1.1.0"}
|
||||
org.apache.logging.log4j/log4j-api {:mvn/version "2.13.2"}
|
||||
org.apache.logging.log4j/log4j-core {:mvn/version "2.13.2"}
|
||||
org.apache.logging.log4j/log4j-web {:mvn/version "2.13.2"}
|
||||
org.apache.logging.log4j/log4j-jul {:mvn/version "2.13.2"}
|
||||
org.apache.logging.log4j/log4j-slf4j-impl {:mvn/version "2.13.2"}
|
||||
org.apache.logging.log4j/log4j-api {:mvn/version "2.13.3"}
|
||||
org.apache.logging.log4j/log4j-core {:mvn/version "2.13.3"}
|
||||
org.apache.logging.log4j/log4j-web {:mvn/version "2.13.3"}
|
||||
org.apache.logging.log4j/log4j-jul {:mvn/version "2.13.3"}
|
||||
org.apache.logging.log4j/log4j-slf4j-impl {:mvn/version "2.13.3"}
|
||||
|
||||
io.prometheus/simpleclient {:mvn/version "0.9.0"}
|
||||
io.prometheus/simpleclient_hotspot {:mvn/version "0.9.0"}
|
||||
io.prometheus/simpleclient_httpserver {:mvn/version "0.9.0"}
|
||||
|
||||
expound/expound {:mvn/version "0.8.4"}
|
||||
instaparse/instaparse {:mvn/version "1.4.10"}
|
||||
|
@ -26,7 +30,7 @@
|
|||
seancorfield/next.jdbc {:mvn/version "1.0.424"}
|
||||
metosin/reitit-ring {:mvn/version "0.4.2"}
|
||||
org.postgresql/postgresql {:mvn/version "42.2.12"}
|
||||
com.zaxxer/HikariCP {:mvn/version "3.4.3"}
|
||||
com.zaxxer/HikariCP {:mvn/version "3.4.5"}
|
||||
|
||||
funcool/datoteka {:mvn/version "1.2.0"}
|
||||
funcool/promesa {:mvn/version "5.1.0"}
|
||||
|
@ -51,7 +55,7 @@
|
|||
io.aviso/pretty {:mvn/version "0.1.37"}
|
||||
|
||||
mount/mount {:mvn/version "0.1.16"}
|
||||
environ/environ {:mvn/version "1.1.0"}}
|
||||
environ/environ {:mvn/version "1.2.0"}}
|
||||
:paths ["src" "resources" "../common" "common"]
|
||||
:aliases
|
||||
{:dev
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="info" monitorInterval="60">
|
||||
<Appenders>
|
||||
<Console name="console" target="SYSTEM_OUT">
|
||||
|
|
|
@ -17,11 +17,13 @@
|
|||
[next.jdbc.result-set :as jdbc-rs]
|
||||
[next.jdbc.sql :as jdbc-sql]
|
||||
[next.jdbc.sql.builder :as jdbc-bld]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.config :as cfg]
|
||||
[uxbox.util.data :as data])
|
||||
(:import
|
||||
org.postgresql.util.PGobject
|
||||
com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory
|
||||
com.zaxxer.hikari.HikariConfig
|
||||
com.zaxxer.hikari.HikariDataSource))
|
||||
|
||||
|
@ -30,17 +32,20 @@
|
|||
(let [dburi (:database-uri cfg)
|
||||
username (:database-username cfg)
|
||||
password (:database-password cfg)
|
||||
config (HikariConfig.)]
|
||||
config (HikariConfig.)
|
||||
mfactory (PrometheusMetricsTrackerFactory. mtx/registry)]
|
||||
(doto config
|
||||
(.setJdbcUrl (str "jdbc:" dburi))
|
||||
(.setPoolName "main")
|
||||
(.setAutoCommit true)
|
||||
(.setReadOnly false)
|
||||
(.setConnectionTimeout 30000)
|
||||
(.setValidationTimeout 5000)
|
||||
(.setIdleTimeout 600000)
|
||||
(.setMaxLifetime 1800000)
|
||||
(.setMinimumIdle 10)
|
||||
(.setMaximumPoolSize 20))
|
||||
(.setConnectionTimeout 30000) ;; 30seg
|
||||
(.setValidationTimeout 5000) ;; 5seg
|
||||
(.setIdleTimeout 900000) ;; 15min
|
||||
(.setMaxLifetime 900000) ;; 15min
|
||||
(.setMinimumIdle 5)
|
||||
(.setMaximumPoolSize 10)
|
||||
(.setMetricsTrackerFactory mfactory))
|
||||
(when username (.setUsername config username))
|
||||
(when password (.setPassword config password))
|
||||
config))
|
||||
|
@ -127,3 +132,11 @@
|
|||
(= typ "jsonb"))
|
||||
(json/read-str val)
|
||||
val)))
|
||||
|
||||
;; Instrumentation
|
||||
|
||||
(mtx/instrument-with-counter!
|
||||
{:var [#'jdbc/execute-one!
|
||||
#'jdbc/execute!]
|
||||
:id "database__query_counter"
|
||||
:help "An absolute counter of database queries."})
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
[uxbox.http.middleware :as middleware]
|
||||
[uxbox.http.session :as session]
|
||||
[uxbox.http.ws :as ws]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.services.notifications :as usn]))
|
||||
|
||||
(defn- create-router
|
||||
[]
|
||||
(rring/router
|
||||
[["/api" {:middleware [[middleware/format-response-body]
|
||||
[["/metrics" {:get mtx/dump}]
|
||||
["/api" {:middleware [[middleware/format-response-body]
|
||||
[middleware/errors errors/handle]
|
||||
[middleware/parse-request-body]
|
||||
[middleware/params]
|
||||
|
@ -37,7 +39,6 @@
|
|||
["/logout" {:handler handlers/logout-handler
|
||||
:method :post}]
|
||||
|
||||
|
||||
["/w" {:middleware [session/auth]}
|
||||
["/query/:type" {:get handlers/query-handler}]
|
||||
["/mutation/:type" {:post handlers/mutation-handler}]]]]))
|
||||
|
@ -46,8 +47,9 @@
|
|||
:start (rring/ring-handler
|
||||
(create-router)
|
||||
(constantly {:status 404, :body ""})
|
||||
{:middleware [middleware/development-resources
|
||||
middleware/development-cors]}))
|
||||
{:middleware [[middleware/development-resources]
|
||||
[middleware/development-cors]
|
||||
[middleware/metrics]]}))
|
||||
|
||||
(defn start-server
|
||||
[cfg app]
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
[clojure.tools.logging :as log]
|
||||
[cuerdas.core :as str]
|
||||
[uxbox.metrics :as mtx]
|
||||
[io.aviso.exception :as e]))
|
||||
|
||||
(defmulti handle-exception
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[ring.middleware.multipart-params :refer [wrap-multipart-params]]
|
||||
[ring.middleware.params :refer [wrap-params]]
|
||||
[ring.middleware.resource :refer [wrap-resource]]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.config :as cfg]
|
||||
[uxbox.util.transit :as t]))
|
||||
|
@ -83,6 +84,12 @@
|
|||
{:name ::errors
|
||||
:compile (constantly wrap-errors)})
|
||||
|
||||
(def metrics
|
||||
{:name ::metrics
|
||||
:wrap (fn [handler]
|
||||
(mtx/wrap-counter handler {:id "http__requests_counter"
|
||||
:help "Absolute http requests counter."}))})
|
||||
|
||||
(def cookies
|
||||
{:name ::cookies
|
||||
:compile (constantly wrap-cookies)})
|
||||
|
|
181
backend/src/uxbox/metrics.clj
Normal file
181
backend/src/uxbox/metrics.clj
Normal file
|
@ -0,0 +1,181 @@
|
|||
;; 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) 2020 UXBOX Labs SL
|
||||
|
||||
(ns uxbox.metrics
|
||||
(:require
|
||||
[clojure.tools.logging :as log]
|
||||
[cuerdas.core :as str])
|
||||
(:import
|
||||
io.prometheus.client.CollectorRegistry
|
||||
io.prometheus.client.Counter
|
||||
io.prometheus.client.Gauge
|
||||
io.prometheus.client.Summary
|
||||
io.prometheus.client.exporter.common.TextFormat
|
||||
io.prometheus.client.hotspot.DefaultExports
|
||||
java.io.StringWriter))
|
||||
|
||||
(defn- create-registry
|
||||
[]
|
||||
(let [registry (CollectorRegistry.)]
|
||||
(DefaultExports/register registry)
|
||||
registry))
|
||||
|
||||
(defonce registry (create-registry))
|
||||
(defonce cache (atom {}))
|
||||
|
||||
(defmacro with-measure
|
||||
[sym expr teardown]
|
||||
`(let [~sym (System/nanoTime)]
|
||||
(try
|
||||
~expr
|
||||
(finally
|
||||
(let [~sym (/ (- (System/nanoTime) ~sym) 1000000)]
|
||||
~teardown)))))
|
||||
|
||||
(defn make-counter
|
||||
[{:keys [id help] :as props}]
|
||||
(let [instance (doto (Counter/build)
|
||||
(.name id)
|
||||
(.help help))
|
||||
instance (.register instance registry)]
|
||||
(reify
|
||||
clojure.lang.IDeref
|
||||
(deref [_] instance)
|
||||
|
||||
clojure.lang.IFn
|
||||
(invoke [_ cmd]
|
||||
(.inc ^Counter instance))
|
||||
|
||||
(invoke [_ cmd val]
|
||||
(case cmd
|
||||
:wrap (fn
|
||||
([a]
|
||||
(.inc ^Counter instance)
|
||||
(val a))
|
||||
([a b]
|
||||
(.inc ^Counter instance)
|
||||
(val a b))
|
||||
([a b c]
|
||||
(.inc ^Counter instance)
|
||||
(val a b c)))
|
||||
|
||||
(throw (IllegalArgumentException. "invalid arguments")))))))
|
||||
|
||||
(defn counter
|
||||
[{:keys [id] :as props}]
|
||||
(or (get @cache id)
|
||||
(let [v (make-counter props)]
|
||||
(swap! cache assoc id v)
|
||||
v)))
|
||||
|
||||
(defn make-gauge
|
||||
[{:keys [id help] :as props}]
|
||||
(let [instance (doto (Gauge/build)
|
||||
(.name id)
|
||||
(.help help))
|
||||
instance (.register instance registry)]
|
||||
(reify
|
||||
clojure.lang.IDeref
|
||||
(deref [_] instance)
|
||||
|
||||
clojure.lang.IFn
|
||||
(invoke [_ cmd]
|
||||
(case cmd
|
||||
:inc (.inc ^Gauge instance)
|
||||
:dec (.dec ^Gauge instance))))))
|
||||
|
||||
(defn gauge
|
||||
[{:keys [id] :as props}]
|
||||
(or (get @cache id)
|
||||
(let [v (make-gauge props)]
|
||||
(swap! cache assoc id v)
|
||||
v)))
|
||||
|
||||
(defn make-summary
|
||||
[{:keys [id help] :as props}]
|
||||
(let [instance (doto (Summary/build)
|
||||
(.name id)
|
||||
(.help help)
|
||||
(.quantile 0.5 0.05)
|
||||
(.quantile 0.9 0.01)
|
||||
(.quantile 0.99 0.001))
|
||||
instance (.register instance registry)]
|
||||
(reify
|
||||
clojure.lang.IDeref
|
||||
(deref [_] instance)
|
||||
|
||||
clojure.lang.IFn
|
||||
(invoke [_ val]
|
||||
(.observe ^Summary instance val))
|
||||
|
||||
(invoke [_ cmd val]
|
||||
(case cmd
|
||||
:wrap (fn
|
||||
([a]
|
||||
(with-measure $$
|
||||
(val a)
|
||||
(.observe ^Summary instance $$)))
|
||||
([a b]
|
||||
(with-measure $$
|
||||
(val a b)
|
||||
(.observe ^Summary instance $$)))
|
||||
([a b c]
|
||||
(with-measure $$
|
||||
(val a b c)
|
||||
(.observe ^Summary instance $$))))
|
||||
|
||||
(throw (IllegalArgumentException. "invalid arguments")))))))
|
||||
|
||||
(defn summary
|
||||
[{:keys [id] :as props}]
|
||||
(or (get @cache id)
|
||||
(let [v (make-summary props)]
|
||||
(swap! cache assoc id v)
|
||||
v)))
|
||||
|
||||
(defn wrap-summary
|
||||
[f props]
|
||||
(let [sm (summary props)]
|
||||
(sm :wrap f)))
|
||||
|
||||
(defn wrap-counter
|
||||
[f props]
|
||||
(let [cnt (counter props)]
|
||||
(cnt :wrap f)))
|
||||
|
||||
(defn instrument-with-counter!
|
||||
[{:keys [var] :as props}]
|
||||
(let [cnt (counter props)
|
||||
vars (if (var? var) [var] var)]
|
||||
(doseq [var vars]
|
||||
(alter-var-root var (fn [root]
|
||||
(let [mdata (meta root)
|
||||
original (::counter-original mdata root)]
|
||||
(with-meta
|
||||
(cnt :wrap original)
|
||||
(assoc mdata ::counter-original original))))))))
|
||||
|
||||
(defn instrument-with-summary!
|
||||
[{:keys [var] :as props}]
|
||||
(let [sm (summary props)]
|
||||
(alter-var-root var (fn [root]
|
||||
(let [mdata (meta root)
|
||||
original (::summary-original mdata root)]
|
||||
(with-meta
|
||||
(sm :wrap original)
|
||||
(assoc mdata ::summary-original original)))))))
|
||||
|
||||
(defn dump
|
||||
[& args]
|
||||
(let [samples (.metricFamilySamples ^CollectorRegistry registry)
|
||||
writer (StringWriter.)]
|
||||
(TextFormat/write004 writer samples)
|
||||
{:headers {"content-type" TextFormat/CONTENT_TYPE_004}
|
||||
:body (.toString writer)}))
|
||||
|
73
backend/src/uxbox/services/middleware.clj
Normal file
73
backend/src/uxbox/services/middleware.clj
Normal file
|
@ -0,0 +1,73 @@
|
|||
;; 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) 2020 UXBOX Labs SL
|
||||
|
||||
(ns uxbox.services.middleware
|
||||
"Common middleware for services."
|
||||
(:require
|
||||
[clojure.tools.logging :as log]
|
||||
[clojure.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[expound.alpha :as expound]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.metrics :as mtx]))
|
||||
|
||||
(defn wrap-spec
|
||||
[handler]
|
||||
(let [mdata (meta handler)
|
||||
spec (s/get-spec (:spec mdata))]
|
||||
(if (nil? spec)
|
||||
handler
|
||||
(with-meta
|
||||
(fn [params]
|
||||
(let [result (us/conform spec params)]
|
||||
(handler result)))
|
||||
(assoc mdata ::wrap-spec true)))))
|
||||
|
||||
(defn wrap-error
|
||||
[handler]
|
||||
(let [mdata (meta handler)]
|
||||
(with-meta
|
||||
(fn [params]
|
||||
(try
|
||||
(handler params)
|
||||
(catch Throwable error
|
||||
(ex/raise :type :service-error
|
||||
:name (:spec mdata)
|
||||
:cause error))))
|
||||
(assoc mdata ::wrap-error true))))
|
||||
|
||||
(defn- get-prefix
|
||||
[nsname]
|
||||
(let [[a b c] (str/split nsname ".")]
|
||||
c))
|
||||
|
||||
(defn wrap-metrics
|
||||
[handler]
|
||||
(let [mdata (meta handler)
|
||||
nsname (namespace (:spec mdata))
|
||||
smname (name (:spec mdata))
|
||||
prefix (get-prefix nsname)
|
||||
|
||||
sname (str prefix "/" smname)
|
||||
|
||||
props {:id (str/join "__" [prefix
|
||||
(str/snake smname)
|
||||
"response_time"])
|
||||
:help (str "Service timing measures for: " sname ".")}]
|
||||
(with-meta
|
||||
(mtx/wrap-summary handler props)
|
||||
(assoc mdata ::wrap-metrics true))))
|
||||
|
||||
(defn wrap
|
||||
[handler]
|
||||
(-> handler
|
||||
(wrap-spec)
|
||||
(wrap-error)
|
||||
(wrap-metrics)))
|
|
@ -5,16 +5,16 @@
|
|||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2019-2020 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns uxbox.services.mutations
|
||||
(:require
|
||||
[uxbox.services.middleware :as middleware]
|
||||
[uxbox.util.dispatcher :as uds]))
|
||||
|
||||
(uds/defservice handle
|
||||
:dispatch-by ::type
|
||||
:wrap [uds/wrap-spec
|
||||
uds/wrap-error])
|
||||
:wrap middleware/wrap)
|
||||
|
||||
(defmacro defmutation
|
||||
[key & rest]
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
[ring.adapter.jetty9 :as jetty]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.common.uuid :as uuid]
|
||||
[uxbox.redis :as redis]
|
||||
[uxbox.db :as db]
|
||||
[uxbox.redis :as redis]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.util.time :as dt]
|
||||
[uxbox.util.transit :as t]))
|
||||
|
||||
|
@ -193,11 +194,20 @@
|
|||
(jetty/send! conn (t/encode-str val))
|
||||
(recur)))))
|
||||
|
||||
(defonce metrics-active-connections
|
||||
(mtx/gauge {:id "notificatons__active_connections"
|
||||
:help "Active connections to the notifications service."}))
|
||||
|
||||
(defonce metrics-message-counter
|
||||
(mtx/counter {:id "notificatons__messages_counter"
|
||||
:help "A total number of messages handled by the notifications service."}))
|
||||
|
||||
(defn websocket
|
||||
[{:keys [file-id] :as params}]
|
||||
(let [in (a/chan 32)
|
||||
out (a/chan 32)]
|
||||
{:on-connect (fn [conn]
|
||||
(metrics-active-connections :inc)
|
||||
(let [xf (map t/decode-str)
|
||||
sub (redis/subscribe (str file-id) xf)
|
||||
ws (WebSocket. conn in out sub nil params)]
|
||||
|
@ -207,21 +217,19 @@
|
|||
(a/close! sub))))
|
||||
|
||||
:on-error (fn [conn e]
|
||||
;; (prn "websocket" :on-error e)
|
||||
(a/close! out)
|
||||
(a/close! in))
|
||||
|
||||
:on-close (fn [conn status-code reason]
|
||||
;; (prn "websocket" :on-close status-code reason)
|
||||
(metrics-active-connections :dec)
|
||||
(a/close! out)
|
||||
(a/close! in))
|
||||
|
||||
:on-text (fn [ws message]
|
||||
(metrics-message-counter :inc)
|
||||
(let [message (t/decode-str message)]
|
||||
;; (prn "websocket" :on-text message)
|
||||
(a/>!! in message)))
|
||||
|
||||
:on-bytes (fn [ws bytes offset len]
|
||||
#_(prn "websocket" :on-bytes bytes))}))
|
||||
:on-bytes (constantly nil)}))
|
||||
|
||||
|
||||
|
|
|
@ -2,16 +2,19 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; Copyright (c) 2019 Andrey Antukh <niwi@niwi.nz>
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns uxbox.services.queries
|
||||
(:require
|
||||
[uxbox.services.middleware :as middleware]
|
||||
[uxbox.util.dispatcher :as uds]))
|
||||
|
||||
(uds/defservice handle
|
||||
:dispatch-by ::type
|
||||
:wrap [uds/wrap-spec
|
||||
uds/wrap-error])
|
||||
:wrap middleware/wrap)
|
||||
|
||||
(defmacro defquery
|
||||
[key & rest]
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
(ns uxbox.services.queries.icons
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[promesa.exec :as px]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.common.uuid :as uuid]
|
||||
|
|
|
@ -10,13 +10,12 @@
|
|||
(ns uxbox.services.queries.images
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[promesa.core :as p]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.db :as db]
|
||||
[uxbox.images :as images]
|
||||
[uxbox.services.queries.teams :as teams]
|
||||
[uxbox.services.queries :as sq]))
|
||||
[uxbox.services.queries :as sq]
|
||||
[uxbox.services.queries.teams :as teams]))
|
||||
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::name ::us/string)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[uxbox.common.spec :as us]
|
||||
[uxbox.config :as cfg]
|
||||
[uxbox.db :as db]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.tasks.sendmail]
|
||||
[uxbox.tasks.gc]
|
||||
[uxbox.tasks.remove-media]
|
||||
|
@ -68,3 +69,8 @@
|
|||
([conn opts]
|
||||
(s/assert ::impl/task-options opts)
|
||||
(impl/submit! conn opts)))
|
||||
|
||||
(mtx/instrument-with-counter!
|
||||
{:var #'submit!
|
||||
:id "tasks__submit_counter"
|
||||
:help "Absolute task submit counter."})
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.db :as db]
|
||||
[uxbox.media :as media]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.util.storage :as ust]))
|
||||
|
||||
(s/def ::type keyword?)
|
||||
|
@ -36,6 +36,11 @@
|
|||
(db/with-atomic [conn db/pool]
|
||||
(handle-deletion conn props)))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__delete_object"
|
||||
:help "Timing of remove-object task."})
|
||||
|
||||
(defmethod handle-deletion :image
|
||||
[conn {:keys [id] :as props}]
|
||||
(let [sql "delete from image where id=? and deleted_at is not null"]
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.db :as db]
|
||||
[uxbox.media :as media]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.util.storage :as ust]))
|
||||
|
||||
(declare delete-profile-data)
|
||||
|
@ -39,6 +39,11 @@
|
|||
(log/warn "Profile " (:id profile)
|
||||
"does not match constraints for deletion")))))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__delete_profile"
|
||||
:help "Timing of delete-profile task."})
|
||||
|
||||
(defn- delete-profile-data
|
||||
[conn profile-id]
|
||||
(log/info "Proceding to delete all data related to profile" profile-id)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.media :as media]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.util.storage :as ust]))
|
||||
|
||||
(s/def ::path ::us/not-empty-string)
|
||||
|
@ -28,3 +29,7 @@
|
|||
(ust/delete! media/media-storage (:path props))
|
||||
(log/debug "Media " (:path props) " removed.")))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__remove_media"
|
||||
:help "Timing of remove-media task."})
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[uxbox.common.data :as d]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.config :as cfg]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.util.http :as http]))
|
||||
|
||||
(defmulti sendmail (fn [config email] (:sendmail-backend config)))
|
||||
|
@ -94,3 +95,7 @@
|
|||
[{:keys [props] :as task}]
|
||||
(sendmail cfg/config props))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__sendmail"
|
||||
:help "Timing of sendmail task."})
|
||||
|
|
|
@ -20,22 +20,18 @@
|
|||
(definterface IDispatcher
|
||||
(^void add [key f]))
|
||||
|
||||
(defn- wrap-handler
|
||||
[items handler]
|
||||
(reduce #(%2 %1) handler items))
|
||||
|
||||
(deftype Dispatcher [reg attr wrap-fns]
|
||||
(deftype Dispatcher [reg attr wrap]
|
||||
IDispatcher
|
||||
(add [this key f]
|
||||
(let [f (wrap-handler wrap-fns f)]
|
||||
(.put ^Map reg key f)
|
||||
this))
|
||||
(.put ^Map reg key (wrap f))
|
||||
this)
|
||||
|
||||
|
||||
clojure.lang.IDeref
|
||||
(deref [_]
|
||||
{:registry reg
|
||||
:attr attr
|
||||
:wrap-fns wrap-fns})
|
||||
:wrap wrap})
|
||||
|
||||
clojure.lang.IFn
|
||||
(invoke [_ params]
|
||||
|
@ -100,36 +96,3 @@
|
|||
`(do
|
||||
(s/assert dispatcher? ~sym)
|
||||
(add-method ~sym ~key ~f ~meta))))
|
||||
|
||||
(defn wrap-spec
|
||||
[handler]
|
||||
(let [mdata (meta handler)
|
||||
spec (s/get-spec (:spec mdata))]
|
||||
(if (nil? spec)
|
||||
handler
|
||||
(with-meta
|
||||
(fn [params]
|
||||
(let [result (s/conform spec params)]
|
||||
(if (not= result ::s/invalid)
|
||||
(handler result)
|
||||
(let [data (s/explain-data spec params)]
|
||||
(ex/raise :type :validation
|
||||
:code :spec-validation
|
||||
:explain (with-out-str
|
||||
(expound/printer data))
|
||||
:data (::s/problems data))))))
|
||||
(assoc mdata ::wrap-spec true)))))
|
||||
|
||||
(defn wrap-error
|
||||
[handler]
|
||||
(let [mdata (meta handler)]
|
||||
(with-meta
|
||||
(fn [params]
|
||||
(try
|
||||
(handler params)
|
||||
(catch Throwable error
|
||||
(ex/raise :type :service-error
|
||||
:name (:spec mdata)
|
||||
:cause error))))
|
||||
(assoc mdata ::wrap-error true))))
|
||||
|
||||
|
|
|
@ -19,11 +19,9 @@
|
|||
[clojure.repl :refer :all]
|
||||
[criterium.core :refer [quick-bench bench with-progress-reporting]]
|
||||
[clj-kondo.core :as kondo]
|
||||
[promesa.core :as p]
|
||||
[promesa.exec :as px]
|
||||
[uxbox.migrations]
|
||||
[uxbox.db :as db]
|
||||
;; [uxbox.redis :as rd]
|
||||
[uxbox.metrics :as mtx]
|
||||
[uxbox.util.storage :as st]
|
||||
[uxbox.util.time :as tm]
|
||||
[uxbox.util.blob :as blob]
|
||||
|
|
Loading…
Add table
Reference in a new issue