[new] Add Timbre shim ns

This commit is contained in:
Peter Taoussanis 2024-03-28 17:12:54 +01:00
parent e0c3e4ba23
commit 97ddc93775
2 changed files with 162 additions and 0 deletions

View file

@ -0,0 +1,141 @@
(ns taoensso.telemere.timbre-shim
"Main Timbre macros, reimplemented on top of Telemere.
Intended to help ease migration from Timbre to Telemere."
(:require
[clojure.string :as str]
[taoensso.encore :as enc :refer [have have?]]
[taoensso.telemere.impl :as impl]
[taoensso.telemere :as tel]))
(comment
(remove-ns 'taoensso.telemere.timbre-shim)
(:api (enc/interns-overview)))
(let [arg-str
(fn [x]
(enc/cond
(nil? x) "nil"
(record? x) (pr-str x)
:else x))]
(defn ^:no-doc parse-vargs
"Private, don't use. Adapted from Timbre."
[format-msg? vargs]
(let [[v0] vargs]
(if (enc/error? v0)
(let [error v0
vargs (enc/vrest vargs)
pattern (if format-msg? (let [[v0] vargs] v0) nil)
vargs (if format-msg? (enc/vrest vargs) vargs)
msg
(delay
(if format-msg?
(enc/format* pattern vargs)
(enc/str-join " " (map arg-str) vargs)))]
[error msg {:vargs vargs}])
(let [md (if (and (map? v0) (get (meta v0) :meta)) v0 nil)
error (get md :err)
md (dissoc md :err)
vargs (if md (enc/vrest vargs) vargs)
pattern (if format-msg? (let [[v0] vargs] v0) nil)
vargs (if format-msg? (enc/vrest vargs) vargs)
msg
(delay
(if format-msg?
(enc/format* pattern vargs)
(enc/str-join " " (map arg-str) vargs)))]
[error msg {:vargs vargs}])))))
(comment
(parse-vargs true [ "hello %s" "stu"])
(parse-vargs true [(Exception. "Ex1") "hello %s" "stu"]))
(def ^:no-doc ^:const shim-id :taoensso.telemere/timbre-shim)
#?(:clj
(defmacro ^:no-doc log!
"Private, don't use."
[level format-msg? vargs]
(enc/keep-callsite
`(when (impl/signal-allowed? {:kind :log, :level ~level, :id shim-id})
(let [[error# msg# data#] (parse-vargs ~format-msg? ~vargs)]
(tel/log!
{:allow? true
:level ~level
:id shim-id
:error error#
:data data#}
msg#)
nil)))))
(comment
(macroexpand '(trace "foo"))
(tel/with-signal :force-msg (trace "foo"))
(tel/with-signal :force-msg (infof "Hello %s" "world")))
#?(:clj
(do
(defmacro log "Prefer `telemere/log!`, etc." [level & args] (enc/keep-callsite `(log! ~level false [~@args])))
(defmacro trace "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :trace false [~@args])))
(defmacro debug "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :debug false [~@args])))
(defmacro info "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :info false [~@args])))
(defmacro warn "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :warn false [~@args])))
(defmacro error "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :error false [~@args])))
(defmacro fatal "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :fatal false [~@args])))
(defmacro report "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :report false [~@args])))
(defmacro logf "Prefer `telemere/log!`, etc." [level & args] (enc/keep-callsite `(log! ~level true [~@args])))
(defmacro tracef "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :trace true [~@args])))
(defmacro debugf "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :debug true [~@args])))
(defmacro infof "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :info true [~@args])))
(defmacro warnf "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :warn true [~@args])))
(defmacro errorf "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :error true [~@args])))
(defmacro fatalf "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :fatal true [~@args])))
(defmacro reportf "Prefer `telemere/log!`, etc." [& args] (enc/keep-callsite `(log! :report true [~@args])))))
#?(:clj
(defmacro spy!
"Prefer `telemere/spy!`."
([ form] (enc/keep-callsite `(spy! :debug nil ~form)))
([level form] (enc/keep-callsite `(spy! ~level nil ~form)))
([level form-name form]
(let [msg
(if-not form-name
`impl/default-trace-msg
`(fn [_form# value# error# nsecs#]
(impl/default-trace-msg ~form-name value# error# nsecs#)))]
(enc/keep-callsite
`(tel/spy!
{:kind :spy
:level ~level
:id shim-id
:msg ~msg
:catch->error true}
~form))))))
(comment
(select-keys (tel/with-signal :force-msg (spy! :info "my-form-name" (+ 1 2))) [:level :msg_])
(select-keys (tel/with-signal :force-msg (spy! :info "my-form-name" (throw (Exception. "Ex")))) [:level #_:msg_]))
#?(:clj (defmacro log-errors "Prefer `telemere/catch->error!`." [& body] (enc/keep-callsite `(tel/catch->error! {:id shim-id, :catch-val nil} (do ~@body)))))
#?(:clj (defmacro log-and-rethrow-errors "Prefer `telemere/catch->error!`." [& body] (enc/keep-callsite `(tel/catch->error! {:id shim-id} (do ~@body)))))
#?(:clj (defmacro logged-future "Prefer `telemere/catch->error!`." [& body] (enc/keep-callsite `(future (tel/catch->error! {:id shim-id} (do ~@body))))))
#?(:clj
(defmacro refer-timbre
"(require
'[taoensso.telemere.timbre-shim :as timbre :refer
[log trace debug info warn error fatal report
logf tracef debugf infof warnf errorf fatalf reportf
spy]])"
[]
`(require
'~'[taoensso.telemere.timbre-shim :as timbre :refer
[log trace debug info warn error fatal report
logf tracef debugf infof warnf errorf fatalf reportf
spy]])))

View file

@ -9,6 +9,7 @@
:rename {signal! sig!, with-signal with-sig, with-signals with-sigs}]
[taoensso.telemere.utils :as utils]
[taoensso.telemere.timbre-shim :as timbre]
#?(:clj [taoensso.telemere.slf4j :as slf4j])
#?(:clj [clojure.tools.logging :as ctl])
#?(:clj [jsonista.core :as jsonista])))
@ -580,6 +581,26 @@
[(is (sm? (with-sig (-> sl (.info "Hello"))) {:level :info, :ctx {"k1" "v1", "k2" "v2"}}) "Legacy API: MDC")
(is (sm? (with-sig (-> (.atInfo sl) (.log "Hello"))) {:level :info, :ctx {"k1" "v1", "k2" "v2"}}) "Fluent API: MDC")])))])])]))
;;;; Timbre shim
(deftest _timbre-shim
[(is (sm? (with-sig (timbre/log :debug "x1" nil "x2")) {:kind :log, :level :debug, :id timbre/shim-id, :msg_ "x1 nil x2", :data {:vargs ["x1" nil "x2"]}, :ns pstr?}))
(is (sm? (with-sig (timbre/info "x1" nil "x2")) {:kind :log, :level :info, :id timbre/shim-id, :msg_ "x1 nil x2", :data {:vargs ["x1" nil "x2"]}, :ns pstr?}))
(is (sm? (with-sig (timbre/error "x1" nil "x2")) {:kind :log, :level :error, :id timbre/shim-id, :msg_ "x1 nil x2", :data {:vargs ["x1" nil "x2"]}, :ns pstr?}))
(is (sm? (with-sig (timbre/logf :debug "%s %s %s" "x1" nil "x2")) {:kind :log, :level :debug, :id timbre/shim-id, :msg_ "x1 nil x2", :data {:vargs ["x1" nil "x2"]}, :ns pstr?}))
(is (sm? (with-sig (timbre/infof "%s %s %s" "x1" nil "x2")) {:kind :log, :level :info, :id timbre/shim-id, :msg_ "x1 nil x2", :data {:vargs ["x1" nil "x2"]}, :ns pstr?}))
(is (sm? (with-sig (timbre/errorf "%s %s %s" "x1" nil "x2")) {:kind :log, :level :error, :id timbre/shim-id, :msg_ "x1 nil x2", :data {:vargs ["x1" nil "x2"]}, :ns pstr?}))
(is (sm? (with-sig (timbre/info ex1 "x1" "x2")) {:kind :log, :level :info, :error pex1?, :msg_ "x1 x2", :data {:vargs ["x1" "x2"]}}) "First-arg error")
(is (sm? (with-sig (timbre/spy! :info "my-name" (+ 1 2))) {:kind :spy, :level :info, :id timbre/shim-id, :msg_ "my-name => 3", :ns pstr?}))
(is (sm? (with-sig (timbre/spy! (+ 1 2))) {:kind :spy, :level :debug, :id timbre/shim-id, :msg_ "(+ 1 2) => 3", :ns pstr?}))
(is (sm? (with-sig (timbre/spy! (ex1!))) {:kind :error, :level :error, :id timbre/shim-id, :msg_ nil, :error pex1?, :ns pstr?}))
(let [[[rv re] [sv]] (with-sigs (timbre/log-errors (ex1!)))] [(is (nil? re)) (is (sm? sv {:kind :error, :level :error, :error pex1?, :id timbre/shim-id}))])
(let [[[rv re] [sv]] (with-sigs (timbre/log-and-rethrow-errors (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :error, :level :error, :error pex1?, :id timbre/shim-id}))])])
;;;; Utils
(deftest _utils