0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-11 23:31:21 -05:00

♻️ Refactor metrics namespace

This commit is contained in:
Andrey Antukh 2022-08-30 19:32:35 +02:00
parent ec3651d85b
commit fd973d87fd
4 changed files with 185 additions and 145 deletions

View file

@ -150,7 +150,7 @@
;; When metrics namespace is provided
(when metrics
(->> (:registry metrics)
(->> (::mtx/registry metrics)
(PrometheusMetricsTrackerFactory.)
(.setMetricsTrackerFactory config)))

View file

@ -151,7 +151,7 @@
[middleware/errors errors/handle]
[middleware/restrict-methods]]}
["/metrics" {:handler (:handler metrics)}]
["/metrics" {:handler (::mtx/handler metrics)}]
["/assets" {:middleware [(:middleware session)]}
["/by-id/:id" {:handler (:objects-handler assets)}]
["/by-file-media-id/:id" {:handler (:file-objects-handler assets)}]

View file

@ -8,6 +8,8 @@
(:refer-clojure :exclude [run!])
(:require
[app.common.logging :as l]
[app.common.spec :as us]
[app.metrics.definition :as-alias mdef]
[clojure.spec.alpha :as s]
[integrant.core :as ig])
(:import
@ -16,11 +18,12 @@
io.prometheus.client.Counter$Child
io.prometheus.client.Gauge
io.prometheus.client.Gauge$Child
io.prometheus.client.Summary
io.prometheus.client.Summary$Child
io.prometheus.client.Summary$Builder
io.prometheus.client.Histogram
io.prometheus.client.Histogram$Child
io.prometheus.client.SimpleCollector
io.prometheus.client.Summary
io.prometheus.client.Summary$Builder
io.prometheus.client.Summary$Child
io.prometheus.client.exporter.common.TextFormat
io.prometheus.client.hotspot.DefaultExports
java.io.StringWriter))
@ -28,7 +31,7 @@
(set! *warn-on-reflection* true)
(declare create-registry)
(declare create)
(declare create-collector)
(declare handler)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -37,128 +40,151 @@
(def default-metrics
{:update-file-changes
{:name "penpot_rpc_update_file_changes_total"
:help "A total number of changes submitted to update-file."
:type :counter}
{::mdef/name "penpot_rpc_update_file_changes_total"
::mdef/help "A total number of changes submitted to update-file."
::mdef/type :counter}
:update-file-bytes-processed
{:name "penpot_rpc_update_file_bytes_processed_total"
:help "A total number of bytes processed by update-file."
:type :counter}
{::mdef/name "penpot_rpc_update_file_bytes_processed_total"
::mdef/help "A total number of bytes processed by update-file."
::mdef/type :counter}
:rpc-mutation-timing
{:name "penpot_rpc_mutation_timing"
:help "RPC mutation method call timming."
:labels ["name"]
:type :histogram}
{::mdef/name "penpot_rpc_mutation_timing"
::mdef/help "RPC mutation method call timming."
::mdef/labels ["name"]
::mdef/type :histogram}
:rpc-command-timing
{:name "penpot_rpc_command_timing"
:help "RPC command method call timming."
:labels ["name"]
:type :histogram}
{::mdef/name "penpot_rpc_command_timing"
::mdef/help "RPC command method call timming."
::mdef/labels ["name"]
::mdef/type :histogram}
:rpc-query-timing
{:name "penpot_rpc_query_timing"
:help "RPC query method call timing."
:labels ["name"]
:type :histogram}
{::mdef/name "penpot_rpc_query_timing"
::mdef/help "RPC query method call timing."
::mdef/labels ["name"]
::mdef/type :histogram}
:websocket-active-connections
{:name "penpot_websocket_active_connections"
:help "Active websocket connections gauge"
:type :gauge}
{::mdef/name "penpot_websocket_active_connections"
::mdef/help "Active websocket connections gauge"
::mdef/type :gauge}
:websocket-messages-total
{:name "penpot_websocket_message_total"
:help "Counter of processed messages."
:labels ["op"]
:type :counter}
{::mdef/name "penpot_websocket_message_total"
::mdef/help "Counter of processed messages."
::mdef/labels ["op"]
::mdef/type :counter}
:websocket-session-timing
{:name "penpot_websocket_session_timing"
:help "Websocket session timing (seconds)."
:type :summary}
{::mdef/name "penpot_websocket_session_timing"
::mdef/help "Websocket session timing (seconds)."
::mdef/type :summary}
:session-update-total
{:name "penpot_http_session_update_total"
:help "A counter of session update batch events."
:type :counter}
{::mdef/name "penpot_http_session_update_total"
::mdef/help "A counter of session update batch events."
::mdef/type :counter}
:tasks-timing
{:name "penpot_tasks_timing"
:help "Background tasks timing (milliseconds)."
:labels ["name"]
:type :summary}
{::mdef/name "penpot_tasks_timing"
::mdef/help "Background tasks timing (milliseconds)."
::mdef/labels ["name"]
::mdef/type :summary}
:redis-eval-timing
{:name "penpot_redis_eval_timing"
:help "Redis EVAL commands execution timings (ms)"
:labels ["name"]
:type :summary}
{::mdef/name "penpot_redis_eval_timing"
::mdef/help "Redis EVAL commands execution timings (ms)"
::mdef/labels ["name"]
::mdef/type :summary}
:rpc-semaphore-queued-submissions
{:name "penpot_rpc_semaphore_queued_submissions"
:help "Current number of queued submissions on RPC-SEMAPHORE."
:labels ["name"]
:type :gauge}
{::mdef/name "penpot_rpc_semaphore_queued_submissions"
::mdef/help "Current number of queued submissions on RPC-SEMAPHORE."
::mdef/labels ["name"]
::mdef/type :gauge}
:rpc-semaphore-used-permits
{:name "penpot_rpc_semaphore_used_permits"
:help "Current number of used permits on RPC-SEMAPHORE."
:labels ["name"]
:type :gauge}
{::mdef/name "penpot_rpc_semaphore_used_permits"
::mdef/help "Current number of used permits on RPC-SEMAPHORE."
::mdef/labels ["name"]
::mdef/type :gauge}
:rpc-semaphore-acquires-total
{:name "penpot_rpc_semaphore_acquires_total"
:help "Total number of acquire operations on RPC-SEMAPHORE."
:labels ["name"]
:type :counter}
{::mdef/name "penpot_rpc_semaphore_acquires_total"
::mdef/help "Total number of acquire operations on RPC-SEMAPHORE."
::mdef/labels ["name"]
::mdef/type :counter}
:executors-active-threads
{:name "penpot_executors_active_threads"
:help "Current number of threads available in the executor service."
:labels ["name"]
:type :gauge}
{::mdef/name "penpot_executors_active_threads"
::mdef/help "Current number of threads available in the executor service."
::mdef/labels ["name"]
::mdef/type :gauge}
:executors-completed-tasks
{:name "penpot_executors_completed_tasks_total"
:help "Aproximate number of completed tasks by the executor."
:labels ["name"]
:type :counter}
{::mdef/name "penpot_executors_completed_tasks_total"
::mdef/help "Aproximate number of completed tasks by the executor."
::mdef/labels ["name"]
::mdef/type :counter}
:executors-running-threads
{:name "penpot_executors_running_threads"
:help "Current number of threads with state RUNNING."
:labels ["name"]
:type :gauge}
{::mdef/name "penpot_executors_running_threads"
::mdef/help "Current number of threads with state RUNNING."
::mdef/labels ["name"]
::mdef/type :gauge}
:executors-queued-submissions
{:name "penpot_executors_queued_submissions"
:help "Current number of queued submissions."
:labels ["name"]
:type :gauge}})
{::mdef/name "penpot_executors_queued_submissions"
::mdef/help "Current number of queued submissions."
::mdef/labels ["name"]
::mdef/type :gauge}})
(s/def ::mdef/name string?)
(s/def ::mdef/help string?)
(s/def ::mdef/labels (s/every string? :kind vector?))
(s/def ::mdef/type #{:gauge :counter :summary :histogram})
(s/def ::mdef/instance
#(instance? SimpleCollector %))
(s/def ::mdef/definition
(s/keys :req [::mdef/name
::mdef/help
::mdef/type]
:opt [::mdef/labels
::mdef/instance]))
(s/def ::definitions
(s/map-of keyword? ::mdef/definition))
(s/def ::registry
#(instance? CollectorRegistry %))
(s/def ::handler fn?)
(s/def ::metrics
(s/keys :req [::registry
::handler
::definitions]))
(defmethod ig/init-key ::metrics
[_ _]
(l/info :action "initialize metrics")
(let [registry (create-registry)
definitions (reduce-kv (fn [res k v]
(->> (assoc v :registry registry)
(create)
(->> (assoc v ::registry registry)
(create-collector)
(assoc res k)))
{}
default-metrics)]
{:handler (partial handler registry)
:definitions definitions
:registry registry}))
(us/verify! ::definitions definitions)
;; TODO: revisit
(s/def ::handler fn?)
(s/def ::registry #(instance? CollectorRegistry %))
(s/def ::metrics
(s/keys :req-un [::registry ::handler]))
{::handler (partial handler registry)
::definitions definitions
::registry registry}))
(defn- handler
[registry _ respond _]
@ -182,13 +208,16 @@
(def default-histogram-buckets
[1 5 10 25 50 75 100 250 500 750 1000 2500 5000 7500])
(defmulti run-collector! (fn [mdef _] (::mdef/type mdef)))
(defmulti create-collector ::mdef/type)
(defn run!
[{:keys [definitions]} {:keys [id] :as params}]
[{:keys [::definitions]} {:keys [id] :as params}]
(when-let [mobj (get definitions id)]
((::fn mobj) params)
(run-collector! mobj params)
true))
(defn create-registry
(defn- create-registry
[]
(let [registry (CollectorRegistry.)]
(DefaultExports/register registry)
@ -200,79 +229,89 @@
(and (.isArray ^Class oc)
(= (.getComponentType oc) String))))
(defn make-counter
[{:keys [name help registry reg labels] :as props}]
(defmethod run-collector! :counter
[{:keys [::mdef/instance]} {:keys [inc labels] :or {inc 1 labels default-empty-labels}}]
(let [instance (.labels instance (if (is-array? labels) labels (into-array String labels)))]
(.inc ^Counter$Child instance (double inc))))
(defmethod run-collector! :gauge
[{:keys [::mdef/instance]} {:keys [inc dec labels val] :or {labels default-empty-labels}}]
(let [instance (.labels ^Gauge instance (if (is-array? labels) labels (into-array String labels)))]
(cond (number? inc) (.inc ^Gauge$Child instance (double inc))
(number? dec) (.dec ^Gauge$Child instance (double dec))
(number? val) (.set ^Gauge$Child instance (double val)))))
(defmethod run-collector! :summary
[{:keys [::mdef/instance]} {:keys [val labels] :or {labels default-empty-labels}}]
(let [instance (.labels ^Summary instance (if (is-array? labels) labels (into-array String labels)))]
(.observe ^Summary$Child instance val)))
(defmethod run-collector! :histogram
[{:keys [::mdef/instance]} {:keys [val labels] :or {labels default-empty-labels}}]
(let [instance (.labels ^Histogram instance (if (is-array? labels) labels (into-array String labels)))]
(.observe ^Histogram$Child instance val)))
(defmethod create-collector :counter
[{::mdef/keys [name help reg labels]
::keys [registry]
:as props}]
(let [registry (or registry reg)
instance (.. (Counter/build)
(name name)
(help help))
_ (when (seq labels)
(.labelNames instance (into-array String labels)))
instance (.register instance registry)]
(help help))]
(when (seq labels)
(.labelNames instance (into-array String labels)))
{::instance instance
::fn (fn [{:keys [inc labels] :or {inc 1 labels default-empty-labels}}]
(let [instance (.labels instance (if (is-array? labels) labels (into-array String labels)))]
(.inc ^Counter$Child instance (double inc))))}))
(assoc props ::mdef/instance (.register instance registry))))
(defn make-gauge
[{:keys [name help registry reg labels] :as props}]
(defmethod create-collector :gauge
[{::mdef/keys [name help reg labels]
::keys [registry]
:as props}]
(let [registry (or registry reg)
instance (.. (Gauge/build)
(name name)
(help help))
_ (when (seq labels)
(.labelNames instance (into-array String labels)))
instance (.register instance registry)]
{::instance instance
::fn (fn [{:keys [inc dec labels val] :or {labels default-empty-labels}}]
(let [instance (.labels ^Gauge instance (if (is-array? labels) labels (into-array String labels)))]
(cond (number? inc) (.inc ^Gauge$Child instance (double inc))
(number? dec) (.dec ^Gauge$Child instance (double dec))
(number? val) (.set ^Gauge$Child instance (double val)))))}))
(help help))]
(when (seq labels)
(.labelNames instance (into-array String labels)))
(defn make-summary
[{:keys [name help registry reg labels max-age quantiles buckets]
:or {max-age 3600 buckets 12 quantiles default-quantiles} :as props}]
(assoc props ::mdef/instance (.register instance registry))))
(defmethod create-collector :summary
[{::mdef/keys [name help reg labels max-age quantiles buckets]
::keys [registry]
:or {max-age 3600 buckets 12 quantiles default-quantiles}
:as props}]
(let [registry (or registry reg)
builder (doto (Summary/build)
(.name name)
(.help help))
_ (when (seq quantiles)
(.maxAgeSeconds ^Summary$Builder builder ^long max-age)
(.ageBuckets ^Summary$Builder builder buckets))
_ (doseq [[q e] quantiles]
(.quantile ^Summary$Builder builder q e))
_ (when (seq labels)
(.labelNames ^Summary$Builder builder (into-array String labels)))
instance (.register ^Summary$Builder builder registry)]
(.help help))]
{::instance instance
::fn (fn [{:keys [val labels] :or {labels default-empty-labels}}]
(let [instance (.labels ^Summary instance (if (is-array? labels) labels (into-array String labels)))]
(.observe ^Summary$Child instance val)))}))
(when (seq quantiles)
(.maxAgeSeconds ^Summary$Builder builder ^long max-age)
(.ageBuckets ^Summary$Builder builder buckets))
(defn make-histogram
[{:keys [name help registry reg labels buckets]
:or {buckets default-histogram-buckets}}]
(doseq [[q e] quantiles]
(.quantile ^Summary$Builder builder q e))
(when (seq labels)
(.labelNames ^Summary$Builder builder (into-array String labels)))
(assoc props ::mdef/instance (.register ^Summary$Builder builder registry))))
(defmethod create-collector :histogram
[{::mdef/keys [name help reg labels buckets]
::keys [registry]
:or {buckets default-histogram-buckets}
:as props}]
(let [registry (or registry reg)
instance (doto (Histogram/build)
(.name name)
(.help help)
(.buckets (into-array Double/TYPE buckets)))
_ (when (seq labels)
(.labelNames instance (into-array String labels)))
instance (.register instance registry)]
(.buckets (into-array Double/TYPE buckets)))]
{::instance instance
::fn (fn [{:keys [val labels] :or {labels default-empty-labels}}]
(let [instance (.labels ^Histogram instance (if (is-array? labels) labels (into-array String labels)))]
(.observe ^Histogram$Child instance val)))}))
(when (seq labels)
(.labelNames instance (into-array String labels)))
(defn create
[{:keys [type] :as props}]
(case type
:counter (make-counter props)
:gauge (make-gauge props)
:summary (make-summary props)
:histogram (make-histogram props)))
(assoc props ::mdef/instance (.register instance registry))))

View file

@ -14,8 +14,8 @@
[app.main.ui.settings.options :refer [options-page]]
[app.main.ui.settings.password :refer [password-page]]
[app.main.ui.settings.profile :refer [profile-page]]
[app.main.ui.settings.sidebar :refer [sidebar]]
[app.util.i18n :as i18n :refer [tr]]
[app.main.ui.settings.sidebar :refer [sidebar]]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[rumext.alpha :as mf]))
@ -31,10 +31,11 @@
(let [section (get-in route [:data :name])
profile (mf/deref refs/profile)
locale (mf/deref i18n/locale)]
(mf/use-effect
#(when (nil? profile)
(st/emit! (rt/nav :auth-login))))
[:section.dashboard-layout
[:& sidebar {:profile profile
:locale locale