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

(ns metrics.ring.expose
  (:import (com.yammer.metrics.core Gauge Timer Counter Histogram Meter))
  (:require [metrics.gauges :as gauges])
  (:require [metrics.meters :as meters])
  (:require [metrics.histograms :as histograms])
  (:require [metrics.counters :as counters])
  (:require [metrics.timers :as timers])
  (:use [ring.util.response :only [header response]])
  (:use [metrics.utils :only [all-metrics]])
  (:use [cheshire.core :only [generate-string]]))


(defprotocol RenderableMetric
  (render-to-basic [metric] "Turn a metric into a basic Clojure datastructure."))

(extend-type Gauge
  RenderableMetric
  (render-to-basic [g]
    {:type :gauge
     :value (gauges/value g)}))

(extend-type Timer
  RenderableMetric
  (render-to-basic [t]
    {:type :timer
     :rates (timers/rates t)
     :percentiles (timers/percentiles t)
     :max (timers/largest t)
     :min (timers/smallest t)
     :mean (timers/mean t)
     :standard-deviation (timers/std-dev t)}))

(extend-type Meter
  RenderableMetric
  (render-to-basic [m]
    {:type :meter
     :rates (meters/rates m)}))

(extend-type Histogram
  RenderableMetric
  (render-to-basic [h]
    {:type :histogram
     :max (histograms/largest h)
     :min (histograms/smallest h)
     :mean (histograms/mean h)
     :standard-deviation (histograms/std-dev h)
     :percentiles (histograms/percentiles h)}))

(extend-type Counter
  RenderableMetric
  (render-to-basic [c]
    {:type :counter
     :value (counters/value c)}))

(defn- ensure-leading-slash [s]
  (if (not= \/ (first s))
    (str \/ s)
    s))

(defn- strip-trailing-slash [s]
  (if (= \/ (last s))
    (apply str (butlast s))
    s))

(defn- sanitize-uri [uri]
  (str (-> uri
         ensure-leading-slash
         strip-trailing-slash)
       \/))

(defn- render-metric [[metric-name metric]]
  [metric-name (render-to-basic metric)])

(defn- metrics-json [request]
  (let [metrics-map (into {} (map render-metric (all-metrics)))
        json (generate-string metrics-map)]
    (-> (response json)
      (header "Content-Type" "application/json"))))

(defn expose-metrics-as-json
  ([handler] (expose-metrics-as-json handler "/metrics"))
  ([handler uri]
   (let [uri (sanitize-uri uri)]
     (fn [request]
       (if (.startsWith (:uri request) uri)
         (metrics-json request)
         (handler request))))))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.