Skip to content

Instantly share code, notes, and snippets.

@dadair-ca
Created December 10, 2019 00:48
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save dadair-ca/08ca7c0b4faba67aceea370ddb5a6c3c to your computer and use it in GitHub Desktop.
(defprotocol Logging
(log [logger data]))
(def ^:dynamic *logger*
(reify Logging
(log [this data]
(clojure.pprint/pprint data))))
(def request-data {::request-id 1 ::request-source "someone"})
(defn map* [f logger]
(reify Logging
(log [this data] (log logger (f data)))))
(defmacro with-logging-context [context & forms]
`(binding [*logger* (map* #(merge % ~context) *logger*)]
~@forms))
(defn handle-request []
(with-logging-context
{::handle-request-1 1}
(log *logger* {::data :z})))
(defn handle-request-2 []
(with-logging-context
{::handle-request-2 2}
(handle-request)))
(defn handle-request-3 []
(with-logging-context
{::handle-request-3 3}
(handle-request-2)))
(handle-request-3)
=>
#:user{:data :z,
:handle-request-1 1,
:handle-request-2 2,
:handle-request-3 3}
;; This method allows for one to pass logging context down the stack, similar to React's Context.
;; This means that `web` code, for example, could add context to the current request logging, which would be included in
;; logging calls "down" in `core` and `infra`.
;; This pattern could be used for adding unique request IDs, with tracing/spans/etc for better telemetry.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment