Logging helper macros
Logging helper macros
(get-loglevel!)
(get-loglevel! cls)
Retrieve the current log level
Retrieve the current log level
(pass expr msg)
(pass expr level msg)
(pass expr level fmt fmt-args)
Convenience macro to log msg
while yielding expr
.
Convenience macro to log `msg` while yielding `expr`.
(passf expr fmt-or-level & args)
Convenience macro to log (format fmt args)
while yielding expr
.
Acceptable forms:
(passf expr :info fmt & fmt-args)
(passf expr fmt & fmt-args)
fmt-or-level
is checked for being a keyword, in which case it is treated
as the log level; otherwise, a default level of :debug
is assumed.
Although this breaks with the tools.logging convention of expr
being last,
writing it in that way is incredibly confusing. This way, even the
thread-last wrapper passf-last
is fairly simple.
The use case is situations where you want to essentially log that something passed through some particular place in the code without necessarily wanting to log the thing itself. For example, when resolving a user, logging the user becomes more and more ridiculous at INFO-level.
This is convenient to avoid something like this:
(def x {:thing {:somekey :some value}})
(if (contains? x :thing)
(do (log/info blah blah blah)
x)
(do (log/warn some other blah blah)
x))
That's purely convenience, and making it easier to understand what the code is doing. An example of where this is almost required:
(def x {:thing {:somekey :some value}})
(some-> x
an-operation
(passf :info "User %s has passed the first hurdle!" user-id)
another-operation
(passf :info "User has passed another hurdle!" user-id))
In the above scenario, we use some->
to short-circuit on a nil
value
coming back from one of the operations in the chain. Without this macro, the
only way to have visibility into the process would be either to ensure that
each step logs aggressively, impossible if using low-level functions, or to
break the logical sequence into a series of when-some
s. Although using
if-some
would allow for logging each step that may or may not fail, and
indeed I use that idiom in many places, there are any number of situations
where you want visibility in the form of 'we got here!' without breaking up
the logical flow of the larger operation into something harder to read.
Convenience macro to log `(format fmt args)` while yielding `expr`. Acceptable forms: ```clojure (passf expr :info fmt & fmt-args) (passf expr fmt & fmt-args) ``` `fmt-or-level` is checked for being a keyword, in which case it is treated as the log level; otherwise, a default level of `:debug` is assumed. Although this breaks with the tools.logging convention of `expr` being last, writing it in that way is incredibly confusing. This way, even the thread-last wrapper [[passf-last]] is fairly simple. The use case is situations where you want to essentially log that something passed through some particular place in the code without necessarily wanting to log the thing itself. For example, when resolving a user, logging the user becomes more and more ridiculous at INFO-level. This is convenient to avoid something like this: ```clojure (def x {:thing {:somekey :some value}}) (if (contains? x :thing) (do (log/info blah blah blah) x) (do (log/warn some other blah blah) x)) ``` That's purely convenience, and making it easier to understand what the code is doing. An example of where this is almost required: ```clojure (def x {:thing {:somekey :some value}}) (some-> x an-operation (passf :info "User %s has passed the first hurdle!" user-id) another-operation (passf :info "User has passed another hurdle!" user-id)) ``` In the above scenario, we use `some->` to short-circuit on a `nil` value coming back from one of the operations in the chain. Without this macro, the only way to have visibility into the process would be either to ensure that each step logs aggressively, impossible if using low-level functions, or to break the logical sequence into a series of `when-some`s. Although using `if-some` would allow for logging each step that may or may not fail, and indeed I use that idiom in many places, there are any number of situations where you want visibility in the form of 'we got here!' without breaking up the logical flow of the larger operation into something harder to read.
(set-loglevel! level)
Update the global log level
Update the global log level
(spy-first expr & args)
Things I like:
Things I don't like:
(-> thing
(some-other thing)
(->> (log/spy :trace))
another-thing)
That's right: this is a macro so I can use log/spy
with (-> ).
Things I like: 1. threading macros 2. inline logging in my threading macros Things I don't like: ```clojure (-> thing (some-other thing) (->> (log/spy :trace)) another-thing) ``` That's right: this is a macro so I can use `log/spy` with (-> ).
(spyf-first expr & args)
Like spy-first
, but dispatches to log/spyf
, rather than log/spy
.
Like `spy-first`, but dispatches to `log/spyf`, rather than `log/spy`.
(strace expr)
No relation to the syscall tracer. Logs expr
at TRACE log level, then
yields expr
.
Most of the time that I find myself using [[log/spy]], I'm inserting some
trace-level info into a threading macro. This removes a lot of the resulting
cruft and also probably takes over the role of spy-first
.
Before:
(-> {:important :thing}
some-operation
(->> (log/spy :trace))
another-operation)
After:
(-> {:important :thing}
some-operation
strace
another-operation)
Look, this happens in more places than you'd think.
No relation to the syscall tracer. Logs `expr` at TRACE log level, then yields `expr`. Most of the time that I find myself using [[log/spy]], I'm inserting some trace-level info into a threading macro. This removes a lot of the resulting cruft and also probably takes over the role of [[spy-first]]. Before: ```clojure (-> {:important :thing} some-operation (->> (log/spy :trace)) another-operation) ``` After: ```clojure (-> {:important :thing} some-operation strace another-operation) ``` Look, this happens in more places than you'd think.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close