Skip to content

Commit 243e7fa

Browse files
Merge pull request #131 from malesch/feature/ring-metric-units
Configurable duration and rate units for Ring reporter middleware
2 parents 60095d2 + 0f30919 commit 243e7fa

File tree

2 files changed

+72
-27
lines changed

2 files changed

+72
-27
lines changed

metrics-clojure-ring/src/metrics/ring/expose.clj

+34-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(ns metrics.ring.expose
2-
(:import (com.codahale.metrics Gauge Timer Counter Histogram Meter))
2+
(:import (com.codahale.metrics Gauge Timer Counter Histogram Meter)
3+
(java.util.concurrent TimeUnit))
34
(:require [clojure.string :as string]
45
[metrics.gauges :as gauges]
56
[metrics.meters :as meters]
@@ -9,39 +10,43 @@
910
[ring.util.response :refer [header response]]
1011
[metrics.core :refer [default-registry]]
1112
[metrics.utils :refer [all-metrics]]
13+
[metrics.ring.unit :as unit]
1214
[cheshire.core :refer [generate-string]]))
1315

1416

1517
; Define rendering protocol ---------------------------------------------------
1618
(defprotocol RenderableMetric
17-
(render-to-basic [metric] "Turn a metric into a basic Clojure datastructure."))
19+
(render-to-basic [metric unit-opts] "Turn a metric into a basic Clojure datastructure."))
1820

1921
(extend-type Gauge
2022
RenderableMetric
21-
(render-to-basic [g]
23+
(render-to-basic [g _]
2224
{:type :gauge
2325
:value (gauges/value g)}))
2426

2527
(extend-type Timer
2628
RenderableMetric
27-
(render-to-basic [t]
28-
{:type :timer
29-
:rates (timers/rates t)
30-
:percentiles (timers/percentiles t)
31-
:max (timers/largest t)
32-
:min (timers/smallest t)
33-
:mean (timers/mean t)
34-
:standard-deviation (timers/std-dev t)}))
29+
(render-to-basic [t unit-opts]
30+
{:type :timer
31+
:duration-unit (:duration-unit-label unit-opts)
32+
:rate-unit (:rate-unit-label unit-opts)
33+
:rates (unit/convert-rates (timers/rates t) unit-opts)
34+
:percentiles (unit/convert-percentiles (timers/percentiles t) unit-opts)
35+
:max (unit/convert-duration (timers/largest t) unit-opts)
36+
:min (unit/convert-duration (timers/smallest t) unit-opts)
37+
:mean (unit/convert-duration (timers/mean t) unit-opts)
38+
:standard-deviation (unit/convert-duration (timers/std-dev t) unit-opts)}))
3539

3640
(extend-type Meter
3741
RenderableMetric
38-
(render-to-basic [m]
39-
{:type :meter
40-
:rates (meters/rates m)}))
42+
(render-to-basic [m unit-opts]
43+
{:type :meter
44+
:rate-unit (:rate-unit-label unit-opts)
45+
:rates (unit/convert-rates (meters/rates m) unit-opts)}))
4146

4247
(extend-type Histogram
4348
RenderableMetric
44-
(render-to-basic [h]
49+
(render-to-basic [h _]
4550
{:type :histogram
4651
:max (histograms/largest h)
4752
:min (histograms/smallest h)
@@ -51,7 +56,7 @@
5156

5257
(extend-type Counter
5358
RenderableMetric
54-
(render-to-basic [c]
59+
(render-to-basic [c _]
5560
{:type :counter
5661
:value (counters/value c)}))
5762

@@ -75,8 +80,8 @@
7580
strip-trailing-slash)
7681
\/))
7782

78-
(defn- render-metric [[metric-name metric]]
79-
[metric-name (render-to-basic metric)])
83+
(defn- render-metric [[metric-name metric] unit-opts]
84+
[metric-name (render-to-basic metric unit-opts)])
8085

8186
(defn- placeholder? [c]
8287
(contains? #{"" "*"} c))
@@ -102,21 +107,21 @@
102107

103108
(defn render-metrics
104109
([]
105-
(render-metrics default-registry nil))
110+
(render-metrics default-registry nil nil))
106111
([filter]
107-
(render-metrics default-registry filter))
108-
([registry filter]
109-
(into {} (map render-metric (->> registry
110-
(all-metrics)
111-
(filter-metrics filter))))))
112+
(render-metrics default-registry filter nil))
113+
([registry filter unit-context]
114+
(into {} (map #(render-metric % unit-context) (->> registry
115+
(all-metrics)
116+
(filter-metrics filter))))))
112117

113118
(defn serve-metrics
114119
([request]
115120
(serve-metrics request default-registry))
116121
([request registry]
117122
(serve-metrics request registry false))
118-
([request registry {:keys [pretty-print? filter] :as opts}]
119-
(let [metrics-map (render-metrics registry filter)
123+
([request registry {:keys [pretty-print? filter rate-unit duration-unit]}]
124+
(let [metrics-map (render-metrics registry filter (unit/build-options rate-unit duration-unit))
120125
json (generate-string metrics-map {:pretty pretty-print?})]
121126
(-> (response json)
122127
(header "Content-Type" "application/json")))))
@@ -134,5 +139,7 @@
134139
^String filter (get-in request [:params :filter])]
135140
(if (or (.startsWith request-uri (sanitize-uri uri))
136141
(= request-uri uri))
137-
(serve-metrics request registry (merge {:filter filter} opts))
142+
(serve-metrics request registry (merge {:filter filter
143+
:rate-unit TimeUnit/SECONDS
144+
:duration-unit TimeUnit/NANOSECONDS} opts))
138145
(handler request))))))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
(ns metrics.ring.unit
2+
(:require [clojure.string :as string])
3+
(:import (java.util.concurrent TimeUnit)))
4+
5+
6+
(defn- rate-factor [^TimeUnit rate-unit]
7+
(.toSeconds rate-unit 1))
8+
9+
(defn- duration-factor [^TimeUnit duration-unit]
10+
(/ 1.0 (.toNanos duration-unit 1)))
11+
12+
(defn- duration-unit-label [^TimeUnit duration-unit]
13+
(string/lower-case duration-unit))
14+
15+
(defn- rate-unit-label [^TimeUnit rate-unit]
16+
(let [ustr (str rate-unit)]
17+
(str "events/" (subs (string/lower-case ustr) 0 (dec (count ustr))))))
18+
19+
(defn- scale-metrics-map [m factor & ignored-keys]
20+
(let [ignored (into #{} ignored-keys)]
21+
(into {} (for [[k v] m]
22+
[k (if (ignored k) v (* v factor))]))))
23+
24+
25+
(defn build-options [^TimeUnit rate-unit ^TimeUnit duration-unit]
26+
{:rate-factor (rate-factor rate-unit)
27+
:rate-unit-label (rate-unit-label rate-unit)
28+
:duration-factor (duration-factor duration-unit)
29+
:duration-unit-label (duration-unit-label duration-unit)})
30+
31+
(defn convert-duration [v {:keys [duration-factor]}]
32+
(* v duration-factor))
33+
34+
(defn convert-rates [rates {:keys [rate-factor]}]
35+
(scale-metrics-map rates rate-factor :mean :total))
36+
37+
(defn convert-percentiles [percentiles {:keys [duration-factor]}]
38+
(scale-metrics-map percentiles duration-factor))

0 commit comments

Comments
 (0)