When clojure.tools.logging is not enough
'Log data, not strings' is a thing, but of all the Java Logging frameworks, log4j2 is the
only one that actually does that. In all logging frameworks you can format messages as
json or something and get {level: "INFO", message "bar"}
, but what is different with log4j2
is that you can log arbitrary data and have that data passed as-is to appenders, such as
nosql appenders. So the console
appender might format that data as JSON, but the mongo appender will persist a mongo object
created directly from the data, not a string representation of it.
clojure.tools.logging can route log statements through many java logging systems including log4j2. However, the args to log functions are stringified before calling the underlying impl so it is not suitable for logging data.
The same limitation also exists in pedestal.log
I haven't used that personally. It might be great, others seem less keen - see Clojureverse thread below for example.
Feature-wise that seems to be the same as log4j2, so to consider that I'd be looking for some compelling reasons to move away from what I consider the safe choice of log4j2.
(ns my.ns
(:require [com.widdindustries.log4j2.log-api :as log])
(:import [org.apache.logging.log4j.message MapMessage]))
;log string
(log/info "hello")
;log a Message - this is how you 'log data'
(log/info (MapMessage. {"foo" "bar"}))
;clojure maps wrapped in MapMessage object
(log/info {"foo" "bar"})
; varargs for formatted string only
(log/info "hello {} there" :foo)
; builder - include throwable|marker|location
(-> (log/info-builder)
(log/with-location)
(log/with-throwable *e)
; finally log string or Message etc
(log/log {"foo" "bar"}))
; change log level to trace
(log/set-level 'my.ns :trace)
Configure log4j2 with xml etc as you like, but if you prefer to do it programmatically, there is a little sugar in this lib that might help a bit.
Configure logger before logging
(ns my.ns
(:require [com.widdindustries.log4j2.config :as config]))
; the equivalent of having magic xml file on classpath
(defn setup-logging []
(let [builder (config/builder)
std-out-appender-name "Stdout"]
(-> builder
(.add (config/std-out-appender builder std-out-appender-name
"%date %level %logger %message%n%throwable"))
(.add (config/root-logger builder org.apache.logging.log4j.Level/INFO std-out-appender-name))
(.add (config/logger builder Level/DEBUG std-out-appender-name "my.ns"))
;(.writeXmlConfiguration System/out)
(config/start))))
create a git tag.
make install VERSION=your-tag
(this installs in ~/.m2 - check that things look ok)
make deploy VERSION=your-tag
- you need to have set up clojars credentials as per https://github.com/applied-science/deps-library
git push origin new-tag-name
Copyright © 2021 Widd Industries
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close