mirror of
https://github.com/taoensso/telemere.git
synced 2025-12-17 01:51:10 +00:00
1019 lines
No EOL
80 KiB
HTML
1019 lines
No EOL
80 KiB
HTML
<!DOCTYPE html PUBLIC ""
|
||
"">
|
||
<html><head><meta charset="UTF-8" /><title>taoensso.telemere documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Telemere</span> <span class="project-version">1.0.0-beta24</span></span></a></h1><div id="langs"><div class="lang"><a href="index.clj.html">clj</a></div><div class="lang current">cljs</div></div></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>taoensso</span></div></div></li><li class="depth-2 current"><a href="taoensso.telemere.cljs.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>telemere</span></div></a></li><li class="depth-3 branch"><a href="taoensso.telemere.timbre.cljs.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>timbre</span></div></a></li><li class="depth-3"><a href="taoensso.telemere.utils.cljs.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-*ctx*"><div class="inner"><span>*ctx*</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-*middleware*"><div class="inner"><span>*middleware*</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-*uid-fn*"><div class="inner"><span>*uid-fn*</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-add-handler.21"><div class="inner"><span>add-handler!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-catch-.3Eerror.21"><div class="inner"><span>catch->error!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-chance"><div class="inner"><span>chance</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-clean-signal-fn"><div class="inner"><span>clean-signal-fn</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-comp-middleware"><div class="inner"><span>comp-middleware</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-default-handler-dispatch-opts"><div class="inner"><span>default-handler-dispatch-opts</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-error.21"><div class="inner"><span>error!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-error-signal.3F"><div class="inner"><span>error-signal?</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-event.21"><div class="inner"><span>event!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-format-signal-fn"><div class="inner"><span>format-signal-fn</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-get-env"><div class="inner"><span>get-env</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-get-filters"><div class="inner"><span>get-filters</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-get-handlers"><div class="inner"><span>get-handlers</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-get-handlers-stats"><div class="inner"><span>get-handlers-stats</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-get-min-levels"><div class="inner"><span>get-min-levels</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-handler.3Aconsole"><div class="inner"><span>handler:console</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-handler.3Aconsole-raw"><div class="inner"><span>handler:console-raw</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-help.3Aenvironmental-config"><div class="inner"><span>help:environmental-config</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-help.3Afilters"><div class="inner"><span>help:filters</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-help.3Ahandler-dispatch-options"><div class="inner"><span>help:handler-dispatch-options</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-help.3Ahandlers"><div class="inner"><span>help:handlers</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-help.3Asignal-content"><div class="inner"><span>help:signal-content</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-help.3Asignal-creators"><div class="inner"><span>help:signal-creators</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-help.3Asignal-options"><div class="inner"><span>help:signal-options</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-level-aliases"><div class="inner"><span>level-aliases</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-log.21"><div class="inner"><span>log!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-msg-skip"><div class="inner"><span>msg-skip</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-msg-splice"><div class="inner"><span>msg-splice</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-newline"><div class="inner"><span>newline</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-pr-signal-fn"><div class="inner"><span>pr-signal-fn</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-rate-limiter"><div class="inner"><span>rate-limiter</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-remove-handler.21"><div class="inner"><span>remove-handler!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-set-ctx.21"><div class="inner"><span>set-ctx!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-set-id-filter.21"><div class="inner"><span>set-id-filter!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-set-kind-filter.21"><div class="inner"><span>set-kind-filter!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-set-middleware.21"><div class="inner"><span>set-middleware!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-set-min-level.21"><div class="inner"><span>set-min-level!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-set-ns-filter.21"><div class="inner"><span>set-ns-filter!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-set-var-root.21"><div class="inner"><span>set-var-root!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-signal.21"><div class="inner"><span>signal!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-signal-allowed.3F"><div class="inner"><span>signal-allowed?</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-spy.21"><div class="inner"><span>spy!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-stop-handlers.21"><div class="inner"><span>stop-handlers!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-trace.21"><div class="inner"><span>trace!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-uncaught-.3Eerror.21"><div class="inner"><span>uncaught->error!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-update-var-root.21"><div class="inner"><span>update-var-root!</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-ctx"><div class="inner"><span>with-ctx</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-ctx.2B"><div class="inner"><span>with-ctx+</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-err-.3Etelemere"><div class="inner"><span>with-err->telemere</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-handler"><div class="inner"><span>with-handler</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-handler.2B"><div class="inner"><span>with-handler+</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-id-filter"><div class="inner"><span>with-id-filter</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-kind-filter"><div class="inner"><span>with-kind-filter</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-middleware"><div class="inner"><span>with-middleware</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-min-level"><div class="inner"><span>with-min-level</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-ns-filter"><div class="inner"><span>with-ns-filter</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-out-.3Etelemere"><div class="inner"><span>with-out->telemere</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-signal"><div class="inner"><span>with-signal</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-signals"><div class="inner"><span>with-signals</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-with-streams-.3Etelemere"><div class="inner"><span>with-streams->telemere</span></div></a></li><li class="depth-1"><a href="taoensso.telemere.cljs.html#var-without-filters"><div class="inner"><span>without-filters</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">taoensso.telemere</h1><div class="doc"><pre class="plaintext">Structured telemetry for Clojure/Script applications.
|
||
|
||
See the GitHub page (esp. Wiki) for info on motivation and design:
|
||
<<a href="https://www.taoensso.com/telemere">https://www.taoensso.com/telemere</a>></pre></div><div class="public anchor" id="var-*ctx*"><h3>*ctx*</h3><h4 class="dynamic">dynamic</h4><h4 class="lang"><a href="taoensso.telemere.html#var-*ctx*">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Optional context (state) attached to all signals.
|
||
Value may be any type, but is usually nil or a map. Default (root) value is nil.
|
||
|
||
Useful for dynamically attaching arbitrary app-level state to signals.
|
||
|
||
Re/bind dynamic value using `with-ctx`, `with-ctx+`, or `binding`.
|
||
Modify root (default) value using `set-ctx!`.
|
||
|
||
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.
|
||
- Use `get-env` to set default (root) value based on environmental config.</pre></div></div><div class="public anchor" id="var-*middleware*"><h3>*middleware*</h3><h4 class="dynamic">dynamic</h4><h4 class="lang"><a href="taoensso.telemere.html#var-*middleware*">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Optional (fn [signal]) => ?modified-signal to apply to all signals.
|
||
When middleware returns nil, skips all handlers. Default (root) value is nil.
|
||
|
||
Useful for dynamically transforming signals and/or filtering signals
|
||
by signal data/content/etc.
|
||
|
||
Re/bind dynamic value using `with-middleware`, `binding`.
|
||
Modify root (default) value using `set-middleware!`.
|
||
|
||
As with all dynamic Clojure vars, "binding conveyance" applies when using
|
||
futures, agents, etc.
|
||
|
||
Examples:
|
||
|
||
;; Filter signals by returning nil:
|
||
(t/set-middleware! (fn [signal] (when-not (:skip-me? signal) signal)))
|
||
|
||
;; Remove key/s from signals:
|
||
(t/set-middleware! (fn [signal] (dissoc signal :unwanted-key1 ...)))
|
||
|
||
;; Remove key/s from signals to specific handler:
|
||
(t/add-handler! ::my-handler my-handler
|
||
{:middleware (fn [signal] (dissoc signal :unwanted-key1 ...))})
|
||
|
||
Tips:
|
||
- Compose multiple middleware fns together with `comp-middleware`.
|
||
- Use `get-env` to set default (root) value based on environmental config.</pre></div></div><div class="public anchor" id="var-*uid-fn*"><h3>*uid-fn*</h3><h4 class="dynamic">dynamic</h4><h4 class="lang"><a href="taoensso.telemere.html#var-*uid-fn*">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
(fn [root?]) used to generate signal `:uid` values (unique instance ids)
|
||
when tracing.
|
||
|
||
Relevant only when `otel-tracing?` is false.
|
||
If `otel-tracing?` is true, uids are instead generated by `*otel-tracer*`.
|
||
|
||
`root?` argument is true iff signal is a top-level trace (i.e. form being
|
||
traced is unnested = has no parent form). Root-level uids typically need
|
||
more entropy and so are usually longer (e.g. 32 vs 16 hex chars).
|
||
|
||
Override default by setting one of the following:
|
||
JVM property: `taoensso.telemere/uid-fn`
|
||
Env variable: `TAOENSSO_TELEMERE_UID_FN`
|
||
Classpath resource: `taoensso.telemere/uid-fn`
|
||
|
||
Possible (compile-time) values include:
|
||
`:uuid` - UUID string (Cljs) or `java.util.UUID` (Clj)
|
||
`:uuid-str` - UUID string (36/36 chars)
|
||
`:nano/secure` - nano-style string (21/10 chars) w/ strong RNG
|
||
`:nano/insecure` - nano-style string (21/10 chars) w/ fast RNG (default)
|
||
`:hex/insecure` - hex-style string (32/16 chars) w/ strong RNG
|
||
`:hex/secure` - hex-style string (32/16 chars) w/ fast RNG</pre></div></div><div class="public anchor" id="var-add-handler.21"><h3>add-handler!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-add-handler.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(add-handler! handler-id handler-fn)</code><code>(add-handler! handler-id handler-fn dispatch-opts)</code></div><div class="doc"><pre class="plaintext">Registers given signal handler and returns
|
||
{<handler-id> {:keys [dispatch-opts handler-fn]}} for all handlers
|
||
now registered. If an old handler already existed under the same id, stop it.
|
||
|
||
`handler-fn` should be a fn of exactly 2 arities:
|
||
|
||
[signal] ; Single argument
|
||
Called asynchronously or synchronously (depending on dispatch options)
|
||
to do something useful with the given signal.
|
||
|
||
Example actions:
|
||
Save data to disk or db, `tap>`, log, `put!` to an appropriate
|
||
`core.async` channel, filter, aggregate, use for a realtime analytics
|
||
dashboard, examine for outliers or unexpected data, etc.
|
||
|
||
[] ; No arguments
|
||
Called exactly once when stopping handler to provide an opportunity
|
||
for handler to flush buffers, close files, etc. May just noop.
|
||
|
||
NB you should always call `stop-handlers!` somewhere appropriate - usually
|
||
near the end of your `-main` or shutdown procedure, AFTER all other code has
|
||
completed that could create signals.
|
||
|
||
See `help:handler-dispatch-options` for handler filters, etc.</pre></div></div><div class="public anchor" id="var-catch-.3Eerror.21"><h3>catch->error!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-catch-.3Eerror.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(catch->error! form)</code><code>(catch->error! id form)</code><code>(catch->error! {:as opts, :keys [rethrow? catch-val elidable? location inst uid middleware sample-rate kind ns id level when rate-limit rate-limit-by ctx parent root trace? do let data msg error & kvs]} form)</code></div><div class="doc"><pre class="plaintext">Unconditionally executes given form and-
|
||
If form succeeds: return the form's result.
|
||
If form throws:
|
||
Call `error!` with the thrown error and the given signal options [2],
|
||
then return (:catch-val opts) if it exists, or rethrow the error.
|
||
|
||
API: [form] [id-or-opts form] => form's result (value/throw) (unconditional), or (:catch-val opts)
|
||
Default kind: `:error`
|
||
Default level: `:error`
|
||
|
||
Examples:
|
||
|
||
(catch->error! (/ 1 0)) ; %> {:kind :error, :level :error, :error <caught> ...}
|
||
(catch->error! ::my-id (/ 1 0)) ; %> {... :id ::my-id ...}
|
||
(catch->error!
|
||
{:let [x "x"] ; Available to `:data` and `:msg`
|
||
:data {:x x}
|
||
:msg ["My msg:" x my-error]
|
||
:catch-val "Return value when form throws"
|
||
:catch-sym my-error ; Sym of caught error, available to `:data` and `:msg`
|
||
}
|
||
|
||
(/ 1 0)) ; %> {... :data {x "x"}, :msg_ "My msg: x <caught>" ...}
|
||
|
||
Tips:
|
||
|
||
- Test using `with-signal`: (with-signal (catch->error! ...)).
|
||
- Supports the same options [2] as other signals [1].
|
||
|
||
- Useful for preventing errors from going unnoticed in futures, callbacks,
|
||
agent actions, etc.!: (future (catch->error ::my-future (do-something)))
|
||
|
||
See also `error!`.
|
||
|
||
----------------------------------------------------------------------
|
||
[1] See `help:signal-creators` - (`signal!`, `log!`, `event!`, ...)
|
||
[2] See `help:signal-options` - {:keys [kind level id data ...]}
|
||
[3] See `help:signal-content` - {:keys [kind level id data ...]}
|
||
[4] See `help:signal-filters` - (by ns/kind/id/level, sampling, etc.)</pre></div></div><div class="public anchor" id="var-chance"><h3>chance</h3><h4 class="lang"><a href="taoensso.telemere.html#var-chance">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(chance prob)</code></div><div class="doc"><pre class="plaintext">Returns true with given probability ∈ ℝ[0,1].
|
||
</pre></div></div><div class="public anchor" id="var-clean-signal-fn"><h3>clean-signal-fn</h3><h4 class="lang"><a href="taoensso.telemere.html#var-clean-signal-fn">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(clean-signal-fn)</code><code>(clean-signal-fn {:keys [incl-kvs? incl-nils? incl-keys], :as opts})</code></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
Returns a (fn clean [signal]) that:
|
||
- Takes a Telemere signal (map).
|
||
- Returns a minimal signal (map) ready for printing, etc.
|
||
|
||
Signals are optimized for cheap creation and easy handling, so tend to be
|
||
verbose and may contain things like nil values and duplicated content.
|
||
|
||
This util efficiently cleans signals of such noise, helping reduce
|
||
storage/transmission size, and making key info easier to see.
|
||
|
||
Options:
|
||
`:incl-nils?` - Include signal's keys with nil values? (default false)
|
||
`:incl-kvs?` - Include signal's app-level root kvs? (default false)
|
||
`:incl-keys` - Subset of signal keys to retain from those otherwise
|
||
excluded by default: #{:location :kvs :file :host :thread}</pre></div></div><div class="public anchor" id="var-comp-middleware"><h3>comp-middleware</h3><h4 class="lang"><a href="taoensso.telemere.html#var-comp-middleware">clj</a></h4><h4 class="lang current">cljs</h4><h4 class="added">added in Encore v3.106.0 (2024-05-01)</h4><div class="usage"><code>(comp-middleware fs)</code><code>(comp-middleware f1 f2)</code><code>(comp-middleware f1 f2 f3)</code><code>(comp-middleware f1 f2 f3 & fs)</code></div><div class="doc"><pre class="plaintext">Returns a single (composite) unary fn that applies all given unary fns
|
||
sequentially (left->right!: f1, f2, ...). If any given fn returns nil, the
|
||
returned composite fn immediately returns nil:
|
||
|
||
((comp-middleware inc #(* % 2) inc) 1) => 5 ; (inc (* (inc 1) 2))
|
||
((comp-middleware inc (fn [_] nil) (fn [_] (throw (Exception. "Never thrown!")))) 1) => nil
|
||
|
||
Useful for composing Ring-style middleware fns.</pre></div></div><div class="public anchor" id="var-default-handler-dispatch-opts"><h3>default-handler-dispatch-opts</h3><h4 class="lang"><a href="taoensso.telemere.html#var-default-handler-dispatch-opts">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext"></pre></div></div><div class="public anchor" id="var-error.21"><h3>error!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-error.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(error! error)</code><code>(error! id error)</code><code>(error! {:as opts, :keys [elidable? location inst uid middleware sample-rate kind ns id level when rate-limit rate-limit-by ctx parent root trace? do let data msg error & kvs]} error)</code></div><div class="doc"><pre class="plaintext">"Error" signal creator, emphasizing error + id.
|
||
|
||
API: [error] [id-or-opts error] => given error (unconditional)
|
||
Default kind: `:error`
|
||
Default level: `:error`
|
||
|
||
Examples:
|
||
|
||
(throw (error! (ex-info "MyEx" {}))) ; %> {:kind :error, :level :error, :error <MyEx> ...}
|
||
(throw (error! ::my-id (ex-info "MyEx" {}))) ; %> {... :id ::my-id ...}
|
||
(throw
|
||
(error!
|
||
{:let [x "x"] ; Available to `:data` and `:msg`
|
||
:data {:x x}
|
||
:msg ["My message:" x]}
|
||
|
||
(ex-info "MyEx" {}))) ; %> {... :data {x "x"}, :msg_ "My msg: x" ...}
|
||
|
||
Tips:
|
||
|
||
- Test using `with-signal`: (with-signal (error! ...)).
|
||
- Supports the same options [2] as other signals [1].
|
||
|
||
- `error` arg is a platform error (`java.lang.Throwable` or `js/Error`).
|
||
- Can conveniently be wrapped by `throw`: (throw (error! ...)).
|
||
|
||
----------------------------------------------------------------------
|
||
[1] See `help:signal-creators` - (`signal!`, `log!`, `event!`, ...)
|
||
[2] See `help:signal-options` - {:keys [kind level id data ...]}
|
||
[3] See `help:signal-content` - {:keys [kind level id data ...]}
|
||
[4] See `help:signal-filters` - (by ns/kind/id/level, sampling, etc.)</pre></div></div><div class="public anchor" id="var-error-signal.3F"><h3>error-signal?</h3><h4 class="lang"><a href="taoensso.telemere.html#var-error-signal.3F">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(error-signal? signal)</code></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
Returns true iff given signal has an `:error` value, or a `:kind` or `:level`
|
||
that indicates that it's an error.</pre></div></div><div class="public anchor" id="var-event.21"><h3>event!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-event.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(event! id)</code><code>(event! id level)</code><code>(event! id {:as opts, :keys [elidable? location inst uid middleware sample-rate kind ns id level when rate-limit rate-limit-by ctx parent root trace? do let data msg error & kvs]})</code></div><div class="doc"><pre class="plaintext">"Event" signal creator, emphasizing id + level.
|
||
|
||
API: [id] [id level-or-opts] => true iff signal was allowed
|
||
Default kind: `:event`
|
||
Default level: `:info`
|
||
|
||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||
dispatches it to registered handlers for processing (e.g. writing to
|
||
console/file/queue/db, etc.).
|
||
|
||
Examples:
|
||
|
||
(event! ::my-id) ; %> {:kind :event, :level :info, :id ::my-id ...}
|
||
(event! ::my-id :warn) ; %> {... :level :warn ...}
|
||
(event! ::my-id
|
||
{:let [x "x"] ; Available to `:data` and `:msg`
|
||
:data {:x x}
|
||
:msg ["My msg:" x]}) ; %> {... :data {x "x"}, :msg_ "My msg: x" ...}
|
||
|
||
Tips:
|
||
|
||
- Test using `with-signal`: (with-signal (event! ...)).
|
||
- Supports the same options [2] as other signals [1].
|
||
|
||
- `log!` and `event!` are both good default/general-purpose signal creators.
|
||
- `log!` emphasizes messages, while `event!` emphasizes ids.
|
||
|
||
- Has a different 2-arity arg order to all other signals!
|
||
Mnemonic: the arg that's typically larger is *always* in the rightmost
|
||
position, and for `event!` that's the `level-or-opts` arg.
|
||
|
||
----------------------------------------------------------------------
|
||
[1] See `help:signal-creators` - (`signal!`, `log!`, `event!`, ...)
|
||
[2] See `help:signal-options` - {:keys [kind level id data ...]}
|
||
[3] See `help:signal-content` - {:keys [kind level id data ...]}
|
||
[4] See `help:signal-filters` - (by ns/kind/id/level, sampling, etc.)</pre></div></div><div class="public anchor" id="var-format-signal-fn"><h3>format-signal-fn</h3><h4 class="lang"><a href="taoensso.telemere.html#var-format-signal-fn">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(format-signal-fn)</code><code>(format-signal-fn {:keys [incl-newline? preamble-fn content-fn], :or {incl-newline? true, preamble-fn (signal-preamble-fn), content-fn (signal-content-fn)}})</code></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
Returns a (fn format [signal]) that:
|
||
- Takes a Telemere signal (map).
|
||
- Returns a human-readable signal string.
|
||
|
||
Options:
|
||
`:incl-newline?` - Include terminating system newline? (default true)
|
||
`:preamble-fn` - (fn [signal]) => signal preamble string, see [1]
|
||
`:content-fn` - (fn [signal]) => signal content string, see [2]
|
||
|
||
[1] `taoensso.telemere.utils/signal-preamble-fn`, etc.
|
||
[2] `taoensso.telemere.utils/signal-content-fn`, etc.
|
||
|
||
See also `pr-signal-fn` for an alternative to `format-signal-fn`
|
||
that produces machine-readable output (edn, JSON, etc.).</pre></div></div><div class="public anchor" id="var-get-env"><h3>get-env</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-get-env">clj</a></h4><h4 class="lang current">cljs</h4><h4 class="added">added in Encore v3.75.0 (2024-01-29)</h4><div class="usage"><code>(get-env {:keys [as default return], :or {as :str, return :value}} spec)</code></div><div class="doc"><pre class="plaintext">Flexible cross-platform util to return an environmental config value.
|
||
|
||
Given an id (const keyword/string) or vector of desc-priority alternative
|
||
ids, parse and return the first of the following that exists:
|
||
- JVM property value for id
|
||
- Environment variable value for id
|
||
- Classpath resource content for id
|
||
|
||
Ids may include optional segment in `<>` tag (e.g. `<.edn>`).
|
||
Ids may include `<.?platform.?>` tag for auto replacement:
|
||
`<.platform>` => ".clj" / ".cljs"
|
||
`<platform->` => "clj-" / "cljs-", etc.
|
||
|
||
Search order: desc by combined [alt-index platform(y/n) optional(y/n)].
|
||
|
||
So (get-env {:as :edn} [:my-app/alt1<.platform><.edn> :my-app/alt2])
|
||
will parse and return the first of the following that exists:
|
||
|
||
1. Alt1 +platform +optional (optional .edn suffix)
|
||
1a. `my-app.alt1.clj.edn` JVM property value
|
||
1b. `MY_APP_ALT1_CLJ_EDN` environment variable value
|
||
1c. `my-app.alt1.clj.edn` classpath resource content
|
||
|
||
2. Alt1 +platform -optional (optional .edn suffix)
|
||
2a. `my-app.alt1.clj` JVM property value
|
||
2b. `MY_APP_ALT1_CLJ` environment variable value
|
||
2c. `my-app.alt1.clj` classpath resource content
|
||
|
||
3. Alt1 -platform +optional (optional .edn suffix)
|
||
3a. `my-app.alt1.edn` JVM property value
|
||
3b. `MY_APP_ALT1_EDN` environment variable value
|
||
3c. `my-app.alt1.edn` classpath resource content
|
||
|
||
4. Alt1 -platform -optional (optional .edn suffix)
|
||
4a. `my-app.alt1` JVM property value
|
||
4b. `MY_APP_ALT1` environment variable value
|
||
4c. `my-app.alt1` classpath resource content
|
||
|
||
5. Alt2
|
||
5a. `my-app.alt2` JVM property value
|
||
5b. `MY_APP_ALT2` environment variable value
|
||
5c. `my-app.alt2` classpath resource content
|
||
|
||
Options:
|
||
`:as` - Parse found value as given type ∈ #{:str :bool :edn} (default `:str`).
|
||
`:default` - Fallback to return unparsed if no value found during search (default `nil`).
|
||
`:return` - Return type ∈ #{:value :map :explain} (default `:value`).
|
||
|
||
For Cljs: resulting config value must be something that can be safely
|
||
embedded in code during macro expansion!
|
||
|
||
Advanced: if resulting config value is a single top-level symbol, it will
|
||
be evaluated during macro expansion.
|
||
|
||
TIP!: Use the {:return :explain} option in tests or at the REPL to
|
||
verify/inspect resulting config value, config source, and specific
|
||
search order of prop/env/res ids.</pre></div></div><div class="public anchor" id="var-get-filters"><h3>get-filters</h3><h4 class="lang"><a href="taoensso.telemere.html#var-get-filters">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(get-filters)</code></div><div class="doc"><pre class="plaintext">Returns current ?{:keys [compile-time runtime]} filter config.
|
||
</pre></div></div><div class="public anchor" id="var-get-handlers"><h3>get-handlers</h3><h4 class="lang"><a href="taoensso.telemere.html#var-get-handlers">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(get-handlers)</code></div><div class="doc"><pre class="plaintext">Returns ?{<handler-id> {:keys [dispatch-opts handler-fn handler-stats_]}}
|
||
for all registered signal handlers.</pre></div></div><div class="public anchor" id="var-get-handlers-stats"><h3>get-handlers-stats</h3><h4 class="lang"><a href="taoensso.telemere.html#var-get-handlers-stats">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(get-handlers-stats)</code></div><div class="doc"><pre class="plaintext">Alpha, subject to change.
|
||
Returns ?{<handler-id> {:keys [handling-nsecs counts]}} for all registered
|
||
signal handlers that have the `:track-stats?` dispatch option enabled
|
||
(it is by default).
|
||
|
||
Stats include:
|
||
|
||
`:handling-nsecs` - Summary stats of nanosecond handling times, keys:
|
||
`:min` - Minimum handling time
|
||
`:max` - Maximum handling time
|
||
`:mean` - Arithmetic mean handling time
|
||
`:mad` - Mean absolute deviation of handling time (measure of dispersion)
|
||
`:var` - Variance of handling time (measure of dispersion)
|
||
`:p50` - 50th percentile of handling time (50% of times <= this)
|
||
`:p90` - 90th percentile of handling time (90% of times <= this)
|
||
`:p99` - 99th percentile of handling time
|
||
`:last` - Most recent handling time
|
||
...
|
||
|
||
`:counts` - Integer counts for handler outcomes, keys (chronologically):
|
||
|
||
`:dropped` - Noop handler calls due to stopped handler
|
||
`:back-pressure` - Handler calls that experienced (async) back-pressure
|
||
(possible noop, depending on back-pressure mode)
|
||
|
||
`:sampled` - Noop handler calls due to sample rate
|
||
`:filtered` - Noop handler calls due to kind/ns/id/level/when filtering
|
||
`:rate-limited` - Noop handler calls due to rate limit
|
||
`:disallowed` - Noop handler calls due to sampling/filtering/rate-limiting
|
||
`:allowed` - Other handler calls (no sampling/filtering/rate-limiting)
|
||
|
||
`:suppressed` - Noop handler calls due to nil middleware result
|
||
`:handled` - Handler calls that completed successfully
|
||
`:errors` - Handler calls that threw an error
|
||
|
||
Note that for performance reasons returned counts are not mutually atomic,
|
||
e.g. `:sampled` count may be incremented before `:disallowed` count is.
|
||
|
||
Useful for understanding/debugging how your handlers behave in practice,
|
||
especially when they're under stress (high-volumes, etc.).
|
||
|
||
Handler stats are tracked from the time each handler is last registered
|
||
(e.g. with an `add-handler!` call).</pre></div></div><div class="public anchor" id="var-get-min-levels"><h3>get-min-levels</h3><h4 class="lang"><a href="taoensso.telemere.html#var-get-min-levels">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(get-min-levels)</code><code>(get-min-levels kind)</code><code>(get-min-levels kind ns)</code></div><div class="doc"><pre class="plaintext">Returns current ?{:keys [compile-time runtime]} minimum signal levels.
|
||
</pre></div></div><div class="public anchor" id="var-handler.3Aconsole"><h3>handler:console</h3><h4 class="lang"><a href="taoensso.telemere.html#var-handler.3Aconsole">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(handler:console)</code><code>(handler:console {:keys [output-fn], :or {output-fn (utils/format-signal-fn)}})</code></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
|
||
If `js/console` exists, returns a signal handler that:
|
||
- Takes a Telemere signal (map).
|
||
- Writes the signal as a string to JavaScript console.
|
||
|
||
A general-purpose `println`-style handler that's well suited for outputting
|
||
signals as human or machine-readable (edn, JSON) strings.
|
||
|
||
Options:
|
||
`:output-fn` - (fn [signal]) => string, see `format-signal-fn` or `pr-signal-fn`</pre></div></div><div class="public anchor" id="var-handler.3Aconsole-raw"><h3>handler:console-raw</h3><h4 class="lang current">cljs</h4><div class="usage"><code>(handler:console-raw)</code><code>(handler:console-raw {:keys [preamble-fn format-nsecs-fn], :as opts, :or {preamble-fn (utils/signal-preamble-fn), format-nsecs-fn (utils/format-nsecs-fn)}})</code></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
|
||
If `js/console` exists, returns a signal handler that:
|
||
- Takes a Telemere signal (map).
|
||
- Writes the raw signal to JavaScript console.
|
||
|
||
Intended for use with browser formatting tools like `binaryage/devtools`,
|
||
Ref. <<a href="https://github.com/binaryage/cljs-devtools">https://github.com/binaryage/cljs-devtools</a>>.
|
||
|
||
Options:
|
||
`:preamble-fn` - (fn [signal]) => string, see [1].
|
||
`:format-nsecs-fn` - (fn [nanosecs]) => string.
|
||
|
||
[1] `taoensso.telemere.utils/signal-preamble-fn`, etc.</pre></div></div><div class="public anchor" id="var-help.3Aenvironmental-config"><h3>help:environmental-config</h3><h4 class="lang"><a href="taoensso.telemere.html#var-help.3Aenvironmental-config">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Telemere supports extensive environmental config via JVM properties,
|
||
environment variables, or classpath resources.
|
||
|
||
Environmental filter config includes:
|
||
|
||
Kind filter:
|
||
JVM property: `taoensso.telemere.rt-kind-filter`
|
||
Env variable: `TAOENSSO_TELEMERE_RT_KIND_FILTER`
|
||
Classpath resource: `taoensso.telemere.rt-kind-filter`
|
||
|
||
Namespace filter:
|
||
JVM property: `taoensso.telemere.rt-ns-filter`
|
||
Env variable: `TAOENSSO_TELEMERE_RT_NS_FILTER`
|
||
Classpath resource: `taoensso.telemere.rt-ns-filter`
|
||
|
||
Id filter:
|
||
JVM property: `taoensso.telemere.rt-id-filter`
|
||
Env variable: `TAOENSSO_TELEMERE_RT_ID_FILTER`
|
||
Classpath resource: `taoensso.telemere.rt-id-filter`
|
||
|
||
Minimum level:
|
||
JVM property: `taoensso.telemere.rt-min-level`
|
||
Env variable: `TAOENSSO_TELEMERE_RT_MIN_LEVEL`
|
||
Classpath resource: `taoensso.telemere.rt-min-level`
|
||
|
||
Values are edn, examples:
|
||
|
||
`taoensso.telemere.rt-min-level` -> ":info"
|
||
`TAOENSSO_TELEMERE_RT_NS_FILTER` -> "{:disallow \"taoensso.*\"}"
|
||
`taoensso.telemere.rt-id-filter.cljs` -> "#{:my-id1 :my-id2}"
|
||
`TAOENSSO_TELEMERE_RT_KIND_FILTER_CLJ` -> "nil"
|
||
|
||
For other (non-filter) environmental config, see the relevant docstrings.
|
||
|
||
Tips:
|
||
|
||
- The above ids are for runtime filters (the most common).
|
||
For compile-time filters, change `rt`->`ct` / `RT`->`CT`.
|
||
|
||
- The above ids will affect both Clj AND Cljs.
|
||
For platform-specific filters, use
|
||
".clj.edn" / "_CLJ_EDN" or
|
||
".cljs.edn" / "_CLJS_EDN" suffixes instead.
|
||
|
||
- Optional ".edn" / "_EDN" suffixes may be added for clarity.
|
||
|
||
- To get the right edn syntax, first set your runtime filters using the
|
||
standard utils (`set-min-level!`, etc.). Then call `get-filters` and
|
||
serialize the relevant parts to edn with `pr-str`.
|
||
|
||
- All environmental config uses `get-env` underneath.
|
||
See the `get-env` docstring for more/advanced details.
|
||
|
||
- Classpath resources are files accessible on your project's
|
||
classpath. This usually includes files in your project's
|
||
`resources/` dir.</pre></div></div><div class="public anchor" id="var-help.3Afilters"><h3>help:filters</h3><h4 class="lang"><a href="taoensso.telemere.html#var-help.3Afilters">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">A signal will be provided to a handler iff ALL of the following are true:
|
||
|
||
1. Signal creation is allowed by "signal filters":
|
||
a. Compile-time: sample rate, kind, ns, id, level, when form, rate limit
|
||
b. Runtime: sample rate, kind, ns, id, level, when form, rate limit
|
||
|
||
2. Signal handling is allowed by "handler filters":
|
||
a. Compile-time: not applicable
|
||
b. Runtime: sample rate, kind, ns, id, level, when fn, rate limit
|
||
|
||
3. Signal middleware (fn [signal]) => ?modified-signal does not return nil
|
||
4. Handler middleware (fn [signal]) => ?modified-signal does not return nil
|
||
|
||
Note that middleware provides a flexible way to filter signals by arbitrary
|
||
signal data/content conditions (return nil to filter signal).
|
||
|
||
Config:
|
||
|
||
To set signal filters (1a, 1b):
|
||
|
||
Use:
|
||
`set-kind-filter!`, `with-kind-filter`
|
||
`set-ns-filter!`, `with-ns-filter`
|
||
`set-id-filter!`, `with-id-filter`
|
||
`set-min-level!`, `with-min-level`
|
||
or see `help:environmental-config`.
|
||
|
||
To set handler filters (2b) or handler middleware (4):
|
||
|
||
Provide relevant opts when calling `add-handler!` or `with-handler/+`.
|
||
See `help:handler-dispatch-options` for details.
|
||
|
||
Note: signal filters (1a, 1b) should generally be AT LEAST as permissive as
|
||
handler filters (2b), otherwise signals will be filtered before even
|
||
reaching handlers.
|
||
|
||
To set signal middleware (3): use `set-middleware!`, `with-middleware`
|
||
|
||
Compile-time vs runtime filters:
|
||
|
||
Compile-time filters are an advanced feature that can be tricky to set
|
||
and use correctly. Most folks will want ONLY runtime filters.
|
||
|
||
Compile-time filters works by eliding (completely removing the code for)
|
||
disallowed signals. This means zero performance cost for these signals,
|
||
but also means that compile-time filters are PERMANENT once applied.
|
||
|
||
So if you set `:info` as the compile-time minimum level, that'll REMOVE
|
||
CODE for every signal below `:info` level. To decrease that minimum level,
|
||
you'll need to rebuild.
|
||
|
||
Compile-time filters can be set ONLY with environmental config
|
||
(see `help:environmental-config` for details).
|
||
|
||
Signal and handler sampling is multiplicative:
|
||
|
||
Both signals and handlers can have independent sample rates, and these
|
||
MULTIPLY! If a signal is created with 20% sampling and a handler
|
||
handles 50% of received signals, then 10% of possible signals will be
|
||
handled (50% of 20%).
|
||
|
||
The final (multiplicative) rate is helpfully reflected in each signal's
|
||
`:sample-rate` value.
|
||
|
||
For more info:
|
||
|
||
- On signal filters, see: `help:filters`
|
||
- On handler filters, see: `help:handler-dispatch-options`
|
||
|
||
If anything is unclear, please ping me (@ptaoussanis) so that I can
|
||
improve these docs!</pre></div></div><div class="public anchor" id="var-help.3Ahandler-dispatch-options"><h3>help:handler-dispatch-options</h3><h4 class="lang"><a href="taoensso.telemere.html#var-help.3Ahandler-dispatch-options">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Dispatch options can be provided for each signal handler when calling
|
||
`add-handler!` or `with-handler/+`. These options will be merged over the
|
||
defaults specified by `default-handler-dispatch-opts`.
|
||
|
||
All handlers support the same dispatch options, including:
|
||
|
||
`:async` (Clj only) options include:
|
||
|
||
`:buffer-size` (default 1024)
|
||
Size of request buffer, and the max number of pending requests before
|
||
configured back-pressure behaviour is triggered (see `:mode`).
|
||
|
||
`:mode` (default `:blocking`)
|
||
Back-pressure mode ∈ #{:blocking :dropping :sliding}.
|
||
Controls what happens when a new request is made while request buffer is full:
|
||
`:blocking` => Blocks caller until buffer space is available
|
||
`:dropping` => Drops the newest request (noop)
|
||
`:sliding` => Drops the oldest request
|
||
|
||
`:n-threads` (default 1)
|
||
Number of threads to use for executing fns (servicing request buffer).
|
||
NB execution order may be non-sequential when n > 1.
|
||
|
||
`:drain-msecs` (default 6000 msecs)
|
||
Maximum time (in milliseconds) to try allow pending execution requests to
|
||
complete when stopping handler. nil => no maximum.
|
||
|
||
`:priority` (default 100)
|
||
Optional handler priority ∈ℤ.
|
||
Handlers will be called in descending priority order (larger ints first).
|
||
|
||
`:track-stats?` (default true)
|
||
Should handler track statistics (e.g. handling times) for
|
||
reporting by `get-handlers-stats`?
|
||
|
||
`:sample-rate` (default nil => no sampling)
|
||
Optional sample rate ∈ℝ[0,1], or (fn dyamic-sample-rate []) => ℝ[0,1].
|
||
When present, handle only this (random) proportion of args:
|
||
1.0 => handle every arg (same as nil rate, default)
|
||
0.0 => noop every arg
|
||
0.5 => handle random 50% of args
|
||
|
||
`:kind-filter` - Kind filter as in `set-kind-filter!` (when relevant)
|
||
`:ns-filter` - Namespace filter as in `set-ns-filter!`
|
||
`:id-filter` - Id filter as in `set-id-filter!` (when relevant)
|
||
`:min-level` - Minimum level as in `set-min-level!`
|
||
|
||
`:when-fn` (default nil => always allow)
|
||
Optional nullary (fn allow? []) that must return truthy for handler to be
|
||
called. When present, called *after* sampling and other filters, but before
|
||
rate limiting. Useful for filtering based on external state/context.
|
||
|
||
See `:middleware` for an alternative that takes a signal argument.
|
||
|
||
`:rate-limit` (default nil => no rate limit)
|
||
Optional rate limit spec as provided to `taoensso.encore/rate-limiter`,
|
||
{<limit-id> [<n-max-calls> <msecs-window>]}.
|
||
|
||
Examples:
|
||
{"1/sec" [1 1000]} => Max 1 call per 1000 msecs
|
||
{"1/sec" [1 1000]
|
||
"10/min" [10 60000]} => Max 1 call per 1000 msecs,
|
||
and 10 calls per 60 secs
|
||
|
||
`:middleware` (default nil => no middleware)
|
||
Optional (fn [signal]) => ?modified-signal to apply before
|
||
handling signal. When middleware returns nil, skips handler.
|
||
|
||
Compose multiple middleware fns together with `comp-middleware`.
|
||
|
||
`:error-fn` - (fn [{:keys [handler-id signal error]}]) to call on handler error.
|
||
`:backp-fn` - (fn [{:keys [handler-id ]}]) to call on handler back-pressure.
|
||
|
||
If anything is unclear, please ping me (@ptaoussanis) so that I can
|
||
improve these docs!</pre></div></div><div class="public anchor" id="var-help.3Ahandlers"><h3>help:handlers</h3><h4 class="lang"><a href="taoensso.telemere.html#var-help.3Ahandlers">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Signal handlers process created signals to do something with them (analyse them,
|
||
write them to console/file/queue/db, etc.).
|
||
|
||
Manage handlers with:
|
||
|
||
`get-handlers` - Returns info on registered handlers (dispatch options, etc.)
|
||
`get-handlers-stats` - Returns stats for registered handlers (handling times, etc.)
|
||
|
||
`add-handler!` - Registers given handler
|
||
`remove-handler!` - Unregisters given handler
|
||
|
||
`with-handler` - Executes form with ONLY the given handler registered
|
||
`with-handler+` - Executes form with the given handler (also) registered
|
||
|
||
`stop-handlers!` - Stops registered handlers
|
||
NB you should always call `stop-handlers!` somewhere appropriate - usually
|
||
near the end of your `-main` or shutdown procedure, AFTER all other code has
|
||
completed that could create signals.
|
||
|
||
See the relevant docstrings for details.
|
||
See `help:handler-dispatch-options` for handler filters, etc.
|
||
|
||
If anything is unclear, please ping me (@ptaoussanis) so that I can
|
||
improve these docs!</pre></div></div><div class="public anchor" id="var-help.3Asignal-content"><h3>help:signal-content</h3><h4 class="lang"><a href="taoensso.telemere.html#var-help.3Asignal-content">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Signals are maps with {:keys [inst id ns level data msg_ ...]}, though they
|
||
can be modified by signal and/or handler middleware.
|
||
|
||
Default signal keys:
|
||
|
||
`:schema` ------ Int version of signal schema (current: 1)
|
||
`:inst` -------- Platform instant [1] when signal was created
|
||
`:level` ------- Signal level ∈ #{<int> :trace :debug :info :warn :error :fatal :report ...}
|
||
`: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`)
|
||
`:uid` --------- ?id of signal instance (unique to each signal created at callsite when tracing, contrast with `:id`)
|
||
|
||
`:msg` --------- Arb app-level message ?str given to signal creator
|
||
`:data` -------- Arb app-level data ?val (usu. a map) given to signal creator
|
||
`:error` ------- Arb app-level platform ?error [2] given to signal creator
|
||
|
||
`:run-form` ---- Unevaluated ?form given to signal creator as `:run`
|
||
`:run-val` ----- Successful return ?val of `:run` ?form
|
||
`:run-nsecs` --- ?int nanosecs runtime of `:run` ?form
|
||
`:end-inst` ---- Platform ?instant [1] when `:run` ?form completed
|
||
|
||
`:ctx` --------- ?val of `*ctx*` (arb app-level state) when signal was created
|
||
`:parent` ------ ?{:keys [id uid]} of parent signal, present in nested signals when tracing
|
||
`:root` -------- ?{:keys [id uid]} of root signal, present in nested signals when tracing
|
||
|
||
`:location` ---- ?{:keys [ns file line column]} signal creator callsite
|
||
`:ns` ---------- ?str namespace of signal creator callsite, same as (:ns location)
|
||
`:line` -------- ?int line of signal creator callsite, same as (:line location)
|
||
`:column` ------ ?int column of signal creator callsite, same as (:column location)
|
||
`:file` -------- ?str filename of signal creator callsite, same as (:file location)
|
||
|
||
`:host` -------- (Clj only) {:keys [name ip]} info for network host
|
||
`:thread` ------ (Clj only) {:keys [name id group]} info for thread that created signal
|
||
|
||
`:sample-rate` - ?rate ∈ℝ[0,1] for combined signal AND handler sampling (0.75 => allow 75% of signals, nil => allow all)
|
||
|
||
<kvs> ---------- Other arb app-level ?kvs given to signal creator. Typically NOT included
|
||
in handler output, so a great way to provide custom data/opts for use
|
||
(only) by custom middleware/handlers.
|
||
|
||
If anything is unclear, please ping me (@ptaoussanis) so that I can improve these docs!
|
||
|
||
[1] `java.time.Instant` or `js/Date`
|
||
[2] `java.lang.Throwable` or `js/Error`</pre></div></div><div class="public anchor" id="var-help.3Asignal-creators"><h3>help:signal-creators</h3><h4 class="lang"><a href="taoensso.telemere.html#var-help.3Asignal-creators">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Call a Telemere signal creator to conditionally create a signal at that callsite.
|
||
|
||
When filtering conditions are met [4], the call creates a Telemere signal [3]
|
||
and dispatches it to registered handlers for processing (e.g. writing to
|
||
console/file/queue/db, etc.).
|
||
|
||
Telemere doesn't make a hard distinction between different kinds of signals
|
||
(log, event, error, etc.) - they're all just plain Clojure/Script maps with
|
||
various keys:
|
||
|
||
- All signal creators offer the same options [2], and
|
||
- All signal kinds can contain the same content [3]
|
||
|
||
Creators vary only in in their default options and call APIs (expected args
|
||
and return values), making them more/less convenient for certain use cases:
|
||
|
||
`event!` -------- [id ] or [id opts/level] => true iff signal was created (allowed)
|
||
`log!` ---------- [msg ] or [opts/level msg] => true iff signal was created (allowed)
|
||
`error!` -------- [error] or [opts/id error] => given error (unconditional)
|
||
`trace!` -------- [form ] or [opts/id form] => form result (value/throw) (unconditional)
|
||
`spy!` ---------- [form ] or [opts/level form] => form result (value/throw) (unconditional)
|
||
`catch->error!` - [form ] or [opts/id form] => form value, or given fallback
|
||
`signal!` ------- [opts ] => depends on options
|
||
|
||
- `log!` and `event!` are both good default/general-purpose signal creators.
|
||
- `log!` emphasizes messages, while `event!` emphasizes ids.
|
||
- `signal!` is the generic creator, and is used by all the others.
|
||
|
||
----------------------------------------------------------------------
|
||
[2] See `help:signal-options` - {:keys [kind level id data ...]}
|
||
[3] See `help:signal-content` - {:keys [kind level id data ...]}
|
||
[4] See `help:signal-filters` - (by ns/kind/id/level, sampling, etc.)</pre></div></div><div class="public anchor" id="var-help.3Asignal-options"><h3>help:signal-options</h3><h4 class="lang"><a href="taoensso.telemere.html#var-help.3Asignal-options">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Signal options (shared by all signal creators):
|
||
|
||
`:inst` -------- Platform instant [1] when signal was created, ∈ #{nil :auto <[1]>}
|
||
`:level` ------- Signal level ∈ #{<int> :trace :debug :info :warn :error :fatal :report ...}
|
||
`:kind` -------- Signal ?kind ∈ #{nil :event :error :log :trace :spy <app-val> ...}
|
||
`:id` ---------- ?id of signal (common to all signals created at callsite, contrast with `:uid`)
|
||
`:uid` --------- ?id of signal instance (unique to each signal created at callsite, contrast with `:id`)
|
||
Defaults to `:auto` for tracing signals, and nil otherwise
|
||
|
||
`:msg` --------- Arb app-level ?message to incl. in signal: str or vec of strs to join (with `\space`)
|
||
`:data` -------- Arb app-level ?data to incl. in signal: usu. a map
|
||
`:error` ------- Arb app-level ?error to incl. in signal: platform error [2]
|
||
|
||
`:run` --------- ?form to execute UNCONDITIONALLY; will incl. `:run-value` in signal
|
||
`:do` ---------- ?form to execute conditionally (iff signal allowed), before establishing `:let` ?binding
|
||
`:let` --------- ?bindings to establish conditionally (iff signal allowed), BEFORE evaluating `:data` and `:msg` (useful!)
|
||
|
||
`:ctx` --------- Custom ?val to override auto (dynamic `*ctx*`) in signal
|
||
`:parent` ------ Custom ?{:keys [id uid]} to override auto (dynamic) parent signal tracing info
|
||
`:root` -------- Custom ?{:keys [id uid]} to override auto (dynamic) root signal tracing info
|
||
`:location` ---- Custom ?{:keys [ns line column file]} to override auto signal creator callsite location
|
||
|
||
`:elidable?` --- Should signal be subject to compile-time elision? (Default: true)
|
||
`:sample-rate` - ?rate ∈ℝ[0,1] for signal sampling (0.75 => allow 75% of signals, nil => allow all)
|
||
`:when` -------- Arb ?form; when present, form must return truthy to allow signal
|
||
`:rate-limit` -- ?spec as given to `taoensso.telemere/rate-limiter`, see its docstring for details
|
||
`:rate-limit-by` When present, rate limits will be enforced independently for each id (any Clojure value!)
|
||
`:middleware` -- Optional (fn [signal]) => ?modified-signal to apply when signal is created
|
||
`:trace?` ------ Should tracing be enabled for `:run` form?
|
||
|
||
<kvs> ---------- Other arb app-level ?kvs to incl. in signal. Typically NOT included in
|
||
handler output, so a great way to provide custom data/opts for use
|
||
(only) by custom middleware/handlers.
|
||
|
||
If anything is unclear, please ping me (@ptaoussanis) so that I can improve these docs!
|
||
|
||
[1] `java.time.Instant` or `js/Date`
|
||
[2] `java.lang.Throwable` or `js/Error`</pre></div></div><div class="public anchor" id="var-level-aliases"><h3>level-aliases</h3><h4 class="lang"><a href="taoensso.telemere.html#var-level-aliases">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext"></pre></div></div><div class="public anchor" id="var-log.21"><h3>log!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-log.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(log! msg)</code><code>(log! level msg)</code><code>(log! {:as opts, :keys [elidable? location inst uid middleware sample-rate kind ns id level when rate-limit rate-limit-by ctx parent root trace? do let data msg error & kvs]} msg)</code></div><div class="doc"><pre class="plaintext">"Log" signal creator, emphasizing message + level.
|
||
|
||
API: [msg] [level-or-opts msg] => true iff signal was allowed.
|
||
Default kind: `:log`
|
||
Default level: `:info`
|
||
|
||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||
dispatches it to registered handlers for processing (e.g. writing to
|
||
console/file/queue/db, etc.).
|
||
|
||
Examples:
|
||
|
||
(log! "My msg") ; %> {:kind :log, :level :info, :id ::my-id ...}
|
||
(log! :warn "My msg") ; %> {... :level :warn ...}
|
||
(log!
|
||
{:let [x "x"] ; Available to `:data` and `:msg`
|
||
:data {:x x}}
|
||
|
||
["My msg:" x]) ; %> {... :data {x "x"}, :msg_ "My msg: x" ...}
|
||
|
||
Tips:
|
||
|
||
- Test using `with-signal`: (with-signal (log! ...)).
|
||
- Supports the same options [2] as other signals [1].
|
||
|
||
- `log!` and `event!` are both good default/general-purpose signal creators.
|
||
- `log!` emphasizes messages, while `event!` emphasizes ids.
|
||
|
||
- `msg` arg may be a string, or vector of strings to join with `\space`.
|
||
- See also `msg-splice`, `msg-skip` utils.
|
||
|
||
----------------------------------------------------------------------
|
||
[1] See `help:signal-creators` - (`signal!`, `log!`, `event!`, ...)
|
||
[2] See `help:signal-options` - {:keys [kind level id data ...]}
|
||
[3] See `help:signal-content` - {:keys [kind level id data ...]}
|
||
[4] See `help:signal-filters` - (by ns/kind/id/level, sampling, etc.)</pre></div></div><div class="public anchor" id="var-msg-skip"><h3>msg-skip</h3><h4 class="lang"><a href="taoensso.telemere.html#var-msg-skip">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"></div><div class="doc"><pre class="plaintext"></pre></div></div><div class="public anchor" id="var-msg-splice"><h3>msg-splice</h3><h4 class="lang"><a href="taoensso.telemere.html#var-msg-splice">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(msg-splice args)</code></div><div class="doc"><pre class="plaintext">For use within signal message vectors.
|
||
Wraps given arguments so that they're spliced when creating message.
|
||
Useful for conditionally splicing in extra message content, etc.:
|
||
|
||
(signal! {:msg [(when <cond> (msg-splice ["Username:" "Steve"])) <...>]}) or
|
||
(log! [(when <cond> (msg-splice ["Username:" "Steve"]))])
|
||
|
||
%> {:msg_ "Username: Steve"}</pre></div></div><div class="public anchor" id="var-newline"><h3>newline</h3><h4 class="lang"><a href="taoensso.telemere.html#var-newline">clj</a></h4><h4 class="lang current">cljs</h4><h4 class="added">added in Encore v3.68.0 (2023-09-25)</h4><div class="usage"></div><div class="doc"><pre class="plaintext">Single system newline
|
||
</pre></div></div><div class="public anchor" id="var-pr-signal-fn"><h3>pr-signal-fn</h3><h4 class="lang"><a href="taoensso.telemere.html#var-pr-signal-fn">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(pr-signal-fn)</code><code>(pr-signal-fn {:keys [pr-fn clean-fn incl-newline?], :as opts, :or {pr-fn :edn, clean-fn (clean-signal-fn), incl-newline? true}})</code></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
Returns a (fn pr [signal]) that:
|
||
- Takes a Telemere signal (map).
|
||
- Returns a machine-readable signal string.
|
||
|
||
Options:
|
||
`:pr-fn` - ∈ #{<unary-fn> :edn (default) :json (Cljs only)}
|
||
`:clean-fn` - (fn [signal]) => clean signal map, see [1]
|
||
`:incl-newline?` - Include terminating system newline? (default true)
|
||
|
||
Examples:
|
||
|
||
;; To print as edn:
|
||
(pr-signal-fn {:pr-fn :edn})
|
||
|
||
;; To print as JSON:
|
||
;; Ref. <<a href="https://github.com/metosin/jsonista">https://github.com/metosin/jsonista</a>> (or any alt JSON lib)
|
||
#?(:clj (require '[jsonista.core :as jsonista]))
|
||
(pr-signal-fn
|
||
{:pr-fn
|
||
#?(:cljs :json ; Use js/JSON.stringify
|
||
:clj jsonista/write-value-as-string)})
|
||
|
||
[1] `taoensso.telemere.utils/clean-signal-fn`, etc.
|
||
|
||
See also `format-signal-fn` for an alternative to `pr-signal-fn`
|
||
that produces human-readable output.</pre></div></div><div class="public anchor" id="var-rate-limiter"><h3>rate-limiter</h3><h4 class="lang"><a href="taoensso.telemere.html#var-rate-limiter">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(rate-limiter spec)</code><code>(rate-limiter opts spec)</code></div><div class="doc"><pre class="plaintext">Takes a spec of form
|
||
[ [<n-max-reqs> <msecs-window>] ...] or ; Unnamed limits
|
||
{<limit-id> [<n-max-reqs> <msecs-window>]} ; Named limits
|
||
and returns stateful (fn a-rate-limiter [] [req-id] [command req-id]).
|
||
|
||
Call the returned limiter fn with a request id (any Clojure value!) to
|
||
enforce limits independently for each id.
|
||
|
||
For example, (limiter-fn <ip-address-string>) will return:
|
||
- Falsey when allowed (all limits pass for given IP), or
|
||
- Truthy when disallowed (any limits fail for given IP):
|
||
[<worst-limit-id> <worst-backoff-msecs> {<limit-id> <backoff-msecs>}]
|
||
|
||
Or call the returned limiter fn with an extra command argument:
|
||
(limiter-fn :rl/peek <req-id) - Check limits WITHOUT incrementing count
|
||
(limiter-fn :rl/reset <req-id) - Reset all limits for given req-id</pre></div></div><div class="public anchor" id="var-remove-handler.21"><h3>remove-handler!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-remove-handler.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(remove-handler! handler-id)</code></div><div class="doc"><pre class="plaintext">Stops and deregisters signal handler with given id, and returns
|
||
?{<handler-id> {:keys [dispatch-opts handler-fn]}} for all handlers
|
||
still registered.</pre></div></div><div class="public anchor" id="var-set-ctx.21"><h3>set-ctx!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-set-ctx.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(set-ctx! root-ctx-val)</code></div><div class="doc"><pre class="plaintext">Set `*ctx*` var's default (root) value. See `*ctx*` for details.
|
||
</pre></div></div><div class="public anchor" id="var-set-id-filter.21"><h3>set-id-filter!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-set-id-filter.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(set-id-filter! id-filter)</code></div><div class="doc"><pre class="plaintext">Sets signal id filter based on given `id-filter` spec.
|
||
`id-filter` may be:
|
||
|
||
- A regex pattern of id/s to allow
|
||
- A str/kw/sym to allow, with "*" and "(.*)" as wildcards:
|
||
"foo.*" will allow "foo.bar"
|
||
"foo(.*)" will allow "foo.bar" and "foo"
|
||
|
||
- A set/vector of above (allow on any match)
|
||
- A map, {:allow <spec> :disallow <spec>} with specs as above:
|
||
If present, `:allow` spec MUST match, AND
|
||
If present, `:disallow` spec MUST NOT match.</pre></div></div><div class="public anchor" id="var-set-kind-filter.21"><h3>set-kind-filter!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-set-kind-filter.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(set-kind-filter! kind-filter)</code></div><div class="doc"><pre class="plaintext">Sets signal kind filter based on given `kind-filter` spec.
|
||
`kind-filter` may be:
|
||
|
||
- A regex pattern of kind/s to allow
|
||
- A str/kw/sym to allow, with "*" and "(.*)" as wildcards:
|
||
"foo.*" will allow "foo.bar"
|
||
"foo(.*)" will allow "foo.bar" and "foo"
|
||
|
||
- A set/vector of above (allow on any match)
|
||
- A map, {:allow <spec> :disallow <spec>} with specs as above:
|
||
If present, `:allow` spec MUST match, AND
|
||
If present, `:disallow` spec MUST NOT match.</pre></div></div><div class="public anchor" id="var-set-middleware.21"><h3>set-middleware!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-set-middleware.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(set-middleware! ?root-middleware-fn)</code></div><div class="doc"><pre class="plaintext">Set `*middleware*` var's default (root) value. See `*middleware*` for details.
|
||
</pre></div></div><div class="public anchor" id="var-set-min-level.21"><h3>set-min-level!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-set-min-level.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(set-min-level! min-level)</code><code>(set-min-level! kind min-level)</code><code>(set-min-level! kind ns-filter min-level)</code></div><div class="doc"><pre class="plaintext">Sets minimum signal level based on given `min-level` spec.
|
||
`min-level` may be:
|
||
|
||
- nil (=> no minimum level).
|
||
- A level keyword (see `level-aliases` var for details).
|
||
- An integer.
|
||
|
||
If `ns-filter` is provided, then the given minimum level
|
||
will apply only for the namespace/s that match `ns-filter`.
|
||
See `set-ns-filter!` for details.
|
||
|
||
If non-nil `kind` is provided, then the given minimum level
|
||
will apply only for that signal kind.
|
||
|
||
Examples:
|
||
(set-min-level! nil) ; Disable minimum level
|
||
(set-min-level! :info) ; Set `:info` as minimum level
|
||
(set-min-level! 100) ; Set 100 as minimum level
|
||
|
||
;; Set `:debug` as minimum level for current namespace
|
||
;; (nil `kind` => all kinds)
|
||
(set-min-level! nil *ns* :debug)</pre></div></div><div class="public anchor" id="var-set-ns-filter.21"><h3>set-ns-filter!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-set-ns-filter.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(set-ns-filter! ns-filter)</code></div><div class="doc"><pre class="plaintext">Sets signal namespace filter based on given `ns-filter` spec.
|
||
`ns-filter` may be:
|
||
|
||
- A namespace.
|
||
- A regex pattern of namespaces/s to allow
|
||
- A str/kw/sym to allow, with "*" and "(.*)" as wildcards:
|
||
"foo.*" will allow "foo.bar"
|
||
"foo(.*)" will allow "foo.bar" and "foo"
|
||
|
||
- A set/vector of above (allow on any match)
|
||
- A map, {:allow <spec> :disallow <spec>} with specs as above:
|
||
If present, `:allow` spec MUST match, AND
|
||
If present, `:disallow` spec MUST NOT match.</pre></div></div><div class="public anchor" id="var-set-var-root.21"><h3>set-var-root!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-set-var-root.21">clj</a></h4><h4 class="lang current">cljs</h4><h4 class="added">added in Encore v3.75.0 (2024-01-29)</h4><div class="usage"><code>(set-var-root! var-sym root-val)</code></div><div class="doc"><pre class="plaintext">Sets root binding (value) of the var identified by given symbol, and returns
|
||
the new value. Cross-platform. See also `update-var-root!`.</pre></div></div><div class="public anchor" id="var-signal.21"><h3>signal!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-signal.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(signal! {:as opts, :keys [elidable? location inst uid middleware sample-rate kind ns id level when rate-limit rate-limit-by ctx parent root trace? do let data msg error run & kvs]})</code></div><div class="doc"><pre class="plaintext">Low-level generic signal creator.
|
||
|
||
API: [opts] => depends on options [2]
|
||
Default kind: none (optional)
|
||
Default level: none (must be provided)
|
||
|
||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||
dispatches it to registered handlers for processing (e.g. writing to
|
||
console/file/queue/db, etc.).
|
||
|
||
If `:run` option is provided: returns value of given run form, or throws.
|
||
Otherwise: returns true iff signal was created (allowed).
|
||
|
||
Generic signals are fairly low-level and useful mostly for library authors or
|
||
advanced users writing their own wrapper macros. Regular users will typically
|
||
prefer one of the higher-level signal creators optimized for ease-of-use in
|
||
common cases [1].
|
||
|
||
Tips:
|
||
|
||
- Test using `with-signal`: (with-signal (signal! ...)).
|
||
- Supports the same options [2] as other signals [1].
|
||
|
||
----------------------------------------------------------------------
|
||
[1] See `help:signal-creators` - (`signal!`, `log!`, `event!`, ...)
|
||
[2] See `help:signal-options` - {:keys [kind level id data ...]}
|
||
[3] See `help:signal-content` - {:keys [kind level id data ...]}
|
||
[4] See `help:signal-filters` - (by ns/kind/id/level, sampling, etc.)</pre></div></div><div class="public anchor" id="var-signal-allowed.3F"><h3>signal-allowed?</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-signal-allowed.3F">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(signal-allowed? {:as opts, :keys [elidable? location sample-rate kind ns id level when rate-limit rate-limit-by]})</code></div><div class="doc"><pre class="plaintext">Returns true iff signal with given opts would meet filtering conditions:
|
||
(when (signal-allowed? {:level :warn, <...>}) (my-custom-code))
|
||
|
||
Allows you to use Telemere's rich filtering system for conditionally
|
||
executing arbitrary code. Also handy for batching multiple signals
|
||
under a single set of conditions (incl. rate-limiting, sampling, etc.):
|
||
|
||
;; Logs exactly 2 or 0 messages (never 1):
|
||
(when (signal-allowed? {:level :info, :sample-rate 0.5})
|
||
(log! {:allow? true} "Message 1")
|
||
(log! {:allow? true} "Message 2"))</pre></div></div><div class="public anchor" id="var-spy.21"><h3>spy!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-spy.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(spy! form)</code><code>(spy! level form)</code><code>(spy! {:as opts, :keys [elidable? location inst uid middleware sample-rate kind ns id level when rate-limit rate-limit-by ctx parent root trace? do let data msg error run & kvs]} form)</code></div><div class="doc"><pre class="plaintext">"Spy" signal creator, emphasizing form + level.
|
||
|
||
API: [form] [level-or-opts form] => form's result (value/throw) (unconditional)
|
||
Default kind: `:spy`
|
||
Default level: `:info`
|
||
|
||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||
dispatches it to registered handlers for processing (e.g. writing to
|
||
console/file/queue/db, etc.).
|
||
|
||
`form` is generally expected to be synchronous and eager (not a lazy seq,
|
||
async call, or IOT code like a core.async `go` block, etc.).
|
||
|
||
Examples:
|
||
|
||
(spy! (+ 1 2)) ; %> {:kind :trace, :level :info, :run-form '(+ 1 2),
|
||
; :run-val 3, :run-nsecs <int>, :parent {:keys [id uid]}
|
||
; :msg "(+ 1 2) => 3" ...}
|
||
(spy! ::my-id (+ 1 2)) ; %> {... :id ::my-id ...}
|
||
(spy!
|
||
{:let [x "x"] ; Available to `:data` and `:msg`
|
||
:data {:x x}}
|
||
|
||
(+ 1 2)) ; %> {... :data {x "x"}, :msg_ "My msg: x" ...}
|
||
|
||
Tips:
|
||
|
||
- Test using `with-signal`: (with-signal (spy! ...)).
|
||
- Supports the same options [2] as other signals [1].
|
||
|
||
- Identical to `trace!`, but emphasizes form + level rather than form + id.
|
||
|
||
- Useful for debugging/monitoring forms, and tracing (nested) execution flow.
|
||
- Execution of `form` arg may create additional (nested) signals.
|
||
Each signal's `:parent` key will indicate its immediate parent.
|
||
|
||
- Can be useful to wrap with `catch->error!`:
|
||
(catch->error! ::error-id (spy! ...)).
|
||
|
||
----------------------------------------------------------------------
|
||
[1] See `help:signal-creators` - (`signal!`, `log!`, `event!`, ...)
|
||
[2] See `help:signal-options` - {:keys [kind level id data ...]}
|
||
[3] See `help:signal-content` - {:keys [kind level id data ...]}
|
||
[4] See `help:signal-filters` - (by ns/kind/id/level, sampling, etc.)</pre></div></div><div class="public anchor" id="var-stop-handlers.21"><h3>stop-handlers!</h3><h4 class="lang"><a href="taoensso.telemere.html#var-stop-handlers.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(stop-handlers!)</code></div><div class="doc"><pre class="plaintext">Stops registered signal handlers in parallel by calling each
|
||
handler-fn with no arguments. This gives each handler the opportunity
|
||
to flush buffers, close files, etc.
|
||
|
||
Each handler will immediately stop accepting new signals, nooping if called.
|
||
|
||
Blocks to return ?{<handler-id> {:keys [okay error]}}, honouring each
|
||
handler's `:drain-msecs` value (see `help:handler-dispatch-options`).
|
||
|
||
NB you should always call `stop-handlers!` somewhere appropriate - usually
|
||
near the end of your `-main` or shutdown procedure, AFTER all other code has
|
||
completed that could create signals.</pre></div></div><div class="public anchor" id="var-trace.21"><h3>trace!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-trace.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(trace! form)</code><code>(trace! id form)</code><code>(trace! {:as opts, :keys [elidable? location inst uid middleware sample-rate kind ns id level when rate-limit rate-limit-by ctx parent root trace? do let data msg error run & kvs]} form)</code></div><div class="doc"><pre class="plaintext">"Trace" signal creator, emphasizing form + id.
|
||
|
||
API: [form] [id-or-opts form] => form's result (value/throw) (unconditional)
|
||
Default kind: `:trace`
|
||
Default level: `:info` (intentionally NOT `:trace`!)
|
||
|
||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||
dispatches it to registered handlers for processing (e.g. writing to
|
||
console/file/queue/db, etc.).
|
||
|
||
`form` is generally expected to be synchronous and eager (not a lazy seq,
|
||
async call, or IOT code like a core.async `go` block, etc.).
|
||
|
||
Examples:
|
||
|
||
(trace! (+ 1 2)) ; %> {:kind :trace, :level :info, :run-form '(+ 1 2),
|
||
; :run-val 3, :run-nsecs <int>, :parent {:keys [id uid]} ...
|
||
; :msg "(+ 1 2) => 3" ...}
|
||
(trace! ::my-id (+ 1 2)) ; %> {... :id ::my-id ...}
|
||
(trace!
|
||
{:let [x "x"] ; Available to `:data` and `:msg`
|
||
:data {:x x}}
|
||
|
||
(+ 1 2)) ; %> {... :data {x "x"}, :msg_ "My msg: x" ...}
|
||
|
||
Tips:
|
||
|
||
- Test using `with-signal`: (with-signal (trace! ...)).
|
||
- Supports the same options [2] as other signals [1].
|
||
|
||
- Identical to `spy!`, but emphasizes form + id rather than form + level.
|
||
|
||
- Useful for debugging/monitoring forms, and tracing (nested) execution flow.
|
||
- Execution of `form` arg may create additional (nested) signals.
|
||
Each signal's `:parent` key will indicate its immediate parent.
|
||
|
||
- Can be useful to wrap with `catch->error!`:
|
||
(catch->error! ::error-id (trace! ...)).
|
||
|
||
- Default level is `:info`, not `:trace`! The name "trace" in "trace signal"
|
||
refers to the general action of tracing program flow rather than to the
|
||
common logging level of the same name.
|
||
|
||
----------------------------------------------------------------------
|
||
[1] See `help:signal-creators` - (`signal!`, `log!`, `event!`, ...)
|
||
[2] See `help:signal-options` - {:keys [kind level id data ...]}
|
||
[3] See `help:signal-content` - {:keys [kind level id data ...]}
|
||
[4] See `help:signal-filters` - (by ns/kind/id/level, sampling, etc.)</pre></div></div><div class="public anchor" id="var-uncaught-.3Eerror.21"><h3>uncaught->error!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-uncaught-.3Eerror.21">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(uncaught->error!)</code><code>(uncaught->error! id)</code><code>(uncaught->error! {:as opts, :keys [elidable? location inst uid middleware sample-rate kind ns id level when rate-limit rate-limit-by ctx parent root trace? do let data msg error & kvs]})</code></div><div class="doc"><pre class="plaintext">Uses `uncaught->handler!` so that `error!` will be called for
|
||
uncaught JVM errors.
|
||
|
||
See `uncaught->handler!` and `error!` for details.</pre></div></div><div class="public anchor" id="var-update-var-root.21"><h3>update-var-root!</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-update-var-root.21">clj</a></h4><h4 class="lang current">cljs</h4><h4 class="added">added in Encore v3.68.0 (2023-09-25)</h4><div class="usage"><code>(update-var-root! var-sym update-fn)</code></div><div class="doc"><pre class="plaintext">Updates root binding (value) of the var identified by given symbol, and returns
|
||
the new value:
|
||
(update-var-root! my-var (fn [old-root-val] <new-root-val>)) => <new-root-val>
|
||
|
||
Similar to `alter-var-root` but cross-platform and takes a symbol rather than a var.
|
||
See also `set-var-root!`.</pre></div></div><div class="public anchor" id="var-with-ctx"><h3>with-ctx</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-ctx">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-ctx ctx-val form)</code></div><div class="doc"><pre class="plaintext">Evaluates given form with given `*ctx*` value. See `*ctx*` for details.
|
||
</pre></div></div><div class="public anchor" id="var-with-ctx.2B"><h3>with-ctx+</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-ctx.2B">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-ctx+ update-map-or-fn form)</code></div><div class="doc"><pre class="plaintext">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.</pre></div></div><div class="public anchor" id="var-with-err-.3Etelemere"><h3>with-err->telemere</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-err-.3Etelemere">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-err->telemere form)</code><code>(with-err->telemere opts form)</code></div><div class="doc"><pre class="plaintext">Executes form with `*err*` bound to flush to Telemere signals with given opts.
|
||
</pre></div></div><div class="public anchor" id="var-with-handler"><h3>with-handler</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-handler">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-handler handler-id handler-fn form)</code><code>(with-handler handler-id handler-fn dispatch-opts form)</code></div><div class="doc"><pre class="plaintext">Executes form with ONLY the given signal handler registered.
|
||
Stops handler after use. Useful for tests/debugging.
|
||
|
||
See `help:handler-dispatch-options` for handler filters, etc.
|
||
See also `with-handler+`.</pre></div></div><div class="public anchor" id="var-with-handler.2B"><h3>with-handler+</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-handler.2B">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-handler+ handler-id handler-fn form)</code><code>(with-handler+ handler-id handler-fn dispatch-opts form)</code></div><div class="doc"><pre class="plaintext">Executes form with the given signal handler (also) registered.
|
||
Stops handler after use. Useful for tests/debugging.
|
||
|
||
See `help:handler-dispatch-options` for handler filters, etc.
|
||
See also `with-handler`.</pre></div></div><div class="public anchor" id="var-with-id-filter"><h3>with-id-filter</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-id-filter">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-id-filter id-filter form)</code></div><div class="doc"><pre class="plaintext">Executes form with given signal id filter in effect.
|
||
See `set-id-filter!` for details.</pre></div></div><div class="public anchor" id="var-with-kind-filter"><h3>with-kind-filter</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-kind-filter">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-kind-filter kind-filter form)</code></div><div class="doc"><pre class="plaintext">Executes form with given signal kind filter in effect.
|
||
See `set-kind-filter!` for details.</pre></div></div><div class="public anchor" id="var-with-middleware"><h3>with-middleware</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-middleware">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-middleware ?middleware-fn form)</code></div><div class="doc"><pre class="plaintext">Evaluates given form with given `*middleware*` value.
|
||
See `*middleware*` for details.</pre></div></div><div class="public anchor" id="var-with-min-level"><h3>with-min-level</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-min-level">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-min-level min-level form)</code><code>(with-min-level kind min-level form)</code><code>(with-min-level kind ns-filter min-level form)</code></div><div class="doc"><pre class="plaintext">Executes form with given minimum signal level in effect.
|
||
See `set-min-level!` for details.</pre></div></div><div class="public anchor" id="var-with-ns-filter"><h3>with-ns-filter</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-ns-filter">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-ns-filter ns-filter form)</code></div><div class="doc"><pre class="plaintext">Executes form with given signal namespace filter in effect.
|
||
See `set-ns-filter!` for details.</pre></div></div><div class="public anchor" id="var-with-out-.3Etelemere"><h3>with-out->telemere</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-out-.3Etelemere">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-out->telemere form)</code><code>(with-out->telemere opts form)</code></div><div class="doc"><pre class="plaintext">Executes form with `*out*` bound to flush to Telemere signals with given opts.
|
||
</pre></div></div><div class="public anchor" id="var-with-signal"><h3>with-signal</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-signal">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-signal form)</code><code>(with-signal trap-signals? form)</code><code>(with-signal raw-msg? trap-signals? form)</code></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
Executes given form, trapping errors. Returns the LAST signal created by form.
|
||
Useful for tests/debugging.
|
||
|
||
Options:
|
||
`trap-signals?` (default false)
|
||
Should ALL signals created by form be trapped to prevent normal dispatch
|
||
to registered handlers?
|
||
|
||
`raw-msg?` (default false)
|
||
Should delayed `:msg_` in returned signal be retained as-is?
|
||
Delay is otherwise replaced by realized string.
|
||
|
||
See also `with-signals`.</pre></div></div><div class="public anchor" id="var-with-signals"><h3>with-signals</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-signals">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-signals form)</code><code>(with-signals trap-signals? form)</code><code>(with-signals raw-msgs? trap-signals? form)</code></div><div class="doc"><pre class="plaintext">Experimental, subject to change.
|
||
Like `with-signal` but returns [[<form-value> <form-error>] [<signal1> ...]].
|
||
Useful for tests/debugging.</pre></div></div><div class="public anchor" id="var-with-streams-.3Etelemere"><h3>with-streams->telemere</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-with-streams-.3Etelemere">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(with-streams->telemere form)</code><code>(with-streams->telemere {:keys [out err], :or {out default-out-opts, err default-err-opts}} form)</code></div><div class="doc"><pre class="plaintext">Executes form with `*out*` and/or `*err*` bound to flush to Telemere signals
|
||
with given opts.</pre></div></div><div class="public anchor" id="var-without-filters"><h3>without-filters</h3><h4 class="type">macro</h4><h4 class="lang"><a href="taoensso.telemere.html#var-without-filters">clj</a></h4><h4 class="lang current">cljs</h4><div class="usage"><code>(without-filters form)</code></div><div class="doc"><pre class="plaintext">Executes form without any runtime signal filters.
|
||
</pre></div></div></div></body></html> |