Add clojure.tools.logging + timbre
This commit is contained in:
parent
a359bd1746
commit
e996351dc9
5 changed files with 153 additions and 3 deletions
|
|
@ -6,12 +6,16 @@ For a list of breaking changes, check [here](#breaking-changes).
|
|||
|
||||
Babashka proper:
|
||||
|
||||
- Add `clojure.tools.logging` with `taoensso.timbre` as the default implementation
|
||||
- Passing form on Windows with question mark breaks evaluation [#889](https://github.com/babashka/babashka/issues/889)
|
||||
- `(read-line)` is buggy in REPL [#899](https://github.com/babashka/babashka/issues/899)
|
||||
- Add `java.io.FileInputStream`. This fixes compatibility with [replikativ/hasch](https://github.com/replikativ/hasch).
|
||||
- `babashka.tasks/clojure` with `:dir` option doesn't resolve deps in `:dir` [#914](https://github.com/babashka/babashka/issues/914)
|
||||
- Support `pprint/formatter-out` [#922](https://github.com/babashka/babashka/issues/922)
|
||||
- Support `pprint/cl-format` with `with-out-str` [#930](https://github.com/babashka/babashka/issues/930)
|
||||
- Compatibility with `org.clojure/data.json {:mvn/version "2.4.0}"`
|
||||
- Support passing `GITLIBS` via `:extra-env` in `clojure` to set git lib dir:
|
||||
`(clojure {:extra-env {"GITLIBS" ".gitlib"}} ,,,) [#934](https://github.com/babashka/babashka/issues/934)`
|
||||
|
||||
Deps.clj:
|
||||
|
||||
|
|
|
|||
4
deps.edn
4
deps.edn
|
|
@ -37,7 +37,9 @@
|
|||
org.clojure/core.match {:mvn/version "1.0.0"}
|
||||
hiccup/hiccup {:mvn/version "2.0.0-alpha2"}
|
||||
rewrite-clj/rewrite-clj {:mvn/version "1.0.605-alpha"}
|
||||
selmer/selmer {:mvn/version "1.12.40"}}
|
||||
selmer/selmer {:mvn/version "1.12.40"}
|
||||
com.taoensso/timbre {:mvn/version "5.1.2"}
|
||||
org.clojure/tools.logging {:mvn/version "1.1.0"}}
|
||||
:aliases {:babashka/dev
|
||||
{:main-opts ["-m" "babashka.main"]}
|
||||
:profile
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@
|
|||
[cheshire "5.10.0"]
|
||||
[nrepl/bencode "1.1.0"]
|
||||
[borkdude/sci.impl.reflector "0.0.1"]
|
||||
[org.clojure/test.check "1.1.0"]]
|
||||
[org.clojure/test.check "1.1.0"]
|
||||
[com.taoensso/timbre "5.1.2"]
|
||||
[org.clojure/tools.logging "1.1.0"]]
|
||||
:profiles {:feature/xml {:source-paths ["feature-xml"]
|
||||
:dependencies [[org.clojure/data.xml "0.2.0-alpha6"]]}
|
||||
:feature/yaml {:source-paths ["feature-yaml"]
|
||||
|
|
|
|||
137
src/babashka/impl/timbre.clj
Normal file
137
src/babashka/impl/timbre.clj
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
(ns babashka.impl.timbre
|
||||
(:require [clojure.tools.logging]
|
||||
[clojure.tools.logging.impl :as impl]
|
||||
[sci.core :as sci]
|
||||
[taoensso.encore :as enc :refer [have]]
|
||||
[taoensso.timbre :as timbre]))
|
||||
|
||||
;;;; timbre
|
||||
|
||||
(def tns (sci/create-ns 'taoensso.timbre nil))
|
||||
|
||||
(defn- fline [and-form] (:line (meta and-form)))
|
||||
|
||||
(defmacro log! ; Public wrapper around `-log!`
|
||||
"Core low-level log macro. Useful for tooling, etc.
|
||||
* `level` - must eval to a valid logging level
|
||||
* `msg-type` - must eval to e/o #{:p :f nil}
|
||||
* `opts` - ks e/o #{:config :?err :?ns-str :?file :?line :?base-data :spying?}
|
||||
Supports compile-time elision when compile-time const vals
|
||||
provided for `level` and/or `?ns-str`."
|
||||
[level msg-type args & [opts]]
|
||||
(have [:or nil? sequential?] args) ; To allow -> (delay [~@args])
|
||||
(let [{:keys [?ns-str] :or {?ns-str (str @sci/ns)}} opts]
|
||||
;; level, ns may/not be compile-time consts:
|
||||
(when-not (timbre/-elide? level ?ns-str)
|
||||
(let [{:keys [config ?err ?file ?line ?base-data spying?]
|
||||
:or {config 'taoensso.timbre/*config*
|
||||
?err :auto ; => Extract as err-type v0
|
||||
?file @sci/file
|
||||
;; NB waiting on CLJ-865:
|
||||
?line (fline &form)}} opts
|
||||
|
||||
?file (when (not= ?file "NO_SOURCE_PATH") ?file)
|
||||
|
||||
;; Identifies this particular macro expansion; note that this'll
|
||||
;; be fixed for any fns wrapping `log!` (notably `tools.logging`,
|
||||
;; `slf4j-timbre`, etc.):
|
||||
callsite-id
|
||||
(hash [level msg-type args ; Unevaluated args (arg forms)
|
||||
?ns-str ?file ?line (rand)])]
|
||||
|
||||
`(taoensso.timbre/-log! ~config ~level ~?ns-str ~?file ~?line ~msg-type ~?err
|
||||
(delay [~@args]) ~?base-data ~callsite-id ~spying?)))))
|
||||
|
||||
(defn make-ns [ns sci-ns ks]
|
||||
(reduce (fn [ns-map [var-name var]]
|
||||
(let [m (meta var)
|
||||
no-doc (:no-doc m)
|
||||
doc (:doc m)
|
||||
arglists (:arglists m)]
|
||||
(if no-doc ns-map
|
||||
(assoc ns-map var-name
|
||||
(sci/new-var (symbol var-name) @var
|
||||
(cond-> {:ns sci-ns
|
||||
:name (:name m)}
|
||||
(:macro m) (assoc :macro true)
|
||||
doc (assoc :doc doc)
|
||||
arglists (assoc :arglists arglists)))))))
|
||||
{}
|
||||
(select-keys (ns-publics ns) ks)))
|
||||
|
||||
(def config (sci/new-dynamic-var '*config* timbre/*config* {:ns tns}))
|
||||
|
||||
(defn swap-config! [f & args]
|
||||
(apply sci/alter-var-root config f args))
|
||||
|
||||
(defn set-level! [level] (swap-config! (fn [m] (assoc m :min-level level))))
|
||||
|
||||
(def timbre-namespace
|
||||
(assoc (make-ns 'taoensso.timbre tns ['trace 'tracef 'debug 'debugf
|
||||
'info 'infof 'warn 'warnf
|
||||
'error 'errorf
|
||||
'-log! 'with-level
|
||||
'println-appender 'spit-appender])
|
||||
'log! (sci/copy-var log! tns)
|
||||
'*config* config
|
||||
'swap-config! (sci/copy-var swap-config! tns)
|
||||
'set-level! (sci/copy-var set-level! tns)))
|
||||
|
||||
;;;; clojure.tools.logging
|
||||
|
||||
(defn- force-var "To support dynamic vars, etc."
|
||||
[x] (if (instance? clojure.lang.IDeref x) (deref x) x))
|
||||
|
||||
(deftype Logger [logger-ns-str timbre-config]
|
||||
clojure.tools.logging.impl/Logger
|
||||
|
||||
(enabled? [_ level]
|
||||
;; No support for per-call config
|
||||
(timbre/may-log? level logger-ns-str
|
||||
(force-var timbre-config)))
|
||||
|
||||
(write! [_ level throwable message]
|
||||
(log! level :p
|
||||
[message] ; No support for pre-msg raw args
|
||||
{:config (force-var timbre-config) ; No support for per-call config
|
||||
:?ns-str logger-ns-str
|
||||
:?file nil ; No support
|
||||
:?line nil ; ''
|
||||
:?err throwable})))
|
||||
|
||||
(deftype LoggerFactory [get-logger-fn]
|
||||
clojure.tools.logging.impl/LoggerFactory
|
||||
(name [_] "Timbre")
|
||||
(get-logger [_ logger-ns] (get-logger-fn logger-ns)))
|
||||
|
||||
(alter-var-root
|
||||
#'clojure.tools.logging/*logger-factory*
|
||||
(fn [_]
|
||||
(LoggerFactory.
|
||||
(enc/memoize (fn [logger-ns] (Logger. (str logger-ns) config))))))
|
||||
|
||||
(def lns (sci/create-ns 'clojure.tools.logging nil))
|
||||
|
||||
(defmacro log
|
||||
"Evaluates and logs a message only if the specified level is enabled. See log*
|
||||
for more details."
|
||||
([level message]
|
||||
`(clojure.tools.logging/log ~level nil ~message))
|
||||
([level throwable message]
|
||||
`(clojure.tools.logging/log ~(deref sci/ns) ~level ~throwable ~message))
|
||||
([logger-ns level throwable message]
|
||||
`(clojure.tools.logging/log clojure.tools.logging/*logger-factory* ~logger-ns ~level ~throwable ~message))
|
||||
([logger-factory logger-ns level throwable message]
|
||||
`(let [logger# (impl/get-logger ~logger-factory ~logger-ns)]
|
||||
(if (impl/enabled? logger# ~level)
|
||||
(clojure.tools.logging/log* logger# ~level ~throwable ~message)))))
|
||||
|
||||
(def tools-logging-namespace
|
||||
(assoc (make-ns 'clojure.tools.logging lns ['debug 'debugf 'info 'infof 'warn 'warnf 'error 'errorf
|
||||
'logp 'logf '*logger-factory* 'log*])
|
||||
'log (sci/copy-var log lns)))
|
||||
|
||||
(def lins (sci/create-ns 'clojure.tools.logging.impl nil))
|
||||
|
||||
(def tools-logging-impl-namespace
|
||||
(make-ns 'clojure.tools.logging.impl lins ['get-logger 'enabled?]))
|
||||
|
|
@ -33,6 +33,8 @@
|
|||
[babashka.impl.socket-repl :as socket-repl]
|
||||
[babashka.impl.tasks :as tasks :refer [tasks-namespace]]
|
||||
[babashka.impl.test :as t]
|
||||
[babashka.impl.timbre :refer [timbre-namespace tools-logging-namespace
|
||||
tools-logging-impl-namespace]]
|
||||
[babashka.impl.tools.cli :refer [tools-cli-namespace]]
|
||||
[babashka.nrepl.server :as nrepl-server]
|
||||
[babashka.wait :as wait]
|
||||
|
|
@ -350,7 +352,10 @@ Use bb run --help to show this help output.
|
|||
'babashka.process process-namespace
|
||||
'clojure.core.server clojure-core-server
|
||||
'babashka.deps deps-namespace
|
||||
'babashka.tasks tasks-namespace}
|
||||
'babashka.tasks tasks-namespace
|
||||
'taoensso.timbre timbre-namespace
|
||||
'clojure.tools.logging tools-logging-namespace
|
||||
'clojure.tools.logging.impl tools-logging-impl-namespace}
|
||||
features/xml? (assoc 'clojure.data.xml @(resolve 'babashka.impl.xml/xml-namespace))
|
||||
features/yaml? (assoc 'clj-yaml.core @(resolve 'babashka.impl.yaml/yaml-namespace)
|
||||
'flatland.ordered.map @(resolve 'babashka.impl.ordered/ordered-map-ns))
|
||||
|
|
|
|||
Loading…
Reference in a new issue