diff --git a/slf4j/src/taoensso/telemere/slf4j.clj b/slf4j/src/taoensso/telemere/slf4j.clj index 211495a..1cb5c9f 100644 --- a/slf4j/src/taoensso/telemere/slf4j.clj +++ b/slf4j/src/taoensso/telemere/slf4j.clj @@ -102,7 +102,6 @@ (when-debug (println [:slf4j/allowed? (sig-level level)])) (impl/signal-allowed? {:location nil - :ns nil :kind :log :id :taoensso.telemere/slf4j :level (sig-level level)})) @@ -113,7 +112,6 @@ (impl/signal! {:allow? true ; Pre-filtered by `allowed?` call :location nil - :ns nil :kind :log :id :taoensso.telemere/slf4j :level (sig-level level) diff --git a/src/taoensso/telemere.cljc b/src/taoensso/telemere.cljc index cb06f51..b3a6dee 100644 --- a/src/taoensso/telemere.cljc +++ b/src/taoensso/telemere.cljc @@ -350,8 +350,11 @@ (enc/defaliases handlers/console-handler-fn #?(:cljs handlers/raw-console-handler-fn)) -(add-handler! :default-console-handler - (console-handler-fn)) +(defonce ^:no-doc __add-default-handlers + (do + (add-handler! :default-console-handler + (console-handler-fn)) + nil)) ;;;; Flow benchmarks diff --git a/src/taoensso/telemere/handlers.cljc b/src/taoensso/telemere/handlers.cljc index 3384be7..c1a48de 100644 --- a/src/taoensso/telemere/handlers.cljc +++ b/src/taoensso/telemere/handlers.cljc @@ -1,4 +1,4 @@ -(ns ^:no-doc taoensso.telemere.handlers +(ns taoensso.telemere.handlers "Built-in Telemere handlers." (:require [clojure.string :as str] @@ -22,9 +22,9 @@ Defaults to `*err*` if `utils/error-signal?` is true, and `*out*` otherwise. Common formatting alternatives: - (utils/format-signal-str->fn) ; For human-readable string output (default) - (utils/format-signal->edn-fn) ; For edn output - (utils/format-signal->json-fn) ; For JSON output + (utils/format-signal-str->fn) {}) ; For human-readable string output (default) + (utils/format-signal->edn-fn) {}) ; For edn output + (utils/format-signal->json-fn {}) ; For JSON output etc. See each format builder for options, etc." @@ -53,9 +53,9 @@ - Writes a formatted signal string to JavaScript console. Common formatting alternatives: - (utils/format-signal-str->fn) ; For human-readable string output (default) - (utils/format-signal->edn-fn) ; For edn output - (utils/format-signal->json-fn) ; For JSON output + (utils/format-signal-str->fn) {}) ; For human-readable string output (default) + (utils/format-signal->edn-fn) {}) ; For edn output + (utils/format-signal->json-fn {}) ; For JSON output etc. See each format builder for options, etc." diff --git a/src/taoensso/telemere/impl.cljc b/src/taoensso/telemere/impl.cljc index 15acdb6..400d37e 100644 --- a/src/taoensso/telemere/impl.cljc +++ b/src/taoensso/telemere/impl.cljc @@ -263,7 +263,7 @@ (form-fn) (enc/try* (do [(form-fn) nil]) - (catch :any t t [nil t])))] + (catch :all t t [nil t])))] [form-result (when-let [sigs @sigs_] @@ -513,40 +513,38 @@ (if elide? run-form - (let [{:keys [ns line column file]} location - {inst-form :inst - kind-form :kind - id-form :id - level-form :level} opts + (let [{ns-form :ns + line-form :line + column-form :column + file-form :file} location - trace? (get opts :trace? (boolean run-form)) - uid-form (get opts :uid (when trace? :auto/uuid)) - ctx-form (get opts :ctx `taoensso.telemere/*ctx*) - parent-form (get opts :parent (when trace? `taoensso.telemere.impl/*trace-parent*)) - inst-form (get opts :inst :auto) - inst-form (if (= inst-form :auto) `(enc/now-inst*) inst-form) - uid-form (parse-uid-form uid-form) - ;; run-fn-form (when run-form `(fn [] ~run-form)) - run-result-form - (when run-form - `(let [~'__t0 (enc/now-nano*)] - (with-tracing ~trace? ~'__id ~'__uid - (enc/try* - (do (RunResult. ~run-form nil (- (enc/now-nano*) ~'__t0))) - (catch :any ~'__t (RunResult. nil ~'__t (- (enc/now-nano*) ~'__t0))))))) + {inst-form :inst + level-form :level + kind-form :kind + id-form :id} opts + + trace? (get opts :trace? (boolean run-form)) + + inst-form (get opts :inst :auto) + inst-form (if (= inst-form :auto) `(enc/now-inst*) inst-form) + + uid-form (get opts :uid (when trace? :auto/uuid)) + uid-form (parse-uid-form uid-form) signal-form (let [{do-form :do let-form :let - data-form :data msg-form :msg + data-form :data error-form :error - sample-rate-form :sample-rate} - opts + sample-rate-form :sample-rate} opts let-form (or let-form '[]) msg-form (parse-msg-form msg-form) + ctx-form (get opts :ctx `taoensso.telemere/*ctx*) + parent-form (get opts :parent (when trace? `taoensso.telemere.impl/*trace-parent*)) + extra-kvs-form (not-empty (dissoc opts @@ -568,42 +566,52 @@ ~do-form (let ~let-form ; Allow to throw during `signal-value_` deref (new-signal ~'__inst ~'__uid - ~location ~ns ~line ~column ~file, - ~sample-rate-form, ~kind-form ~'__id ~level-form, ~ctx-form ~parent-form, + ~location ~'__ns ~line-form ~column-form ~file-form, + ~sample-rate-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form, ~extra-kvs-form ~data-form ~msg-form, - '~run-form ~'__run-result ~error-form))))] + '~run-form ~'__run-result ~error-form)))) - #_ ; Sacrifice some perf to de-dupe (possibly large) `run-form` - (let [~'__run-fn ~run-fn-form] - (if-not ~allow? - (when ~'__run-fn (~'__run-fn)) - (let []))) + run-fn-form (when run-form `(fn [] (~run-form)))] + + ;; Could avoid double `run-form` expansion with a fn wrap (>0 cost) + ;; `(let [~'run-fn-form ~run-fn-form] + ;; (if-not ~allow? + ;; (run-fn-form) + ;; (let [...]))) `(enc/if-not ~allow? ; Allow to throw at call ~run-form - (let [~'__inst ~inst-form ; Allow to throw at call - ~'__id ~id-form ; '' - ~'__uid ~uid-form ; '' - ~'__run-result ~run-result-form ; Non-throwing (traps) + (let [~'__inst ~inst-form ; Allow to throw at call + ~'__level ~level-form ; '' + ~'__kind ~kind-form ; '' + ~'__id ~id-form ; '' + ~'__uid ~uid-form ; '' + ~'__ns ~ns-form ; '' - ~'__call-middleware - ~(get opts :middleware - `taoensso.telemere/*middleware*)] + ~'__call-middleware ~(get opts :middleware `taoensso.telemere/*middleware*) + ~'__run-result ; Non-throwing (traps) + ~(when run-form + `(let [~'__t0 (enc/now-nano*)] + (with-tracing ~trace? ~'__id ~'__uid + (enc/try* + (do (RunResult. ~run-form nil (- (enc/now-nano*) ~'__t0))) + (catch :all ~'__t (RunResult. nil ~'__t (- (enc/now-nano*) ~'__t0))))))) - (dispatch-signal! - (WrappedSignal. ; Same internal value sent (conditionally) to all handlers - ~ns ~kind-form ~'__id ~level-form - - ;; Cache shared by all handlers. Covers signal `:let` eval, signal construction, - ;; middleware (possibly expensive), etc. + ~'__signal_ (delay + ;; Cache shared by all handlers. Covers signal `:let` eval, signal construction, + ;; middleware (possibly expensive), etc. ;; The unwrapped signal value actually visible to users/handler-fns, realized only ;; AFTER handler filtering. Allowed to throw on deref (handler will catch). (let [~'__signal ~signal-form] ; Can throw (if ~'__call-middleware ((sigs/get-middleware-fn ~'__call-middleware) ~'__signal) ; Can throw - (do ~'__signal)))))) + (do ~'__signal))))] + + ;; Unconditionally send same wrapped signal to all handlers. + ;; Each handler will then use wrapper for filtering, unwrapping allowed signals. + (dispatch-signal! (WrappedSignal. ~'__ns ~'__kind ~'__id ~'__level ~'__signal_)) (if ~'__run-result (do (~'__run-result)) diff --git a/src/taoensso/telemere/streams.clj b/src/taoensso/telemere/streams.clj index 1e9e210..d18452d 100644 --- a/src/taoensso/telemere/streams.clj +++ b/src/taoensso/telemere/streams.clj @@ -1,7 +1,6 @@ (ns ^:no-doc taoensso.telemere.streams "Private ns, implementation detail. Interop support: standard stream/s -> Telemere." - (:refer-clojure :exclude [binding]) (:require [taoensso.encore :as enc :refer [binding have have?]] diff --git a/src/taoensso/telemere/tools_logging.clj b/src/taoensso/telemere/tools_logging.clj index 66dec53..13221ff 100644 --- a/src/taoensso/telemere/tools_logging.clj +++ b/src/taoensso/telemere/tools_logging.clj @@ -15,7 +15,6 @@ (when-debug (println [:tools.logger/enabled? logger-ns level])) (impl/signal-allowed? {:location nil - :ns nil :kind :log :id :taoensso.telemere/tools-logging :level level})) @@ -25,11 +24,9 @@ (impl/signal! {:allow? true ; Pre-filtered by `enabled?` call :location nil - :ns nil :kind :log :id :taoensso.telemere/tools-logging :level level - :inst :auto :error throwable :msg message}) nil)) @@ -42,7 +39,6 @@ (defn ^:public tools-logging->telemere! "Configures `clojure.tools.logging` to use Telemere as its logging implementation." [] - (impl/signal! {:kind :event :level :info diff --git a/src/taoensso/telemere/utils.cljc b/src/taoensso/telemere/utils.cljc index 59b39fe..f97db8f 100644 --- a/src/taoensso/telemere/utils.cljc +++ b/src/taoensso/telemere/utils.cljc @@ -1,4 +1,4 @@ -(ns ^:no-doc taoensso.telemere.utils +(ns taoensso.telemere.utils "Misc utils useful for Telemere handlers, middleware, etc." (:refer-clojure :exclude [newline]) (:require @@ -77,7 +77,7 @@ `:error` -> `js/console.error`, etc. Defaults to `js.console.log` for unmatched signal levels. - NB: assumes that `js/console` exists, handler builders should check first!" + NB: assumes that `js/console` exists, handler constructors should check first!" [level] (case level :trace js/console.trace