iapetos icon indicating copy to clipboard operation
iapetos copied to clipboard

Jetty Metrics

Open naveen-negi opened this issue 5 years ago • 1 comments

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

naveen-negi avatar Jun 26 '20 13:06 naveen-negi

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.

Limess avatar Nov 20 '20 15:11 Limess