dependencies
| (this space intentionally left almost blank) | ||||||
Utility library for emitting messages to | (ns logfmt.core (:require [io.aviso.ansi :as ansi])) | ||||||
Indicates whether development mode is active. | (def dev-mode false) | ||||||
Updates | (defn set-dev-mode! [value] (alter-var-root #'dev-mode (constantly value))) | ||||||
(defn- string-with-slash-or-whitespace? [s] (and (string? s) (re-find #"(\/|\s)" s))) | |||||||
Formats a key / value pair as | (defn- format-key-value-pairs [[k v]] (let [format-str (if (string-with-slash-or-whitespace? v) "%s=\"%s\"" "%s=%s")] (format format-str (name k) v))) | ||||||
When | (defn- determine-color-fn [level] (cond (= :info level) ansi/cyan (= :error level) ansi/red :else identity)) | ||||||
Build the message based on When | (defn- full-message [level text attrs] (let [level-str (name level) color (determine-color-fn level) attr-str (clojure.string/join " " (map format-key-value-pairs attrs))] (if dev-mode (clojure.string/trimr (format "\n%s | %s %s" (color level-str) (color text) attr-str)) (clojure.string/trim (format "at=%s msg=\"%s\" %s" level-str text attr-str))))) | ||||||
Generic log function. For JVM projects, Heroku recommends using
| (defn- log ([level message] (log level message {})) ([level message attrs] (.println System/out (full-message level message attrs)))) | ||||||
Log information level messages. | (def info (partial log :info)) | ||||||
Log error level messages. | (def error (partial log :error)) | ||||||
Ring middleware helpers. | (ns logfmt.ring.middleware (:require [logfmt.core :refer [info]]) (:import (java.util UUID))) | ||||||
Wraps a Ring request outputting two logging messages: one for the request
and another for the response. Includes useful attributes such as Also adds a Heroku will add a | (defn wrap-logger [handler] (fn [req] (let [start (System/currentTimeMillis) request-id (get-in req [:headers "x-request-id"] (UUID/randomUUID)) method (clojure.string/upper-case (name (:request-method req))) path (str (:uri req) (if-let [query-string (:query-string req)] (str "?" query-string)))] (info (format "Started %s '%s'" method path) {:method method :path path :params (:params req) :request-id request-id}) (let [response (handler req) status (:status response) duration (str (- (System/currentTimeMillis) start) "ms")] (info (format "Completed %s in %s" status duration) {:method method :path path :status status :duration duration :request-id request-id}) response)))) | ||||||