mirror of
https://github.com/taoensso/telemere.git
synced 2025-12-18 10:11:10 +00:00
[nop] Misc improvements
This commit is contained in:
parent
32e8909e42
commit
248e91f982
9 changed files with 145 additions and 163 deletions
171
examples.cljc
171
examples.cljc
|
|
@ -1,33 +1,33 @@
|
||||||
(ns examples
|
(ns examples
|
||||||
"Basic Telemere usage examples that appear in the Wiki or docstrings."
|
"Basic Telemere usage examples that appear in the Wiki or docstrings."
|
||||||
(:require [taoensso.telemere :as t]))
|
(:require [taoensso.telemere :as tel]))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
|
|
||||||
;;;; README "Quick examples"
|
;;;; README "Quick examples"
|
||||||
|
|
||||||
(require '[taoensso.telemere :as t])
|
(require '[taoensso.telemere :as tel])
|
||||||
|
|
||||||
;; (Just works / no config necessary for typical use cases)
|
;; (Just works / no config necessary for typical use cases)
|
||||||
|
|
||||||
;; Without structured data
|
;; Without structured data
|
||||||
(t/log! :info "Hello world!") ; %> Basic log signal (has message)
|
(tel/log! :info "Hello world!") ; %> Basic log signal (has message)
|
||||||
(t/event! ::my-id :debug) ; %> Basic event signal (just id)
|
(tel/event! ::my-id :debug) ; %> Basic event signal (just id)
|
||||||
|
|
||||||
;; With structured data
|
;; With structured data
|
||||||
(t/log! {:level :info, :data {}} "Hello again!")
|
(tel/log! {:level :info, :data {}} "Hello again!")
|
||||||
(t/event! ::my-id {:level :debug, :data {}})
|
(tel/event! ::my-id {:level :debug, :data {}})
|
||||||
|
|
||||||
;; Trace (auto interops with OpenTelemetry)
|
;; Trace (auto interops with OpenTelemetry)
|
||||||
;; Tracks form runtime, return value, and (nested) parent tree
|
;; Tracks form runtime, return value, and (nested) parent tree
|
||||||
(t/trace! {:id ::my-id :data {}}
|
(tel/trace! {:id ::my-id :data {}}
|
||||||
(do-some-work))
|
(do-some-work))
|
||||||
|
|
||||||
;; Check resulting signal content for debug/tests
|
;; Check resulting signal content for debug/tests
|
||||||
(t/with-signal (t/event! ::my-id)) ; => {:keys [ns level id data msg_ ...]}
|
(tel/with-signal (tel/event! ::my-id)) ; => {:keys [ns level id data msg_ ...]}
|
||||||
|
|
||||||
;; Getting fancy (all costs are conditional!)
|
;; Getting fancy (all costs are conditional!)
|
||||||
(t/log!
|
(tel/log!
|
||||||
{:level :debug
|
{:level :debug
|
||||||
:sample 0.75 ; 75% sampling (noop 25% of the time)
|
:sample 0.75 ; 75% sampling (noop 25% of the time)
|
||||||
:when (my-conditional)
|
:when (my-conditional)
|
||||||
|
|
@ -49,40 +49,40 @@
|
||||||
["Something interesting happened!" formatted])
|
["Something interesting happened!" formatted])
|
||||||
|
|
||||||
;; Set minimum level
|
;; Set minimum level
|
||||||
(t/set-min-level! :warn) ; For all signals
|
(tel/set-min-level! :warn) ; For all signals
|
||||||
(t/set-min-level! :log :debug) ; For `log!` signals only
|
(tel/set-min-level! :log :debug) ; For `log!` signals only
|
||||||
|
|
||||||
;; Set namespace and id filters
|
;; Set namespace and id filters
|
||||||
(t/set-ns-filter! {:disallow "taoensso.*" :allow "taoensso.sente.*"})
|
(tel/set-ns-filter! {:disallow "taoensso.*" :allow "taoensso.sente.*"})
|
||||||
(t/set-id-filter! {:allow #{::my-particular-id "my-app/*"}})
|
(tel/set-id-filter! {:allow #{::my-particular-id "my-app/*"}})
|
||||||
|
|
||||||
;; Set minimum level for `event!` signals for particular ns pattern
|
;; Set minimum level for `event!` signals for particular ns pattern
|
||||||
(t/set-min-level! :event "taoensso.sente.*" :warn)
|
(tel/set-min-level! :event "taoensso.sente.*" :warn)
|
||||||
|
|
||||||
;; Use transforms (xfns) to filter and/or arbitrarily modify signals
|
;; Use transforms (xfns) to filter and/or arbitrarily modify signals
|
||||||
;; by signal data/content/etc.
|
;; by signal data/contentel/etc.
|
||||||
|
|
||||||
(t/set-xfn!
|
(tel/set-xfn!
|
||||||
(fn [signal]
|
(fn [signal]
|
||||||
(if (-> signal :data :skip-me?)
|
(if (-> signal :data :skip-me?)
|
||||||
nil ; Filter signal (don't handle)
|
nil ; Filter signal (don't handle)
|
||||||
(assoc signal :transformed? true))))
|
(assoc signal :transformed? true))))
|
||||||
|
|
||||||
(t/with-signal (t/event! ::my-id {:data {:skip-me? true}})) ; => nil
|
(tel/with-signal (tel/event! ::my-id {:data {:skip-me? true}})) ; => nil
|
||||||
(t/with-signal (t/event! ::my-id {:data {:skip-me? false}})) ; => {...}
|
(tel/with-signal (tel/event! ::my-id {:data {:skip-me? false}})) ; => {...}
|
||||||
|
|
||||||
;; See `t/help:filters` docstring for more filtering options
|
;; See `tel/help:filters` docstring for more filtering options
|
||||||
|
|
||||||
;;;; README "More examples"
|
;;;; README "More examples"
|
||||||
|
|
||||||
;; Add your own signal handler
|
;; Add your own signal handler
|
||||||
(t/add-handler! :my-handler
|
(tel/add-handler! :my-handler
|
||||||
(fn
|
(fn
|
||||||
([signal] (println signal))
|
([signal] (println signal))
|
||||||
([] (println "Handler has shut down"))))
|
([] (println "Handler has shut down"))))
|
||||||
|
|
||||||
;; Use `add-handler!` to set handler-level filtering and back-pressure
|
;; Use `add-handler!` to set handler-level filtering and back-pressure
|
||||||
(t/add-handler! :my-handler
|
(tel/add-handler! :my-handler
|
||||||
(fn
|
(fn
|
||||||
([signal] (println signal))
|
([signal] (println signal))
|
||||||
([] (println "Handler has shut down")))
|
([] (println "Handler has shut down")))
|
||||||
|
|
@ -93,79 +93,79 @@
|
||||||
:min-level :info
|
:min-level :info
|
||||||
:ns-filter {:disallow "taoensso.*"}
|
:ns-filter {:disallow "taoensso.*"}
|
||||||
:limit {"1 per sec" [1 1000]}
|
:limit {"1 per sec" [1 1000]}
|
||||||
;; See `t/help:handler-dispatch-options` for more
|
;; See `tel/help:handler-dispatch-options` for more
|
||||||
})
|
})
|
||||||
|
|
||||||
;; See current handlers
|
;; See current handlers
|
||||||
(t/get-handlers) ; => {<handler-id> {:keys [handler-fn handler-stats_ dispatch-opts]}}
|
(tel/get-handlers) ; => {<handler-id> {:keys [handler-fn handler-stats_ dispatch-opts]}}
|
||||||
|
|
||||||
;; Add console handler to print signals as human-readable text
|
;; Add console handler to print signals as human-readable text
|
||||||
(t/add-handler! :my-handler
|
(tel/add-handler! :my-handler
|
||||||
(t/handler:console
|
(tel/handler:console
|
||||||
{:output-fn (t/format-signal-fn {})}))
|
{:output-fn (tel/format-signal-fn {})}))
|
||||||
|
|
||||||
;; Add console handler to print signals as edn
|
;; Add console handler to print signals as edn
|
||||||
(t/add-handler! :my-handler
|
(tel/add-handler! :my-handler
|
||||||
(t/handler:console
|
(tel/handler:console
|
||||||
{:output-fn (t/pr-signal-fn {:pr-fn :edn})}))
|
{:output-fn (tel/pr-signal-fn {:pr-fn :edn})}))
|
||||||
|
|
||||||
;; Add console handler to print signals as JSON
|
;; Add console handler to print signals as JSON
|
||||||
;; Ref. <https://github.com/metosin/jsonista> (or any alt JSON lib)
|
;; Ref. <https://github.com/metosin/jsonista> (or any alt JSON lib)
|
||||||
#?(:clj (require '[jsonista.core :as jsonista]))
|
#?(:clj (require '[jsonista.core :as jsonista]))
|
||||||
(t/add-handler! :my-handler
|
(tel/add-handler! :my-handler
|
||||||
(t/handler:console
|
(tel/handler:console
|
||||||
{:output-fn
|
{:output-fn
|
||||||
#?(:cljs :json ; Use js/JSON.stringify
|
#?(:cljs :json ; Use js/JSON.stringify
|
||||||
:clj jsonista/write-value-as-string)}))
|
:clj jsonista/write-value-as-string)}))
|
||||||
|
|
||||||
;;;; Docstring examples
|
;;;; Docstring examples
|
||||||
|
|
||||||
(t/with-signal (t/event! ::my-id))
|
(tel/with-signal (tel/event! ::my-id))
|
||||||
(t/with-signal (t/event! ::my-id :warn))
|
(tel/with-signal (tel/event! ::my-id :warn))
|
||||||
(t/with-signal
|
(tel/with-signal
|
||||||
(t/event! ::my-id
|
(tel/event! ::my-id
|
||||||
{:let [x "x"] ; Available to `:data` and `:msg`
|
{:let [x "x"] ; Available to `:data` and `:msg`
|
||||||
:data {:x x}
|
:data {:x x}
|
||||||
:msg ["My msg:" x]}))
|
:msg ["My msg:" x]}))
|
||||||
|
|
||||||
(t/with-signal (t/log! "My msg"))
|
(tel/with-signal (tel/log! "My msg"))
|
||||||
(t/with-signal (t/log! :warn "My msg"))
|
(tel/with-signal (tel/log! :warn "My msg"))
|
||||||
(t/with-signal
|
(tel/with-signal
|
||||||
(t/log!
|
(tel/log!
|
||||||
{:let [x "x"] ; Available to `:data` and `:msg`
|
{:let [x "x"] ; Available to `:data` and `:msg`
|
||||||
:data {:x x}}
|
:data {:x x}}
|
||||||
["My msg:" x]))
|
["My msg:" x]))
|
||||||
|
|
||||||
(t/with-signal (throw (t/error! (ex-info "MyEx" {}))))
|
(tel/with-signal (throw (tel/error! (ex-info "MyEx" {}))))
|
||||||
(t/with-signal (throw (t/error! ::my-id (ex-info "MyEx" {}))))
|
(tel/with-signal (throw (tel/error! ::my-id (ex-info "MyEx" {}))))
|
||||||
(t/with-signal
|
(tel/with-signal
|
||||||
(throw
|
(throw
|
||||||
(t/error!
|
(tel/error!
|
||||||
{:let [x "x"] ; Available to `:data` and `:msg`
|
{:let [x "x"] ; Available to `:data` and `:msg`
|
||||||
:data {:x x}
|
:data {:x x}
|
||||||
:msg ["My msg:" x]}
|
:msg ["My msg:" x]}
|
||||||
(ex-info "MyEx" {}))))
|
(ex-info "MyEx" {}))))
|
||||||
|
|
||||||
(t/with-signal (t/trace! (+ 1 2)))
|
(tel/with-signal (tel/trace! (+ 1 2)))
|
||||||
(t/with-signal (t/trace! ::my-id (+ 1 2)))
|
(tel/with-signal (tel/trace! ::my-id (+ 1 2)))
|
||||||
(t/with-signal
|
(tel/with-signal
|
||||||
(t/trace!
|
(tel/trace!
|
||||||
{:let [x "x"] ; Available to `:data` and `:msg`
|
{:let [x "x"] ; Available to `:data` and `:msg`
|
||||||
:data {:x x}}
|
:data {:x x}}
|
||||||
(+ 1 2)))
|
(+ 1 2)))
|
||||||
|
|
||||||
(t/with-signal (t/spy! (+ 1 2)))
|
(tel/with-signal (tel/spy! (+ 1 2)))
|
||||||
(t/with-signal (t/spy! :debug (+ 1 2)))
|
(tel/with-signal (tel/spy! :debug (+ 1 2)))
|
||||||
(t/with-signal
|
(tel/with-signal
|
||||||
(t/spy!
|
(tel/spy!
|
||||||
{:let [x "x"] ; Available to `:data` and `:msg`
|
{:let [x "x"] ; Available to `:data` and `:msg`
|
||||||
:data {:x x}}
|
:data {:x x}}
|
||||||
(+ 1 2)))
|
(+ 1 2)))
|
||||||
|
|
||||||
(t/with-signal (t/catch->error! (/ 1 0)))
|
(tel/with-signal (tel/catch->error! (/ 1 0)))
|
||||||
(t/with-signal (t/catch->error! ::my-id (/ 1 0)))
|
(tel/with-signal (tel/catch->error! ::my-id (/ 1 0)))
|
||||||
(t/with-signal
|
(tel/with-signal
|
||||||
(t/catch->error!
|
(tel/catch->error!
|
||||||
{:let [x "x"] ; Available to `:data` and `:msg`
|
{:let [x "x"] ; Available to `:data` and `:msg`
|
||||||
:data {:x x}
|
:data {:x x}
|
||||||
:msg ["My msg:" x]
|
:msg ["My msg:" x]
|
||||||
|
|
@ -176,25 +176,25 @@
|
||||||
|
|
||||||
;;; Filter signals
|
;;; Filter signals
|
||||||
|
|
||||||
(t/set-min-level! :info) ; Set global minimum level
|
(tel/set-min-level! :info) ; Set global minimum level
|
||||||
(t/with-signal (t/event! ::my-id1 :info)) ; => {:keys [inst id ...]}
|
(tel/with-signal (tel/event! ::my-id1 :info)) ; => {:keys [inst id ...]}
|
||||||
(t/with-signal (t/event! ::my-id1 :debug)) ; => nil (signal not allowed)
|
(tel/with-signal (tel/event! ::my-id1 :debug)) ; => nil (signal not allowed)
|
||||||
|
|
||||||
(t/with-min-level :trace ; Override global minimum level
|
(tel/with-min-level :trace ; Override global minimum level
|
||||||
(t/with-signal (t/event! ::my-id1 :debug))) ; => {:keys [inst id ...]}
|
(tel/with-signal (tel/event! ::my-id1 :debug))) ; => {:keys [inst id ...]}
|
||||||
|
|
||||||
;; Disallow all signals in matching namespaces
|
;; Disallow all signals in matching namespaces
|
||||||
(t/set-ns-filter! {:disallow "some.nosy.namespace.*"})
|
(tel/set-ns-filter! {:disallow "some.nosy.namespace.*"})
|
||||||
|
|
||||||
;;; Configuring handlers
|
;;; Configuring handlers
|
||||||
|
|
||||||
;; Create a test signal
|
;; Create a test signal
|
||||||
(def my-signal
|
(def my-signal
|
||||||
(t/with-signal
|
(tel/with-signal
|
||||||
(t/log! {:id ::my-id, :data {:x1 :x2}} "My message")))
|
(tel/log! {:id ::my-id, :data {:x1 :x2}} "My message")))
|
||||||
|
|
||||||
;; Create console handler with default opts (writes formatted string)
|
;; Create console handler with default opts (writes formatted string)
|
||||||
(def my-handler (t/handler:console {}))
|
(def my-handler (tel/handler:console {}))
|
||||||
|
|
||||||
;; Test handler, remember it's just a (fn [signal])
|
;; Test handler, remember it's just a (fn [signal])
|
||||||
(my-handler my-signal) ; %>
|
(my-handler my-signal) ; %>
|
||||||
|
|
@ -203,8 +203,8 @@
|
||||||
|
|
||||||
;; Create console handler which writes signals as edn
|
;; Create console handler which writes signals as edn
|
||||||
(def my-handler
|
(def my-handler
|
||||||
(t/handler:console
|
(tel/handler:console
|
||||||
{:output-fn (t/pr-signal-fn {:pr-fn :edn})}))
|
{:output-fn (tel/pr-signal-fn {:pr-fn :edn})}))
|
||||||
|
|
||||||
(my-handler my-signal) ; %>
|
(my-handler my-signal) ; %>
|
||||||
;; {:inst #inst "2024-04-11T10:54:57.202869Z", :msg_ "My message", :ns "examples", ...}
|
;; {:inst #inst "2024-04-11T10:54:57.202869Z", :msg_ "My message", :ns "examples", ...}
|
||||||
|
|
@ -213,9 +213,9 @@
|
||||||
;; Ref. <https://github.com/metosin/jsonista> (or any alt JSON lib)
|
;; Ref. <https://github.com/metosin/jsonista> (or any alt JSON lib)
|
||||||
#?(:clj (require '[jsonista.core :as jsonista]))
|
#?(:clj (require '[jsonista.core :as jsonista]))
|
||||||
(def my-handler
|
(def my-handler
|
||||||
(t/handler:console
|
(tel/handler:console
|
||||||
{:output-fn
|
{:output-fn
|
||||||
(t/pr-signal-fn
|
(tel/pr-signal-fn
|
||||||
{:pr-fn
|
{:pr-fn
|
||||||
#?(:cljs :json ; Use js/JSON.stringify
|
#?(:cljs :json ; Use js/JSON.stringify
|
||||||
:clj jsonista/write-value-as-string)})}))
|
:clj jsonista/write-value-as-string)})}))
|
||||||
|
|
@ -224,19 +224,20 @@
|
||||||
;; {"inst":"2024-04-11T10:54:57.202869Z","msg_":"My message","ns":"examples", ...}
|
;; {"inst":"2024-04-11T10:54:57.202869Z","msg_":"My message","ns":"examples", ...}
|
||||||
|
|
||||||
;; Deregister the default console handler
|
;; Deregister the default console handler
|
||||||
(t/remove-handler! :default/console)
|
(tel/remove-handler! :defaultel/console)
|
||||||
|
|
||||||
;; Register our custom console handler
|
;; Register our custom console handler
|
||||||
(t/add-handler! :my-handler my-handler
|
(tel/add-handler! :my-handler my-handler
|
||||||
;; Lots of options here for filtering, etc.
|
;; Lots of options here for filtering, etc.
|
||||||
;; See `help:handler-dispatch-options` docstring!
|
;; See `help:handler-dispatch-options` docstring!
|
||||||
{})
|
{})
|
||||||
|
|
||||||
;; NB make sure to always stop handlers at the end of your
|
;; NB make sure to always stop handlers at the end of your
|
||||||
;; `-main` or shutdown procedure
|
;; `-main` or shutdown procedure
|
||||||
(t/call-on-shutdown! t/stop-handlers!)
|
(tel/call-on-shutdown!
|
||||||
|
(fn [] (tel/stop-handlers!)))
|
||||||
|
|
||||||
;; See `t/help:handlers` docstring for more
|
;; See `tel/help:handlers` docstring for more
|
||||||
|
|
||||||
;;; Writing handlers
|
;;; Writing handlers
|
||||||
|
|
||||||
|
|
@ -298,18 +299,18 @@
|
||||||
;;; Message building
|
;;; Message building
|
||||||
|
|
||||||
;; A fixed message (string arg)
|
;; A fixed message (string arg)
|
||||||
(t/log! "A fixed message") ; %> {:msg "A fixed message"}
|
(tel/log! "A fixed message") ; %> {:msg "A fixed message"}
|
||||||
|
|
||||||
;; A joined message (vector arg)
|
;; A joined message (vector arg)
|
||||||
(let [user-arg "Bob"]
|
(let [user-arg "Bob"]
|
||||||
(t/log! ["User" (str "`" user-arg "`") "just logged in!"]))
|
(tel/log! ["User" (str "`" user-arg "`") "just logged in!"]))
|
||||||
;; %> {:msg_ "User `Bob` just logged in!` ...}
|
;; %> {:msg_ "User `Bob` just logged in!` ...}
|
||||||
|
|
||||||
;; With arg prep
|
;; With arg prep
|
||||||
(let [user-arg "Bob"
|
(let [user-arg "Bob"
|
||||||
usd-balance-str "22.4821"]
|
usd-balance-str "22.4821"]
|
||||||
|
|
||||||
(t/log!
|
(tel/log!
|
||||||
{:let
|
{:let
|
||||||
[username (clojure.string/upper-case user-arg)
|
[username (clojure.string/upper-case user-arg)
|
||||||
usd-balance (parse-double usd-balance-str)]
|
usd-balance (parse-double usd-balance-str)]
|
||||||
|
|
@ -322,16 +323,16 @@
|
||||||
|
|
||||||
;; %> {:msg "User BOB has balance: $22" ...}
|
;; %> {:msg "User BOB has balance: $22" ...}
|
||||||
|
|
||||||
(t/log! (str "This message " "was built " "by `str`"))
|
(tel/log! (str "This message " "was built " "by `str`"))
|
||||||
;; %> {:msg "This message was built by `str`"}
|
;; %> {:msg "This message was built by `str`"}
|
||||||
|
|
||||||
(t/log! (enc/format "This message was built by `%s`" "format"))
|
(tel/log! (enc/format "This message was built by `%s`" "format"))
|
||||||
;; %> {:msg "This message was built by `format`"}
|
;; %> {:msg "This message was built by `format`"}
|
||||||
|
|
||||||
;;; App-level kvs
|
;;; App-level kvs
|
||||||
|
|
||||||
(t/with-signal
|
(tel/with-signal
|
||||||
(t/event! ::my-id
|
(tel/event! ::my-id
|
||||||
{:my-data-for-xfn "foo"
|
{:my-data-for-xfn "foo"
|
||||||
:my-data-for-handler "bar"}))
|
:my-data-for-handler "bar"}))
|
||||||
|
|
||||||
|
|
@ -346,20 +347,20 @@
|
||||||
|
|
||||||
;;;; Misc extra examples
|
;;;; Misc extra examples
|
||||||
|
|
||||||
(t/log! {:id ::my-id, :data {:x1 :x2}} ["My 2-part" "message"]) ; %>
|
(tel/log! {:id ::my-id, :data {:x1 :x2}} ["My 2-part" "message"]) ; %>
|
||||||
;; 2024-04-11T10:54:57.202869Z INFO LOG MyHost examples(56,1) ::my-id - My 2-part message
|
;; 2024-04-11T10:54:57.202869Z INFO LOG MyHost examples(56,1) ::my-id - My 2-part message
|
||||||
;; data: {:x1 :x2}
|
;; data: {:x1 :x2}
|
||||||
|
|
||||||
;; `:let` bindings are available to `:data` and message, but only paid
|
;; `:let` bindings are available to `:data` and message, but only paid
|
||||||
;; for when allowed by minimum level and other filtering criteria
|
;; for when allowed by minimum level and other filtering criteria
|
||||||
(t/log!
|
(tel/log!
|
||||||
{:level :info
|
{:level :info
|
||||||
:let [expensive (reduce * (range 1 12))] ; 12 factorial
|
:let [expensive (reduce * (range 1 12))] ; 12 factorial
|
||||||
:data {:my-metric expensive}}
|
:data {:my-metric expensive}}
|
||||||
["Message with metric:" expensive])
|
["Message with metric:" expensive])
|
||||||
|
|
||||||
;; With sampling 50% and 1/sec rate limiting
|
;; With sampling 50% and 1/sec rate limiting
|
||||||
(t/log!
|
(tel/log!
|
||||||
{:sample 0.5
|
{:sample 0.5
|
||||||
:limit {"1 per sec" [1 1000]}}
|
:limit {"1 per sec" [1 1000]}}
|
||||||
"This signal will be sampled and rate limited")
|
"This signal will be sampled and rate limited")
|
||||||
|
|
@ -368,8 +369,8 @@
|
||||||
;; All offer the same options, but each has an API optimized
|
;; All offer the same options, but each has an API optimized
|
||||||
;; for a particular use case:
|
;; for a particular use case:
|
||||||
|
|
||||||
(t/log! {:level :info, :id ::my-id} "Hi!") ; [msg] or [level-or-opts msg]
|
(tel/log! {:level :info, :id ::my-id} "Hi!") ; [msg] or [level-or-opts msg]
|
||||||
(t/event! ::my-id {:level :info, :msg "Hi!"}) ; [id] or [id level-or-opts]
|
(tel/event! ::my-id {:level :info, :msg "Hi!"}) ; [id] or [id level-or-opts]
|
||||||
(t/signal! {:level :info, :id ::my-id, :msg "Hi!"}) ; [opts]
|
(tel/signal! {:level :info, :id ::my-id, :msg "Hi!"}) ; [opts]
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
Signals are maps with {:keys [inst id ns level data msg_ ...]}, though they
|
Telemere signals are maps with {:keys [inst id ns level data msg_ ...]},
|
||||||
can be modified by call and/or handler transform (xfns).
|
though they can be modified by call and/or handler transform (xfns).
|
||||||
|
|
||||||
Default signal keys:
|
Default signal keys:
|
||||||
|
|
||||||
`:schema` ------ Int version of signal schema (current: 1)
|
`:schema` ------ Int version of signal schema (current: 1)
|
||||||
`:inst` -------- Platform instant [1] when signal was created, monotonicity depends on system clock
|
`:inst` -------- Platform instant [1] when signal was created, monotonicity depends on system clock
|
||||||
`:level` ------- Signal level ∈ #{<int> :trace :debug :info :warn :error :fatal :report ...}
|
`:ns` ---------- ?str namespace of signal callsite
|
||||||
|
`:coords` ------ ?[line column] of signal callsite
|
||||||
|
|
||||||
`:kind` -------- Signal ?kind ∈ #{nil :event :error :log :trace :spy :slf4j :tools-logging <app-val> ...}
|
`:kind` -------- Signal ?kind ∈ #{nil :event :error :log :trace :spy :slf4j :tools-logging <app-val> ...}
|
||||||
`:id` ---------- ?id of signal (common to all signals created at callsite, contrast with `:uid`)
|
`:level` ------- Signal level ∈ #{<int> :trace :debug :info :warn :error :fatal :report ...}
|
||||||
`:uid` --------- ?id of signal instance (unique to each signal created at callsite when tracing, contrast with `:id`)
|
`:id` ---------- Signal callsite ?id (usu. keyword) (common to all signals created at callsite, contrast with `:uid`)
|
||||||
|
`:uid` --------- Signal instance ?id (usu. string) (unique to each signal created at callsite when tracing, contrast with `:id`)
|
||||||
|
|
||||||
`:msg_` -------- Arb app-level message ?str given to signal creator - may be a delay, always use `force` to unwrap!
|
`:msg_` -------- Arb app-level message ?str given to signal creator - may be a delay, always use `force` to unwrap!
|
||||||
`:data` -------- Arb app-level data ?val (usu. a map) given to signal creator
|
`:data` -------- Arb app-level data ?val (usu. a map) given to signal creator
|
||||||
|
|
@ -23,9 +26,6 @@ Default signal keys:
|
||||||
`:root` -------- ?{:keys [id uid]} of root signal, present in nested signals when tracing
|
`:root` -------- ?{:keys [id uid]} of root signal, present in nested signals when tracing
|
||||||
`:ctx` --------- ?val of `*ctx*` (arb app-level state) when signal was created
|
`:ctx` --------- ?val of `*ctx*` (arb app-level state) when signal was created
|
||||||
|
|
||||||
`:ns` ---------- ?str namespace of signal callsite
|
|
||||||
`:coords` ------ ?[line column] of signal callsite
|
|
||||||
|
|
||||||
`:host` -------- (Clj only) {:keys [name ip]} info for network host
|
`:host` -------- (Clj only) {:keys [name ip]} info for network host
|
||||||
`:thread` ------ (Clj only) {:keys [name id group]} info for thread that created signal
|
`:thread` ------ (Clj only) {:keys [name id group]} info for thread that created signal
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ All options are available for all signal creator calls:
|
||||||
`:ns` ---------- Custom ?str namespace to override auto signal callsite info
|
`:ns` ---------- Custom ?str namespace to override auto signal callsite info
|
||||||
`:coords` ------ Custom ?[line column] to override auto signal callsite info
|
`:coords` ------ Custom ?[line column] to override auto signal callsite info
|
||||||
|
|
||||||
`:elidable?` --- Should signal be subject to compile-time elision? (Default: true)
|
`:elidable?` --- Should signal be subject to compile-time elision? (default true)
|
||||||
`:trace?` ------ Should tracing be enabled for `:run` form?
|
`:trace?` ------ Should tracing be enabled for `:run` form?
|
||||||
|
|
||||||
`:sample` ------ Sample ?rate ∈ℝ[0,1] for signal sampling (0.75 => allow 75% of signals, nil => allow all)
|
`:sample` ------ Sample ?rate ∈ℝ[0,1] for random signal sampling (0.75 => allow 75% of signals, nil => allow all)
|
||||||
`:when` -------- Arb ?form; when present, form must return truthy to allow signal
|
`:when` -------- Arb ?form; when present, form must return truthy to allow signal
|
||||||
`:limit` ------- Rate limit ?spec given to `taoensso.telemere/rate-limiter`, see its docstring for details
|
`:limit` ------- Rate limit ?spec given to `taoensso.telemere/rate-limiter`, see its docstring for details
|
||||||
`:limit-by` ---- When present, rate limits will be enforced independently for each value (any Clojure value!)
|
`:limit-by` ---- When present, rate limits will be enforced independently for each value (any Clojure value!)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
(declare ; Needed to avoid `clj-kondo` "Unresolved var" warnings
|
(declare ; Needed to avoid `clj-kondo` "Unresolved var" warnings
|
||||||
level-aliases
|
level-aliases
|
||||||
help:filters help:handler help:handler-dispatch-options
|
help:filters help:handlers help:handler-dispatch-options
|
||||||
get-filters get-min-levels get-handlers get-handlers-stats
|
get-filters get-min-levels get-handlers get-handlers-stats
|
||||||
|
|
||||||
#?(:clj without-filters)
|
#?(:clj without-filters)
|
||||||
|
|
@ -52,15 +52,18 @@
|
||||||
^:dynamic *ctx* set-ctx! #?(:clj with-ctx) #?(:clj with-ctx+)
|
^:dynamic *ctx* set-ctx! #?(:clj with-ctx) #?(:clj with-ctx+)
|
||||||
^:dynamic *xfn* set-xfn! #?(:clj with-xfn) #?(:clj with-xfn+))
|
^:dynamic *xfn* set-xfn! #?(:clj with-xfn) #?(:clj with-xfn+))
|
||||||
|
|
||||||
|
(def default-handler-dispatch-opts
|
||||||
|
"See `help:handler-dispatch-opts` for details."
|
||||||
|
(dissoc sigs/default-handler-dispatch-opts
|
||||||
|
:convey-bindings? ; We use `enc/bound-delay`
|
||||||
|
))
|
||||||
|
|
||||||
(sigs/def-api
|
(sigs/def-api
|
||||||
{:sf-arity 4
|
{:sf-arity 4
|
||||||
:ct-call-filter impl/ct-call-filter
|
:ct-call-filter impl/ct-call-filter
|
||||||
:*rt-call-filter* impl/*rt-call-filter*
|
:*rt-call-filter* impl/*rt-call-filter*
|
||||||
:*sig-handlers* impl/*sig-handlers*
|
:*sig-handlers* impl/*sig-handlers*
|
||||||
:lib-dispatch-opts
|
:lib-dispatch-opts default-handler-dispatch-opts})
|
||||||
(assoc sigs/default-handler-dispatch-opts
|
|
||||||
:convey-bindings? false ; Handled manually
|
|
||||||
)})
|
|
||||||
|
|
||||||
;;;; Aliases
|
;;;; Aliases
|
||||||
|
|
||||||
|
|
@ -74,7 +77,6 @@
|
||||||
enc/rate-limiter
|
enc/rate-limiter
|
||||||
enc/newline
|
enc/newline
|
||||||
sigs/comp-xfn
|
sigs/comp-xfn
|
||||||
sigs/default-handler-dispatch-opts
|
|
||||||
#?(:clj truss/keep-callsite)
|
#?(:clj truss/keep-callsite)
|
||||||
|
|
||||||
;; Impl
|
;; Impl
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defn ^:public handler:console
|
(defn ^:public handler:console
|
||||||
"Alpha, subject to change.
|
"Alpha, subject to change.
|
||||||
|
|
||||||
Returns a signal handler that:
|
Returns a signal handler that:
|
||||||
- Takes a Telemere signal (map).
|
- Takes a Telemere signal (map).
|
||||||
- Writes the signal as a string to specified stream.
|
- Writes the signal as a string to specified stream.
|
||||||
|
|
@ -52,7 +51,6 @@
|
||||||
:cljs
|
:cljs
|
||||||
(defn ^:public handler:console
|
(defn ^:public handler:console
|
||||||
"Alpha, subject to change.
|
"Alpha, subject to change.
|
||||||
|
|
||||||
If `js/console` exists, returns a signal handler that:
|
If `js/console` exists, returns a signal handler that:
|
||||||
- Takes a Telemere signal (map).
|
- Takes a Telemere signal (map).
|
||||||
- Writes the signal as a string to JavaScript console.
|
- Writes the signal as a string to JavaScript console.
|
||||||
|
|
@ -89,7 +87,6 @@
|
||||||
#?(:cljs
|
#?(:cljs
|
||||||
(defn ^:public handler:console-raw
|
(defn ^:public handler:console-raw
|
||||||
"Alpha, subject to change.
|
"Alpha, subject to change.
|
||||||
|
|
||||||
If `js/console` exists, returns a signal handler that:
|
If `js/console` exists, returns a signal handler that:
|
||||||
- Takes a Telemere signal (map).
|
- Takes a Telemere signal (map).
|
||||||
- Writes the raw signal to JavaScript console.
|
- Writes the raw signal to JavaScript console.
|
||||||
|
|
|
||||||
|
|
@ -564,16 +564,12 @@
|
||||||
|
|
||||||
(if elide?
|
(if elide?
|
||||||
run-form
|
run-form
|
||||||
(let [coords
|
(let [coords (get opts :coords (when (= ns-form* :auto) (truss/callsite-coords &form)))
|
||||||
(get opts :coords
|
|
||||||
(when (= ns-form* :auto)
|
|
||||||
;; Auto coords iff auto ns
|
|
||||||
(truss/callsite-coords &form)))
|
|
||||||
|
|
||||||
{inst-form :inst
|
{inst-form :inst
|
||||||
level-form :level
|
|
||||||
kind-form :kind
|
kind-form :kind
|
||||||
id-form :id} opts
|
id-form :id
|
||||||
|
level-form :level} opts
|
||||||
|
|
||||||
trace? (get opts :trace? (boolean run-form))
|
trace? (get opts :trace? (boolean run-form))
|
||||||
_
|
_
|
||||||
|
|
@ -675,7 +671,7 @@
|
||||||
|
|
||||||
;; Final unwrapped signal value visible to users/handler-fns, allow to throw
|
;; Final unwrapped signal value visible to users/handler-fns, allow to throw
|
||||||
(if-let [xfn# ~xfn-form]
|
(if-let [xfn# ~xfn-form]
|
||||||
(xfn# signal#) ; Apply call transform, can throw
|
(xfn# signal#)
|
||||||
(do signal#)))))
|
(do signal#)))))
|
||||||
|
|
||||||
;; Trade-off: avoid double `run-form` expansion
|
;; Trade-off: avoid double `run-form` expansion
|
||||||
|
|
@ -729,11 +725,11 @@
|
||||||
(truss/try*
|
(truss/try*
|
||||||
(do (RunResult. ~run-form* nil (- (enc/now-nano*) t0#)))
|
(do (RunResult. ~run-form* nil (- (enc/now-nano*) t0#)))
|
||||||
(catch :all t# (RunResult. nil t# (- (enc/now-nano*) t0#)))
|
(catch :all t# (RunResult. nil t# (- (enc/now-nano*) t0#)))
|
||||||
(finally (.close otel-scope#))))))])
|
(finally (.close otel-scope#))))))])]
|
||||||
|
|
||||||
final-form
|
`((fn [] ; iife for better IoC compatibility
|
||||||
;; Unless otherwise specified, allow errors to throw on call
|
;; Unless otherwise specified, allow errors to throw on call
|
||||||
`(let [~'__run-fn-form ~run-fn-form
|
(let [~'__run-fn-form ~run-fn-form
|
||||||
~'__kind ~kind-form
|
~'__kind ~kind-form
|
||||||
~'__ns ~ns-form
|
~'__ns ~ns-form
|
||||||
~'__id ~id-form
|
~'__id ~id-form
|
||||||
|
|
@ -756,12 +752,7 @@
|
||||||
|
|
||||||
(if ~'__run-result
|
(if ~'__run-result
|
||||||
( ~'__run-result signal#)
|
( ~'__run-result signal#)
|
||||||
true))))]
|
true))))))))))))
|
||||||
|
|
||||||
(if-let [iife-wrap? true #_cljs?]
|
|
||||||
;; Small perf hit to improve compatibility within `go` and other IOC-style bodies
|
|
||||||
`((fn [] ~final-form))
|
|
||||||
(do final-form))))))))
|
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(with-signal (signal! {:level :warn :let [x :x] :msg ["Test" "message" x] :data {:a :A :x x} :run (+ 1 2)}))
|
(with-signal (signal! {:level :warn :let [x :x] :msg ["Test" "message" x] :data {:a :A :x x} :run (+ 1 2)}))
|
||||||
|
|
|
||||||
|
|
@ -382,9 +382,9 @@
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(do
|
(do
|
||||||
(require '[taoensso.telemere :as t])
|
(require '[taoensso.telemere :as tel])
|
||||||
(def h1 (handler:open-telemetry))
|
(def h1 (handler:open-telemetry))
|
||||||
(let [{[s1 s2] :signals} (t/with-signals (t/trace! ::id1 (t/trace! ::id2 "form2")))]
|
(let [{[s1 s2] :signals} (tel/with-signals (tel/trace! ::id1 (tel/trace! ::id2 "form2")))]
|
||||||
(def s1 s1)
|
(def s1 s1)
|
||||||
(def s2 s2)))
|
(def s2 s2)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -540,17 +540,10 @@
|
||||||
(when kind (s+spc (sigs/upper-qn kind)))
|
(when kind (s+spc (sigs/upper-qn kind)))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(when-let [host (get signal :host)]
|
(when-let [hostname (enc/get-in* signal [:host :name])]
|
||||||
(when-let [hostname (get host :name)]
|
(s+spc hostname)))
|
||||||
(s+spc hostname))))
|
|
||||||
|
|
||||||
(when ns
|
|
||||||
(enc/sb-append sb " " ns)
|
|
||||||
(when-let [[line column] (get signal :coords)]
|
|
||||||
(if column
|
|
||||||
(enc/sb-append sb "[" line "," column "]")
|
|
||||||
(enc/sb-append sb "[" line "]"))))
|
|
||||||
|
|
||||||
|
(when ns (s+spc (sigs/format-callsite ns (get signal :coords))))
|
||||||
(when id (when-let [ff format-id-fn] (s+spc (ff ns id))))
|
(when id (when-let [ff format-id-fn] (s+spc (ff ns id))))
|
||||||
(enc/when-let [ff format-msg-fn
|
(enc/when-let [ff format-msg-fn
|
||||||
msg (force msg_)]
|
msg (force msg_)]
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
My plan for Telemere is to offer a **stable core of limited scope**, then to focus on making it as easy for the **community** to write additional stuff like handlers, transforms, and utils.
|
My plan for Telemere is to offer a **stable core of limited scope**, then to focus on making it as easy for the **community** to write additional stuff like handlers, transforms, and utils.
|
||||||
|
|
||||||
**PRs very welcome** to add links to this page!
|
[PRs](../wiki#contributions-welcome) **very welcome** to add links to this page!
|
||||||
|
|
||||||
If you spot issues with any linked resources, please **contact the relevant authors** to let them know! Thank you! 🙏 - [Peter](https://www.taoensso.com)
|
If you spot issues with any linked resources, please **contact the relevant authors** to let them know! Thank you! 🙏 - [Peter](https://www.taoensso.com)
|
||||||
|
|
||||||
# Learning
|
# Learning
|
||||||
|
|
||||||
Includes videos, tutorials, demo projects, etc.
|
Includes videos, tutorials, demo projects, etc.
|
||||||
[PRs](../wiki#contributions-welcome) welcome for additions!
|
|
||||||
|
|
||||||
| Type | Description |
|
| Type | Description |
|
||||||
| ------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
|
@ -20,9 +19,8 @@ Includes videos, tutorials, demo projects, etc.
|
||||||
|
|
||||||
# Handlers and tools
|
# Handlers and tools
|
||||||
|
|
||||||
Includes libraries or examples for handlers (see [Writing handlers](./4-Handlers#writing-handlers)), transforms, handler utils (e.g. formatters), tools for analyzing signals, etc. [PRs](../wiki#contributions-welcome) welcome for additions!
|
Includes libraries or examples for handlers (see [Writing handlers](./4-Handlers#writing-handlers)), transforms, handler utils (e.g. formatters), tools for analyzing signals, etc.
|
||||||
|
|
||||||
| Type | Description |
|
| Type | Description |
|
||||||
| ---- | :------------------------------------------------------------ |
|
| ---- | :------------------------------------------------------------ |
|
||||||
| - | Your link here? [PRs](../wiki#contributions-welcome) welcome! |
|
| - | Your link here? [PRs](../wiki#contributions-welcome) welcome! |
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue