2023-10-16 08:50:36 +00:00
|
|
|
(ns taoensso.telemere
|
|
|
|
|
"Structured telemetry for Clojure/Script applications.
|
|
|
|
|
|
|
|
|
|
See the GitHub page (esp. Wiki) for info on motivation and design:
|
|
|
|
|
<https://www.taoensso.com/telemere>"
|
|
|
|
|
|
|
|
|
|
{:author "Peter Taoussanis (@ptaoussanis)"}
|
2024-03-16 15:22:01 +00:00
|
|
|
(:refer-clojure :exclude [binding newline])
|
2023-10-16 08:50:36 +00:00
|
|
|
(:require
|
2024-03-16 15:22:01 +00:00
|
|
|
[taoensso.encore :as enc :refer [binding have have?]]
|
2024-03-15 15:02:38 +00:00
|
|
|
[taoensso.encore.signals :as sigs]
|
|
|
|
|
[taoensso.telemere.impl :as impl]
|
2024-03-21 11:36:55 +00:00
|
|
|
[taoensso.telemere.utils :as utils]
|
2024-03-15 15:02:38 +00:00
|
|
|
[taoensso.telemere.handlers :as handlers]
|
2024-03-18 17:12:07 +00:00
|
|
|
#?(:clj [taoensso.telemere.streams :as streams]))
|
|
|
|
|
|
|
|
|
|
#?(:cljs
|
|
|
|
|
(:require-macros
|
|
|
|
|
[taoensso.telemere :refer
|
|
|
|
|
[set-ctx! with-ctx with-ctx+
|
|
|
|
|
set-middleware! with-middleware
|
|
|
|
|
|
2024-03-29 11:30:02 +00:00
|
|
|
with-signal with-signals
|
2024-03-18 17:12:07 +00:00
|
|
|
signal! event! log! trace! spy! catch->error!
|
|
|
|
|
|
|
|
|
|
;; Via `sigs/def-api`
|
|
|
|
|
without-filters with-kind-filter with-ns-filter with-id-filter
|
|
|
|
|
with-min-level with-handler with-handler+]])))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
|
|
|
|
(comment
|
|
|
|
|
(remove-ns 'taoensso.telemere)
|
|
|
|
|
(:api (enc/interns-overview)))
|
|
|
|
|
|
2024-03-16 15:19:23 +00:00
|
|
|
(enc/assert-min-encore-version [3 98 0])
|
2023-10-16 08:50:36 +00:00
|
|
|
|
|
|
|
|
;;;; TODO
|
2024-03-14 10:18:29 +00:00
|
|
|
;; - Review, TODOs, missing docstrings
|
|
|
|
|
;; - Reading plan, wiki docs, explainer/demo video
|
2024-03-13 11:13:27 +00:00
|
|
|
;;
|
|
|
|
|
;; - First OpenTelemetry tools
|
|
|
|
|
;; - Update Tufte (signal API, config API, signal keys, etc.)
|
|
|
|
|
;; - Update Timbre (signal API, config API, signal keys, backport improvements)
|
2023-10-16 08:50:36 +00:00
|
|
|
|
|
|
|
|
;;;; Shared signal API
|
|
|
|
|
|
|
|
|
|
(sigs/def-api
|
|
|
|
|
{:purpose "signal"
|
|
|
|
|
:sf-arity 4
|
|
|
|
|
:*sig-handlers* impl/*sig-handlers*
|
|
|
|
|
:*rt-sig-filter* impl/*rt-sig-filter*})
|
|
|
|
|
|
|
|
|
|
(comment
|
|
|
|
|
[level-aliases]
|
2024-03-11 08:49:56 +00:00
|
|
|
[help:handlers get-handlers add-handler! remove-handler! with-handler with-handler+]
|
|
|
|
|
[help:filtering get-filters get-min-level
|
2023-10-16 08:50:36 +00:00
|
|
|
set-kind-filter! set-ns-filter! set-id-filter! set-min-level!
|
|
|
|
|
with-kind-filter with-ns-filter with-id-filter with-min-level])
|
|
|
|
|
|
|
|
|
|
;;;; Aliases
|
|
|
|
|
|
|
|
|
|
(enc/defaliases
|
|
|
|
|
#?(:clj enc/set-var-root!)
|
|
|
|
|
#?(:clj enc/update-var-root!)
|
|
|
|
|
#?(:clj enc/get-env)
|
|
|
|
|
enc/chance
|
|
|
|
|
enc/rate-limiter
|
|
|
|
|
enc/newline
|
2024-03-06 10:54:51 +00:00
|
|
|
|
2023-10-16 08:50:36 +00:00
|
|
|
impl/msg-splice
|
|
|
|
|
impl/msg-skip
|
2024-03-13 10:54:23 +00:00
|
|
|
#?(:clj impl/with-signal)
|
2024-03-29 11:30:02 +00:00
|
|
|
#?(:clj impl/with-signals)
|
2023-10-16 08:50:36 +00:00
|
|
|
#?(:clj impl/signal!))
|
|
|
|
|
|
2024-03-11 08:49:56 +00:00
|
|
|
;;;; Signal help
|
|
|
|
|
|
|
|
|
|
(comment help:filters help:handlers) ; Via Encore
|
|
|
|
|
|
|
|
|
|
(impl/defhelp help:signal-handling :signal-handling)
|
|
|
|
|
(impl/defhelp help:signal-content :signal-content)
|
|
|
|
|
(impl/defhelp help:signal-options :signal-options)
|
|
|
|
|
|
2023-10-16 08:50:36 +00:00
|
|
|
;;;; Context
|
|
|
|
|
|
|
|
|
|
(enc/defonce default-ctx
|
|
|
|
|
"Advanced feature. Default root (base) value of `*ctx*` var, controlled by:
|
|
|
|
|
(get-env {:as :edn} :taoensso.telemere/default-ctx<.platform><.edn>)
|
|
|
|
|
|
|
|
|
|
See `get-env` for details."
|
|
|
|
|
(enc/get-env {:as :edn} :taoensso.telemere/default-ctx<.platform><.edn>))
|
|
|
|
|
|
|
|
|
|
(enc/def* ^:dynamic *ctx*
|
2024-03-11 08:49:56 +00:00
|
|
|
"Dynamic context: arbitrary user-level state attached as `:ctx` to all signals.
|
2023-10-16 08:50:36 +00:00
|
|
|
Value may be any type, but is usually nil or a map.
|
|
|
|
|
|
|
|
|
|
Re/bind dynamic value using `with-ctx`, `with-ctx+`, or `binding`.
|
|
|
|
|
Modify root (base) value using `set-ctx!`.
|
|
|
|
|
Default root (base) value is `default-ctx`.
|
|
|
|
|
|
|
|
|
|
Note that as with all dynamic Clojure vars, \"binding conveyance\" applies
|
|
|
|
|
when using futures, agents, etc.
|
|
|
|
|
|
|
|
|
|
Tips:
|
|
|
|
|
- Value may be (or may contain) an atom if you want mutable semantics
|
|
|
|
|
- Value may be of form {<scope-id> <data>} for custom scoping, etc."
|
|
|
|
|
default-ctx)
|
|
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(defmacro set-ctx!
|
|
|
|
|
"Set `*ctx*` var's root (base) value. See `*ctx*` for details."
|
|
|
|
|
[root-val] `(enc/set-var-root! *ctx* ~root-val)))
|
|
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(defmacro with-ctx
|
|
|
|
|
"Evaluates given form with given `*ctx*` value. See `*ctx*` for details."
|
|
|
|
|
[init-val form] `(binding [*ctx* ~init-val] ~form)))
|
|
|
|
|
|
|
|
|
|
(comment (with-ctx "my-ctx" *ctx*))
|
|
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(defmacro with-ctx+
|
|
|
|
|
"Evaluates given form with updated `*ctx*` value.
|
|
|
|
|
|
|
|
|
|
`update-map-or-fn` may be:
|
|
|
|
|
- A map to merge with current `*ctx*` value, or
|
|
|
|
|
- A unary fn to apply to current `*ctx*` value
|
|
|
|
|
|
|
|
|
|
See `*ctx*` for details."
|
|
|
|
|
[update-map-or-fn form]
|
|
|
|
|
`(binding [*ctx* (impl/update-ctx *ctx* ~update-map-or-fn)]
|
|
|
|
|
~form)))
|
|
|
|
|
|
|
|
|
|
(comment (with-ctx {:a :A1 :b :B1} (with-ctx+ {:a :A2} *ctx*)))
|
|
|
|
|
|
|
|
|
|
;;;; Middleware
|
|
|
|
|
|
|
|
|
|
(enc/defonce ^:dynamic *middleware*
|
|
|
|
|
"Optional vector of unary middleware fns to apply (sequentially/left-to-right)
|
|
|
|
|
to each signal before passing it to handlers. If any middleware fn returns nil,
|
|
|
|
|
aborts immediately without calling handlers.
|
|
|
|
|
|
|
|
|
|
Useful for transforming each signal before handling.
|
|
|
|
|
|
|
|
|
|
Re/bind dynamic value using `with-middleware`, `binding`.
|
|
|
|
|
Modify root (base) value using `set-middleware!`."
|
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(defmacro set-middleware!
|
|
|
|
|
"Set `*middleware*` var's root (base) value. See `*middleware*` for details."
|
|
|
|
|
[root-val] `(enc/set-var-root! *middleware* ~root-val)))
|
|
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(defmacro with-middleware
|
|
|
|
|
"Evaluates given form with given `*middleware*` value.
|
|
|
|
|
See `*middleware*` for details."
|
|
|
|
|
[init-val form] `(binding [*middleware* ~init-val] ~form)))
|
|
|
|
|
|
|
|
|
|
;;;; Encore integration
|
|
|
|
|
|
|
|
|
|
(do
|
|
|
|
|
(enc/set-var-root! sigs/*default-handler-error-fn*
|
|
|
|
|
(fn [{:keys [error] :as m}]
|
|
|
|
|
(impl/signal!
|
2024-03-06 18:02:58 +00:00
|
|
|
{:kind :error
|
|
|
|
|
:level :error
|
2023-10-16 08:50:36 +00:00
|
|
|
:error error
|
|
|
|
|
:location {:ns "taoensso.encore.signals"}
|
|
|
|
|
:id :taoensso.encore.signals/handler-error
|
2024-03-06 18:02:58 +00:00
|
|
|
:msg "Error executing wrapped handler fn"
|
2023-10-16 08:50:36 +00:00
|
|
|
:data (dissoc m :error)})))
|
|
|
|
|
|
|
|
|
|
(enc/set-var-root! sigs/*default-handler-backp-fn*
|
|
|
|
|
(fn [data]
|
|
|
|
|
(impl/signal!
|
2024-03-06 18:02:58 +00:00
|
|
|
{:kind :event
|
|
|
|
|
:level :warn
|
2023-10-16 08:50:36 +00:00
|
|
|
:location {:ns "taoensso.encore.signals"}
|
|
|
|
|
:id :taoensso.encore.signals/handler-back-pressure
|
2024-03-06 18:02:58 +00:00
|
|
|
:msg "Back pressure on wrapped handler fn"
|
2023-10-16 08:50:36 +00:00
|
|
|
:data data}))))
|
|
|
|
|
|
|
|
|
|
;;;; Common signals
|
2024-03-11 08:49:56 +00:00
|
|
|
;; - signal! [ opts] ; => allowed? / run result (value or throw)
|
|
|
|
|
;; - event! [id ] [id level-or-opts] ; id + ?level => allowed? ; Sole signal with descending main arg!
|
|
|
|
|
;; - log! [msg ] [level-or-opts msg] ; msg + ?level => allowed?
|
|
|
|
|
;; - error! [error] [id-or-opts error] ; error + ?id => given error
|
|
|
|
|
;; - trace! [form ] [id-or-opts form] ; run + ?id => run result (value or throw)
|
|
|
|
|
;; - spy! [form ] [level-or-opts form] ; run + ?level => run result (value or throw)
|
|
|
|
|
;; - catch->error! [form ] [id-or-opts form] ; run + ?id => run value or ?return
|
|
|
|
|
;; - uncaught->error! [ ] [id-or-opts ] ; ?id => nil
|
2023-10-16 08:50:36 +00:00
|
|
|
|
|
|
|
|
#?(:clj
|
2024-03-11 08:49:56 +00:00
|
|
|
(defmacro event!
|
|
|
|
|
"[id] [id level-or-opts] => allowed?"
|
|
|
|
|
{:doc (impl/signal-docstring :event!)
|
|
|
|
|
:arglists (impl/signal-arglists :event!)}
|
2023-10-16 08:50:36 +00:00
|
|
|
[& args]
|
2024-03-11 08:49:56 +00:00
|
|
|
(let [opts (impl/signal-opts `event! {:kind :event, :level :info} :id :level :dsc args)]
|
2023-10-16 08:50:36 +00:00
|
|
|
(enc/keep-callsite `(impl/signal! ~opts)))))
|
|
|
|
|
|
2024-03-13 11:13:27 +00:00
|
|
|
(comment (with-signal (event! ::my-id :info)))
|
2024-03-11 08:49:56 +00:00
|
|
|
|
2023-10-16 08:50:36 +00:00
|
|
|
#?(:clj
|
2024-03-11 08:49:56 +00:00
|
|
|
(defmacro log!
|
|
|
|
|
"[msg] [level-or-opts msg] => allowed?"
|
|
|
|
|
{:doc (impl/signal-docstring :log!)
|
|
|
|
|
:arglists (impl/signal-arglists :log!)}
|
2023-10-16 08:50:36 +00:00
|
|
|
[& args]
|
2024-03-11 08:49:56 +00:00
|
|
|
(let [opts (impl/signal-opts `log! {:kind :log, :level :info} :msg :level :asc args)]
|
2023-10-16 08:50:36 +00:00
|
|
|
(enc/keep-callsite `(impl/signal! ~opts)))))
|
|
|
|
|
|
2024-03-13 11:13:27 +00:00
|
|
|
(comment (with-signal (log! :info "My msg")))
|
2024-03-11 08:49:56 +00:00
|
|
|
|
2023-10-16 08:50:36 +00:00
|
|
|
#?(:clj
|
|
|
|
|
(defmacro error!
|
2024-03-11 08:49:56 +00:00
|
|
|
"[error] [error id-or-opts] => error"
|
|
|
|
|
{:doc (impl/signal-docstring :error!)
|
|
|
|
|
:arglists (impl/signal-arglists :error!)}
|
2023-10-16 08:50:36 +00:00
|
|
|
[& args]
|
2024-03-11 08:49:56 +00:00
|
|
|
(let [opts (impl/signal-opts `error! {:kind :error, :level :error} :error :id :asc args)
|
2023-10-16 08:50:36 +00:00
|
|
|
error-form (get opts :error)]
|
2024-03-11 08:49:56 +00:00
|
|
|
|
2023-10-16 08:50:36 +00:00
|
|
|
(enc/keep-callsite
|
|
|
|
|
`(let [~'__error ~error-form]
|
|
|
|
|
(impl/signal! ~(assoc opts :error '__error))
|
2024-03-11 08:49:56 +00:00
|
|
|
~'__error ; Unconditional!
|
|
|
|
|
)))))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-13 11:13:27 +00:00
|
|
|
(comment (with-signal (throw (error! ::my-id (ex-info "MyEx" {})))))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(defmacro catch->error!
|
2024-03-11 08:49:56 +00:00
|
|
|
"[form] [id-or-opts form] => run value or ?catch-val"
|
|
|
|
|
{:doc (impl/signal-docstring :catch-to-error!)
|
|
|
|
|
:arglists (impl/signal-arglists :catch->error!)}
|
2023-10-16 08:50:36 +00:00
|
|
|
[& args]
|
2024-03-11 08:49:56 +00:00
|
|
|
(let [opts (impl/signal-opts `catch->error! {:kind :error, :level :error} ::__form :id :asc args)
|
2024-03-29 12:58:19 +00:00
|
|
|
rethrow? (if (contains? opts :catch-val) false (get opts :rethrow? true))
|
2023-10-16 08:50:36 +00:00
|
|
|
catch-val (get opts :catch-val)
|
2024-03-13 11:13:27 +00:00
|
|
|
catch-sym (get opts :catch-sym '__caught-error) ; Undocumented
|
2023-10-16 08:50:36 +00:00
|
|
|
form (get opts ::__form)
|
2024-03-13 11:13:27 +00:00
|
|
|
opts (dissoc opts ::__form :catch-val :catch-sym :rethrow?)]
|
2023-10-16 08:50:36 +00:00
|
|
|
|
|
|
|
|
(enc/keep-callsite
|
|
|
|
|
`(enc/try* ~form
|
2024-03-29 12:58:19 +00:00
|
|
|
(catch :all ~catch-sym
|
2024-03-13 11:13:27 +00:00
|
|
|
(impl/signal! ~(assoc opts :error catch-sym))
|
|
|
|
|
(if ~rethrow? (throw ~catch-sym) ~catch-val)))))))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-11 08:49:56 +00:00
|
|
|
(comment
|
2024-03-13 11:13:27 +00:00
|
|
|
(with-signal (catch->error! ::my-id (/ 1 0)))
|
|
|
|
|
(with-signal (catch->error! { :msg_ ["Error:" __caught-error]} (/ 1 0)))
|
|
|
|
|
(with-signal (catch->error! {:catch-sym my-err :msg_ ["Error:" my-err]} (/ 1 0))))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-29 12:58:19 +00:00
|
|
|
#?(:clj
|
|
|
|
|
(defmacro trace!
|
|
|
|
|
"[form] [id-or-opts form] => run result (value or throw)"
|
|
|
|
|
{:doc (impl/signal-docstring :trace!)
|
|
|
|
|
:arglists (impl/signal-arglists :trace!)}
|
|
|
|
|
[& args]
|
|
|
|
|
(let [opts
|
|
|
|
|
(impl/signal-opts `trace!
|
|
|
|
|
{:location (enc/get-source &form &env) ; For catch-opts
|
|
|
|
|
:kind :trace, :level :info, :msg `impl/default-trace-msg}
|
|
|
|
|
:run :id :asc args)
|
|
|
|
|
|
|
|
|
|
;; :catch->error <id-or-opts> currently undocumented
|
|
|
|
|
[opts catch-opts] (impl/signal-catch-opts opts)]
|
|
|
|
|
|
|
|
|
|
(if catch-opts
|
|
|
|
|
(enc/keep-callsite `(catch->error! ~catch-opts (impl/signal! ~opts)))
|
|
|
|
|
(enc/keep-callsite `(impl/signal! ~opts))))))
|
|
|
|
|
|
|
|
|
|
(comment
|
|
|
|
|
(with-signal (trace! ::my-id (+ 1 2)))
|
|
|
|
|
(let [[_ [s1 s2]]
|
|
|
|
|
(with-signals
|
|
|
|
|
(trace! {:id :id1, :catch->error :id2}
|
|
|
|
|
(throw (ex-info "Ex1" {}))))]
|
|
|
|
|
[s2]))
|
|
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(defmacro spy!
|
|
|
|
|
"[form] [level-or-opts form] => run result (value or throw)"
|
|
|
|
|
{:doc (impl/signal-docstring :spy!)
|
|
|
|
|
:arglists (impl/signal-arglists :spy!)}
|
|
|
|
|
[& args]
|
|
|
|
|
(let [opts
|
|
|
|
|
(impl/signal-opts `spy!
|
|
|
|
|
{:location (enc/get-source &form &env) ; For catch-opts
|
|
|
|
|
:kind :spy, :level :info, :msg `impl/default-trace-msg}
|
|
|
|
|
:run :level :asc args)
|
|
|
|
|
|
|
|
|
|
;; :catch->error <id-or-opts> currently undocumented
|
|
|
|
|
[opts catch-opts] (impl/signal-catch-opts opts)]
|
|
|
|
|
|
|
|
|
|
(if catch-opts
|
|
|
|
|
(enc/keep-callsite `(catch->error! ~catch-opts (impl/signal! ~opts)))
|
|
|
|
|
(enc/keep-callsite `(impl/signal! ~opts))))))
|
|
|
|
|
|
|
|
|
|
(comment (with-signal :force (spy! :info (+ 1 2))))
|
|
|
|
|
|
2023-10-16 08:50:36 +00:00
|
|
|
#?(:clj
|
|
|
|
|
(defmacro uncaught->error!
|
2024-03-11 08:49:56 +00:00
|
|
|
"Uses `uncaught->handler!` so that `error!` will be called for
|
|
|
|
|
uncaught JVM errors.
|
|
|
|
|
|
|
|
|
|
See `uncaught->handler!` and `error!` for details."
|
2023-10-16 08:50:36 +00:00
|
|
|
{:arglists (impl/signal-arglists :uncaught->error!)}
|
2024-03-11 08:49:56 +00:00
|
|
|
[& args]
|
|
|
|
|
(let [msg-form ["Uncaught Throwable on thread: " `(.getName ~(with-meta '__thread {:tag 'java.lang.Thread}))]
|
|
|
|
|
opts
|
|
|
|
|
(impl/signal-opts `uncaught->error!
|
|
|
|
|
{:kind :error, :level :error, :msg msg-form}
|
|
|
|
|
:error :id :dsc (into ['__throwable] args))]
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-11 08:49:56 +00:00
|
|
|
(enc/keep-callsite
|
|
|
|
|
`(uncaught->handler!
|
|
|
|
|
(fn [~'__thread ~'__throwable]
|
|
|
|
|
(impl/signal! ~opts)))))))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-13 11:13:27 +00:00
|
|
|
(comment (macroexpand '(uncaught->error! ::my-id)))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(defn uncaught->handler!
|
|
|
|
|
"Sets JVM's global `DefaultUncaughtExceptionHandler` to given
|
|
|
|
|
(fn handler [`<java.lang.Thread>` `<java.lang.Throwable>`]).
|
2024-03-11 08:49:56 +00:00
|
|
|
|
2023-10-16 08:50:36 +00:00
|
|
|
See also `uncaught->error!`."
|
|
|
|
|
[handler]
|
|
|
|
|
(Thread/setDefaultUncaughtExceptionHandler
|
|
|
|
|
(reify Thread$UncaughtExceptionHandler
|
|
|
|
|
(uncaughtException [_ thread throwable]
|
2024-03-11 08:49:56 +00:00
|
|
|
(handler thread throwable))))
|
|
|
|
|
nil))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-03 11:24:44 +00:00
|
|
|
;;;; Interop
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-05 11:49:08 +00:00
|
|
|
(enc/defaliases impl/check-interop)
|
2023-10-16 08:50:36 +00:00
|
|
|
#?(:clj
|
2024-03-05 11:49:08 +00:00
|
|
|
(enc/defaliases
|
|
|
|
|
streams/with-out->telemere
|
|
|
|
|
streams/with-err->telemere
|
|
|
|
|
streams/with-streams->telemere
|
|
|
|
|
streams/streams->telemere!
|
|
|
|
|
streams/streams->reset!))
|
|
|
|
|
|
|
|
|
|
#?(: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!))))
|
|
|
|
|
|
|
|
|
|
#?(:clj
|
|
|
|
|
(enc/compile-when
|
|
|
|
|
(and org.slf4j.Logger com.taoensso.telemere.slf4j.TelemereLogger)
|
2024-03-06 18:02:58 +00:00
|
|
|
|
|
|
|
|
(impl/signal!
|
|
|
|
|
{:kind :event
|
|
|
|
|
:level :info
|
|
|
|
|
:id :taoensso.telemere/slf4j->telemere!
|
|
|
|
|
:msg "Enabling interop: SLF4J -> Telemere"})
|
|
|
|
|
|
2024-03-05 11:49:08 +00:00
|
|
|
(require '[taoensso.telemere.slf4j :as slf4j])))
|
|
|
|
|
|
|
|
|
|
(comment (check-interop))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-15 15:02:38 +00:00
|
|
|
;;;; Handlers
|
|
|
|
|
|
2024-04-01 08:38:49 +00:00
|
|
|
(enc/defaliases
|
|
|
|
|
#?(:default handlers/console-handler)
|
|
|
|
|
#?(:cljs handlers/raw-console-handler)
|
|
|
|
|
#?(:clj handlers/file-handler))
|
2024-03-21 11:36:55 +00:00
|
|
|
|
2024-03-28 15:33:58 +00:00
|
|
|
(defonce ^:no-doc __add-default-handlers
|
|
|
|
|
(do
|
|
|
|
|
(add-handler! :default-console-handler
|
2024-04-04 14:12:44 +00:00
|
|
|
(console-handler))
|
2024-03-28 15:33:58 +00:00
|
|
|
nil))
|
2024-03-15 15:02:38 +00:00
|
|
|
|
2023-10-16 08:50:36 +00:00
|
|
|
;;;; Flow benchmarks
|
|
|
|
|
|
|
|
|
|
(comment
|
|
|
|
|
{:last-updated "2024-02-12"
|
|
|
|
|
:system "2020 Macbook Pro M1, 16 GB memory"
|
|
|
|
|
:clojure-version "1.11.1"
|
|
|
|
|
:java-version "OpenJDK 21"}
|
|
|
|
|
|
2024-03-21 11:36:55 +00:00
|
|
|
[(binding [impl/*sig-handlers* nil]
|
|
|
|
|
(enc/qb 1e6 ; [10.4 17.06 195.42 200.34]
|
2023-10-16 08:50:36 +00:00
|
|
|
(signal! {:level :info, :run nil, :elide? true})
|
|
|
|
|
(signal! {:level :info, :run nil, :allow? false})
|
|
|
|
|
(signal! {:level :info, :run nil, :allow? true })
|
2024-03-21 11:36:55 +00:00
|
|
|
(signal! {:level :info, :run nil})))
|
2023-10-16 08:50:36 +00:00
|
|
|
|
2024-03-21 11:36:55 +00:00
|
|
|
(binding [impl/*sig-handlers* nil]
|
2024-03-16 15:22:01 +00:00
|
|
|
(enc/qb 1e6 ; [8.1 15.35 647.82 279.67 682.1]
|
2023-10-16 08:50:36 +00:00
|
|
|
(signal! {:level :info, :run "run", :elide? true})
|
|
|
|
|
(signal! {:level :info, :run "run", :allow? false})
|
|
|
|
|
(signal! {:level :info, :run "run", :allow? true })
|
|
|
|
|
(signal! {:level :info, :run "run", :trace? false})
|
2024-03-21 11:36:55 +00:00
|
|
|
(signal! {:level :info, :run "run"})))
|
2024-03-05 10:14:01 +00:00
|
|
|
|
2024-03-21 11:36:55 +00:00
|
|
|
;; For README "performance" table
|
|
|
|
|
(binding [impl/*sig-handlers* nil]
|
2024-03-16 15:22:01 +00:00
|
|
|
(enc/qb [8 1e6] ; [9.23 197.2 277.55 649.32]
|
2024-03-05 10:14:01 +00:00
|
|
|
(signal! {:level :info, :elide? true})
|
|
|
|
|
(signal! {:level :info})
|
|
|
|
|
(signal! {:level :info, :run "run", :trace? false})
|
2024-03-21 11:36:55 +00:00
|
|
|
(signal! {:level :info, :run "run"})))])
|
|
|
|
|
|
|
|
|
|
;;;;
|
|
|
|
|
|
|
|
|
|
(comment
|
2024-04-04 14:12:44 +00:00
|
|
|
(with-handler :hid1 (handlers/console-handler) {} (log! "Message"))
|
2024-03-21 11:36:55 +00:00
|
|
|
|
|
|
|
|
(let [sig
|
|
|
|
|
(with-signal
|
|
|
|
|
(event! ::ev-id
|
|
|
|
|
{:data {:a :A :b :b}
|
|
|
|
|
:error
|
|
|
|
|
(ex-info "Ex2" {:b :B}
|
|
|
|
|
(ex-info "Ex1" {:a :A}))}))]
|
|
|
|
|
|
2024-04-01 08:38:49 +00:00
|
|
|
(do (let [hf (handlers/file-handler)] (hf sig) (hf)))
|
|
|
|
|
(do (let [hf (handlers/console-handler)] (hf sig) (hf)))
|
|
|
|
|
#?(:cljs (let [hf (handlers/raw-console-handler)] (hf sig) (hf)))))
|
2024-03-21 11:36:55 +00:00
|
|
|
|
|
|
|
|
;;;;
|