iapetos
iapetos copied to clipboard
Jetty Metrics
Is there a way to collect embedded jetty metrics ? I am interested in these metrics https://github.com/prometheus/client_java/blob/master/simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java#L44
- Thanks
This is how I currently implemented this:
Add the dependencies to project.clj or equivalent project file:
[iapetos "0.1.8"]
;; bump the versions of the io.prometheus libs
[io.prometheus/simpleclient "0.9.0"]
[io.prometheus/simpleclient_common "0.9.0"]
[io.prometheus/simpleclient_hotspot "0.9.0"]
[io.prometheus/simpleclient_pushgateway "0.9.0"]
;; iapetos does not include this currently.
[io.prometheus/simpleclient_jetty "0.9.0" :exclusions [org.eclipse.jetty/jetty-server
org.eclipse.jetty/jetty-servlet]]
(require '[iapetos.core :as prometheus]])
(import [io.prometheus.client Collector$MetricFamilySamples])
(import [org.eclipse.jetty.server.handler StatisticsHandler])
(import [io.prometheus.client.jetty JettyStatisticsCollector])
(defn- metric-family-samples->metric
[^io.prometheus.client.Collector v ^Collector$MetricFamilySamples s]
(if-let [n (.name s)]
(let [[a b] (.split n "_" 2)]
(if b
{:name b, :namespace a}
{:name a, :namespace "raw"}))
{:name (str (.getSimpleName (class v)) "_" (hash v))
:namespace "raw"}));
(defonce jetty-statistics-handler (delay (StatisticsHandler.)))
(defn wrap-jetty-statistics
"Replaces the handler configured on the given jetty server with a handler wrapped by the jetty statistics handler, returns the server."
[^org.eclipse.jetty.server.Server server]
(let [existing-handler (.getHandler server)]
(.setHandler @jetty-statistics-handler existing-handler)
(.setHandler server @jetty-statistics-handler)
server))
(defn- jetty-initialise [registry]
(let [collector (JettyStatisticsCollector. @jetty-statistics-handler)
metricFamilySamples (.collect collector)]
(doseq [sample metricFamilySamples]
(prometheus/register registry (reify iapetos.collector.Collector
(instantiate [_ _]
collector)
(metric [this]
(metric-family-samples->metric collector sample))
(label-instance [_ instance values]
(if-not (empty? values)
(throw (UnsupportedOperationException.))
instance)))))
registry))
(defonce registry
(-> (prometheus/collector-registry)
(jetty-initialise)))
;; start your server
(require '[ring.adapter.jetty :refer [run-jetty]])
(defn start-server []
(run-jetty app {:configurator (fn [server]
(-> server
wrap-jetty-statistics))
:port 8080
:join? false})
)
For reference, this currently exposes the following metrics:
jetty_requests_total
jetty_requests_active
jetty_requests_active_max
jetty_request_time_max_seconds
jetty_request_time_seconds_total
jetty_dispatched_total
jetty_dispatched_active
jetty_dispatched_active_max
jetty_dispatched_time_max
jetty_dispatched_time_seconds_total
jetty_async_requests_total
jetty_async_requests_waiting
jetty_async_requests_waiting_max
jetty_async_dispatches_total
jetty_expires_total
jetty_responses_total{code="1xx",}
jetty_responses_total{code="2xx",}
jetty_responses_total{code="3xx",}
jetty_responses_total{code="4xx",}
jetty_responses_total{code="5xx",}
jetty_stats_seconds
jetty_responses_bytes_total
There's probably some improvements to avoid re-defining the Collector -> metric mapping and some other improvements (I'm still relatively new to Clojure).
I'd like to add this to iapetos directly but may not have time to put a PR together anytime soon.