Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jetty Metrics #46

Open
naveen-negi opened this issue Jun 26, 2020 · 1 comment
Open

Jetty Metrics #46

naveen-negi opened this issue Jun 26, 2020 · 1 comment

Comments

@naveen-negi
Copy link

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
@Limess
Copy link

Limess commented Nov 20, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants