mirror of
https://github.com/taoensso/telemere.git
synced 2025-12-25 04:48:26 +00:00
[new] Refactor interop checks, make extensible
This commit is contained in:
parent
450798832c
commit
722c6abb67
6 changed files with 101 additions and 85 deletions
|
|
@ -173,3 +173,16 @@
|
|||
(org.slf4j.MDC/get "key")
|
||||
(org.slf4j.MDC/getCopyOfContextMap)
|
||||
(org.slf4j.MDC/clear)))
|
||||
|
||||
(impl/add-interop-check! :slf4j
|
||||
(fn []
|
||||
(let [^org.slf4j.Logger sl
|
||||
(org.slf4j.LoggerFactory/getLogger "InteropTestTelemereLogger")
|
||||
sending? (instance? com.taoensso.telemere.slf4j.TelemereLogger sl)
|
||||
receiving?
|
||||
(and sending?
|
||||
(impl/test-interop! "SLF4J -> Telemere" #(.info sl %)))]
|
||||
|
||||
{:present? true
|
||||
:sending->telemere? sending?
|
||||
:telemere-receiving? receiving?})))
|
||||
|
|
|
|||
|
|
@ -359,77 +359,28 @@
|
|||
|
||||
;;;; Interop
|
||||
|
||||
(enc/defaliases impl/check-interop)
|
||||
#?(:clj
|
||||
(do
|
||||
(def ^:private have-tools-logging?
|
||||
(enc/compile-if
|
||||
(do (require '[taoensso.telemere.tools-logging :as ttl]) true)
|
||||
true false))
|
||||
(enc/defaliases
|
||||
streams/with-out->telemere
|
||||
streams/with-err->telemere
|
||||
streams/with-streams->telemere
|
||||
streams/streams->telemere!
|
||||
streams/streams->reset!))
|
||||
|
||||
(enc/compile-when have-tools-logging?
|
||||
(enc/defalias ttl/tools-logging->telemere!)
|
||||
(when (enc/get-env {:as :bool} :clojure.tools.logging->telemere?)
|
||||
(ttl/tools-logging->telemere!)))
|
||||
#?(:clj
|
||||
(enc/compile-when
|
||||
(do (require '[taoensso.telemere.tools-logging :as ttl]) true)
|
||||
(enc/defaliases ttl/tools-logging->telemere!)
|
||||
(when (enc/get-env {:as :bool} :clojure.tools.logging->telemere?)
|
||||
(ttl/tools-logging->telemere!))))
|
||||
|
||||
(enc/defaliases
|
||||
streams/with-out->telemere
|
||||
streams/with-err->telemere
|
||||
streams/with-streams->telemere
|
||||
streams/streams->telemere!
|
||||
streams/streams->reset!)
|
||||
#?(:clj
|
||||
(enc/compile-when
|
||||
(and org.slf4j.Logger com.taoensso.telemere.slf4j.TelemereLogger)
|
||||
(require '[taoensso.telemere.slf4j :as slf4j])))
|
||||
|
||||
(defn- interop-test! [msg form-fn]
|
||||
(let [msg (str "Interop test: " msg " (" (enc/uuid-str) ")")
|
||||
signal
|
||||
(without-filters
|
||||
(impl/with-signal {:stop-propagation? true, :return :signal}
|
||||
(form-fn msg)))]
|
||||
|
||||
(= (force (get signal :msg_)) msg)))
|
||||
|
||||
(defn interop-check
|
||||
"Tests Telemere's interop with `clojure.tools.logging` and SLF4J, useful
|
||||
for tests/debugging. Returns {:keys [tools-logging slf4j streams]} with
|
||||
{:keys [send->telemere? receiving? ...]} sub-maps."
|
||||
[]
|
||||
(let [base-present {:present? true, :send->telemere? false, :receiving? false}]
|
||||
{:tools-logging
|
||||
(if-not (enc/have-resource? "clojure/tools/logging.clj")
|
||||
{:present? false}
|
||||
(merge base-present
|
||||
(enc/compile-when have-tools-logging?
|
||||
(let [sending? (ttl/tools-logging->telemere?)]
|
||||
{:send->telemere? sending?
|
||||
:receiving? (and sending?
|
||||
(interop-test! "`clojure.tools.logging` -> Telemere"
|
||||
#(clojure.tools.logging/info %)))}))))
|
||||
|
||||
:slf4j
|
||||
(if-not (enc/have-class? "org.slf4j.Logger")
|
||||
{:present? false}
|
||||
(merge base-present
|
||||
(enc/compile-when
|
||||
(and org.slf4j.Logger com.taoensso.telemere.slf4j.TelemereLogger)
|
||||
(let [^org.slf4j.Logger sl
|
||||
(org.slf4j.LoggerFactory/getLogger "InteropTestTelemereLogger")
|
||||
|
||||
sending? (instance? com.taoensso.telemere.slf4j.TelemereLogger sl)]
|
||||
|
||||
{:send->telemere? sending?
|
||||
:receiving? (and sending? (interop-test! "SLF4J -> Telemere" #(.info sl %)))}))))
|
||||
|
||||
:streams
|
||||
{:out
|
||||
(let [sending? (boolean @streams/orig-out_)]
|
||||
{:send->telemere? sending?
|
||||
:receiving? (and sending? (interop-test! "`System/out` -> Telemere" #(.println System/out %)))})
|
||||
|
||||
:err
|
||||
(let [sending? (boolean @streams/orig-err_)]
|
||||
{:send->telemere? sending?
|
||||
:receiving? (and sending? (interop-test! "`System/err` -> Telemere" #(.println System/err %)))})}}))))
|
||||
|
||||
(comment (interop-check))
|
||||
(comment (check-interop))
|
||||
|
||||
;;;; Flow benchmarks
|
||||
|
||||
|
|
|
|||
|
|
@ -545,3 +545,32 @@
|
|||
opts)]
|
||||
|
||||
(and (not elide?) allow?))))
|
||||
|
||||
;;;; Interop
|
||||
|
||||
(enc/defonce ^:private interop-checks_ "{<id> (fn check [])}" (atom nil))
|
||||
(defn add-interop-check! [id check-fn] (swap! interop-checks_ assoc id check-fn))
|
||||
|
||||
#?(:clj
|
||||
(when (nil? @interop-checks_)
|
||||
(add-interop-check! :tools-logging (fn [] {:present? (enc/have-resource? "clojure/tools/logging.clj")}))
|
||||
(add-interop-check! :slf4j (fn [] {:present? (enc/compile-when org.slf4j.Logger true false)}))))
|
||||
|
||||
(defn ^:public check-interop
|
||||
"Experimental, subject to change.
|
||||
Runs Telemere's registered interop checks and returns
|
||||
{<interop-id> {:keys [sending->telemere? telemere-receiving? ...]}}.
|
||||
|
||||
Useful for tests/debugging."
|
||||
[]
|
||||
(enc/map-vals (fn [check-fn] (check-fn))
|
||||
@interop-checks_))
|
||||
|
||||
(defn test-interop! [msg test-fn]
|
||||
(let [msg (str "Interop test: " msg " (" (enc/uuid-str) ")")
|
||||
signal
|
||||
(binding [*rt-sig-filter* nil] ; without runtime filters
|
||||
(-with-signal (fn [] (test-fn msg))
|
||||
{:stop-propagation? true, :return :signal}))]
|
||||
|
||||
(= (force (get signal :msg_)) msg)))
|
||||
|
|
|
|||
|
|
@ -73,18 +73,11 @@
|
|||
|
||||
(comment (impl/with-signal (with-out->telemere (println "hello"))))
|
||||
|
||||
(enc/defonce orig-out_ "Original `System/out`, or nil" (atom nil))
|
||||
(enc/defonce orig-err_ "Original `System/err`, or nil" (atom nil))
|
||||
(enc/defonce ^:private orig-out_ "Original `System/out`, or nil" (atom nil))
|
||||
(enc/defonce ^:private orig-err_ "Original `System/err`, or nil" (atom nil))
|
||||
|
||||
(let [monitor (Object.)]
|
||||
|
||||
#_
|
||||
(defn streams->telemere? []
|
||||
;; Not easy to actually identify current `System/out`, `System/err` vals
|
||||
(locking monitor
|
||||
{:out (boolean @orig-out_)
|
||||
:err (boolean @orig-err_)}))
|
||||
|
||||
(defn ^:public streams->reset!
|
||||
"Experimental, subject to change without notice!
|
||||
Resets `System/out` and `System/err` to their original value (prior to any
|
||||
|
|
@ -118,13 +111,25 @@
|
|||
(let [out (when out (telemere-print-stream out))
|
||||
err (when err (telemere-print-stream err))]
|
||||
|
||||
(locking monitor
|
||||
(when out (compare-and-set! orig-out_ nil System/out) (System/setOut out))
|
||||
(when err (compare-and-set! orig-err_ nil System/err) (System/setErr err)))
|
||||
(locking monitor
|
||||
(when out (compare-and-set! orig-out_ nil System/out) (System/setOut out))
|
||||
(when err (compare-and-set! orig-err_ nil System/err) (System/setErr err)))
|
||||
|
||||
true)))))
|
||||
true)))))
|
||||
|
||||
(comment
|
||||
(streams->telemere?)
|
||||
(streams->telemere! {})
|
||||
(streams->reset!))
|
||||
|
||||
(impl/add-interop-check! :system/out
|
||||
(fn []
|
||||
(let [sending? (boolean @orig-out_)
|
||||
receiving? (and sending? (impl/test-interop! "`System/out` -> Telemere" #(.println System/out %)))]
|
||||
{:sending->telemere? sending?, :telemere-receiving? receiving?})))
|
||||
|
||||
(impl/add-interop-check! :system/err
|
||||
(fn []
|
||||
(let [sending? (boolean @orig-err_)
|
||||
receiving? (and sending? (impl/test-interop! "`System/err` -> Telemere" #(.println System/err %)))]
|
||||
{:sending->telemere? sending?, :telemere-receiving? receiving?})))
|
||||
|
|
|
|||
|
|
@ -49,3 +49,15 @@
|
|||
(defn tools-logging->telemere? []
|
||||
(when-let [lf clojure.tools.logging/*logger-factory*]
|
||||
(instance? TelemereLoggerFactory lf)))
|
||||
|
||||
(impl/add-interop-check! :tools-logging
|
||||
(fn []
|
||||
(let [sending? (tools-logging->telemere?)
|
||||
receiving?
|
||||
(and sending?
|
||||
(impl/test-interop! "`clojure.tools.logging` -> Telemere"
|
||||
#(clojure.tools.logging/info %)))]
|
||||
|
||||
{:present? true
|
||||
:sending->telemere? sending?
|
||||
:telemere-receiving? receiving?})))
|
||||
|
|
|
|||
|
|
@ -470,23 +470,29 @@
|
|||
#?(:clj
|
||||
(deftest _interop
|
||||
[(testing "`clojure.tools.logging` -> Telemere"
|
||||
[(is (sm? (tel/interop-check) {:tools-logging {:present? true, :send->telemere? true, :receiving? true}}))
|
||||
[(is (sm? (tel/check-interop) {:tools-logging {:present? true, :sending->telemere? true, :telemere-receiving? true}}))
|
||||
(is (sm? (wsv (ctl/info "Hello" "x" "y")) {:level :info, :location nil, :ns nil, :kind :log, :id :taoensso.telemere/tools-logging, :msg_ "Hello x y"}))
|
||||
(is (sm? (wsv (ctl/warn "Hello" "x" "y")) {:level :warn, :location nil, :ns nil, :kind :log, :id :taoensso.telemere/tools-logging, :msg_ "Hello x y"}))
|
||||
(is (sm? (wsv (ctl/error ex1 "An error")) {:level :error, :error ex1}) "Errors")])
|
||||
|
||||
(testing "Standard out/err streams -> Telemere"
|
||||
[(is (sm? (tel/interop-check) {:streams {:out {:send->telemere? false, :receiving? false}, :err {:send->telemere? false, :receiving? false}}}))
|
||||
[(is (sm? (tel/check-interop) {:system/out {:sending->telemere? false, :telemere-receiving? false},
|
||||
:system/err {:sending->telemere? false, :telemere-receiving? false}}))
|
||||
|
||||
(is (true? (tel/streams->telemere!)))
|
||||
(is (sm? (tel/interop-check) {:streams {:out {:send->telemere? true, :receiving? true}, :err {:send->telemere? true, :receiving? true}}}))
|
||||
(is (sm? (tel/check-interop) {:system/out {:sending->telemere? true, :telemere-receiving? true},
|
||||
:system/err {:sending->telemere? true, :telemere-receiving? true}}))
|
||||
|
||||
(is (true? (tel/streams->reset!)))
|
||||
(is (sm? (tel/interop-check) {:streams {:out {:send->telemere? false, :receiving? false}, :err {:send->telemere? false, :receiving? false}}}))
|
||||
(is (sm? (tel/check-interop) {:system/out {:sending->telemere? false, :telemere-receiving? false},
|
||||
:system/err {:sending->telemere? false, :telemere-receiving? false}}))
|
||||
|
||||
(is
|
||||
(sm? (wsv (tel/with-out->telemere (println "Hello" "x" "y")))
|
||||
{:level :info, :location nil, :ns nil, :kind :system/out, :msg_ "Hello x y"}))])
|
||||
|
||||
(testing "SLF4J -> Telemere"
|
||||
[(is (sm? (tel/interop-check) {:slf4j {:present? true, :send->telemere? true, :receiving? true}}))
|
||||
[(is (sm? (tel/check-interop) {:slf4j {:present? true, :sending->telemere? true, :telemere-receiving? true}}))
|
||||
(let [^org.slf4j.Logger sl (org.slf4j.LoggerFactory/getLogger "MyTelemereSLF4JLogger")]
|
||||
[(testing "Basics"
|
||||
[(is (sm? (wsv (.info sl "Hello")) {:level :info, :location nil, :ns nil, :kind :log, :id :taoensso.telemere/slf4j, :msg_ "Hello"}) "Legacy API: info basics")
|
||||
|
|
|
|||
Loading…
Reference in a new issue