 
 
 (defn- wrap-ring-analytics*
-  [{:keys [client logger] :as record} app-name handler]
+  [{:keys [client logger] :as record} app-name request-filter response-filter handler]
   (fn [request]
     (let [started (System/currentTimeMillis)
           response (try (handler request)
                         (catch Throwable t (ex/exit-when-fatal t) t))
           took (- (System/currentTimeMillis) started)
-          processed (-> request
-                        (dissoc :body :async-channel)
-                        (assoc :started (time/format (time/datetime started)
-                                                     :date-hour-minute-second-ms)
-                               :response (if (instance? Throwable response)
-                                           {:message (.getMessage ^Throwable response)
-                                            :stacktrace (with-out-str
-                                                          (print-cause-trace response))
-                                            :class (str (class response))
-                                            :status 500
-                                            :took took}
-                                           (-> response
-                                               (dissoc :body)
-                                               (assoc :took took)))))]
+          processed (-> (transient request)
+                        (request-filter response)
+                        (dissoc! :async-channel)
+                        (assoc! :started (time/format (time/datetime started)
+                                                      :date-hour-minute-second-ms)
+                                :response (if (instance? Throwable response)
+                                            {:message (.getMessage ^Throwable response)
+                                             :stacktrace (with-out-str
+                                                           (print-cause-trace response))
+                                             :class (str (class response))
+                                             :status 500
+                                             :took took}
+                                            (-> (transient response)
+                                                (assoc! :took took)
+                                                (response-filter request)
+                                                (persistent!))))
+                        (persistent!))]
       (try (store-request client app-name processed)
            (catch Throwable t
              (ex/exit-when-fatal t)

(refer-logging)


;;; The public system API.

(defprotocol Analytics
  (wrap-ring-analytics [this app-name handler]
    "Returns a handler that stores the given request, using the given
    app name for the log name. The body is not read by this
    middleware."))

(extend-type nil
  Analytics
  (wrap-ring-analytics [this app-name handler] handler))


;;; ElasticSearch implementation.

(defrecord ElasticAnalytics [client logger atat]
  Analytics
  (wrap-ring-analytics [this app-name handler]
    (wrap-ring-analytics* this app-name, dissoc!-body   dissoc!-body    handler))
  (wrap-ring-analytics [this app-name request-filter response-filter handler]
    (wrap-ring-analytics* this app-name, request-filter response-filter handler))

  Stoppable
  (stop [this]
    (info logger "Stopping Analytics based on ElasticSearch.")
