Skip to content

Instantly share code, notes, and snippets.

@piranha
Created February 5, 2019 10:38
Show Gist options
  • Save piranha/9b3f21cf0e50ee694d6602c00f1c0f31 to your computer and use it in GitHub Desktop.
Save piranha/9b3f21cf0e50ee694d6602c00f1c0f31 to your computer and use it in GitHub Desktop.
Async Profile Middleware
(defn make-profile-transform [^String thread-name]
(fn [^String s]
(when (> (.indexOf s thread-name) -1)
(-> s
(str/replace #"com.fasterxml.jackson.+" "JACKSON...")
(str/replace #"org.elasticsearch.client.RestClient.+" "ES request...")
(str/replace #"clojure.tools.logging/.+" "LOG...")))))
(defn profiler-mw [handler]
"Supply `_prof=1` to profile single run or `_prof=100` to profile multiple runs.
To profile allocations: `_prof=10,alloc`."
(fn [{qs :query-string :as req}]
(if-not (and (profile-authorized? req)
(some-> qs (str/includes? "_prof=")))
(handler req)
(let [config (-> (re-find #"_prof=([^&]+)" qs)
second
(.split ",")
set)
event-type (if (contains? config "alloc") :alloc :cpu)
times-to-run (->> config
(map #(try (Integer/parseInt %)
(catch Exception e nil)))
(filter identity)
first)
thread-name (.getName (Thread/currentThread))
_ (prof/start {:event event-type
:threads true})
_ (dotimes [_ (or times-to-run 1)]
(handler req))
prof (prof/stop {:transform (make-profile-transform thread-name)})]
{:status 200
:headers {"Content-Type" "image/svg+xml"}
:body prof}))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment