taoensso.telemere
*ctx*
dynamic
clj
Dynamic context: arbitrary app-level state attached as `:ctx` to all signals.
Value may be any type, but is usually nil or a map.
Re/bind dynamic value using `with-ctx`, `with-ctx+`, or `binding`.
Modify root (base) value using `set-ctx!`.
Default root (base) value is `default-ctx`.
Note that as with all dynamic Clojure vars, "binding conveyance" applies
when using futures, agents, etc.
Tips:
- Value may be (or may contain) an atom if you want mutable semantics
- Value may be of form {<scope-id> <data>} for custom scoping, etc.*middleware*
dynamic
clj
Optional vector of unary middleware fns to apply (sequentially/left-to-right)
to each signal before passing it to handlers. If any middleware fn returns nil,
aborts immediately without calling handlers.
Useful for transforming each signal before handling.
Re/bind dynamic value using `with-middleware`, `binding`.
Modify root (base) value using `set-middleware!`.
add-handler!
clj
(add-handler! handler-id handler-fn)(add-handler! handler-id handler-fn dispatch-opts)
Registers given signal handler and returns
{<handler-id> {:keys [dispatch-opts handler-fn]}} for all signal handlers
now registered.
`handler-fn` should be a fn of 1-2 arities:
([handler-arg]) => Handle the given argument (e.g. write to disk/db, etc.)
([]) => Optional arity, called exactly once on system shutdown.
Provides an opportunity for handler to close/release
any resources that it may have opened/acquired.
See the relevant docstring/s for `handler-arg` details.
Handler ideas:
Save to a 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.
Dispatch options include:
`async` (Clj only)
Options for running handler asynchronously via `taoensso.encore/runner`,
{:keys [mode buffer-size n-threads daemon-threads? ...]}
Supports `:blocking`, `:dropping`, and `:sliding` back pressure modes.
NB handling order may be non-sequential when `n-threads` > 1.
`priority`
Optional handler priority ∈ℤ (default 100). Handlers will be called in
descending priority order.
`sample-rate`
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
`ns-filter` - Namespace filter as in `set-ns-filter!`
`kind-filter` - Kind filter as in `set-kind-filter!` (when relevant)
`id-filter` - Id filter as in `set-id-filter!` (when relevant)
`min-level` - Minimum level as in `set-min-level!`
`filter-fn`
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.
`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`
Optional vector of unary middleware fns to apply (left-to-right/sequentially)
to `handler-arg` before passing to `handler-fn`. If any middleware fn returns
nil, aborts immediately without calling `handler-fn`.
Useful for transforming `handler-arg` before handling.
`error-fn` - (fn [{:keys [handler-id handler-arg error]}]) to call on handler error.
`backp-fn` - (fn [{:keys [handler-id ]}]) to call on handler back pressure.
Flow sequence:
1. Per call (n=1):
a. Sampling
b. Filtering (namespace, kind, id, level, filter-fn)
c. Rate limiting
d. Middleware
2. Per handler (n>=0):
a. Sampling
b. Filtering (namespace, kind, id, level, filter-fn)
c. Rate limiting
d. Middleware
e. Hander fn
Note: call filters should generally be at least as permissive as handler filters,
otherwise calls will be suppressed before reaching handlers.catch->error!
macro
clj
(catch->error! form)(catch->error! level form)(catch->error! {:as opts, :keys [rethrow? catch-val elidable? location instant uid middleware sample-rate ns kind id level filter when rate-limit ctx parent trace? let data msg error & user-opts]} form)
TODO Docstring [form] [id-or-opts form] => run value or ?catch-val
chance
clj
(chance prob)
Returns true with given probability ∈ ℝ[0,1].
check-interop
clj
(check-interop)
Experimental, subject to change.
Runs Telemere's registered interop checks and returns
{<interop-id> {:keys [sending->telemere? telemere-receiving? ...]}}.
Useful for tests/debugging.default-ctx
clj
Advanced feature. Default root (base) value of `*ctx*` var, controlled by:
(get-env {:as :edn} :taoensso.telemere/default-ctx<.platform><.edn>)
See `get-env` for details.error!
macro
clj
(error! error)(error! id error)(error! {:as opts, :keys [elidable? location instant uid middleware sample-rate ns kind id level filter when rate-limit ctx parent trace? let data msg error & user-opts]} error)
TODO Docstring [error] [id-or-opts error] => error
(throw (error! <error>)) example.
event!
macro
clj
(event! id)(event! level id)(event! {:as opts, :keys [elidable? location instant uid middleware sample-rate ns kind id level filter when rate-limit ctx parent trace? let data msg error & user-opts]} id)
TODO Docstring [id] [level-or-opts id] => allowed?
filtering-help
clj
Your filter config determines which signal calls will be enabled.
Filtering can occur at compile-time (=> elision), or runtime.
Both compile-time and runtime config can be specified via:
1. System values (JVM properties, environment variables, or
classpath resources). See library docs for details.
2. The filter API consting of the following:
`set-ns-filter!`, `with-ns-filter` - for filtering calls by namespace
`set-minimum-level!`, `with-minimum-level!` - for filtering calls by signal level
`set-id-filter!`, `with-id-filter` - for filtering calls by signal id (when relevant)
`set-kind-filter!`, `with-kind-filter` - for filtering calls by signal kind (when relevant)
See the relevant docstrings for details.
Additional filtering can also be applied on a per-handler basis, see
`add-handler!` for details.
See also:
`get-filters` - to see current filter config
`get-min-level` - to see current minimum level
`without-filters` - to disable all runtime filtering
If anything is unclear, please ping me (@ptaoussanis) so that I can
improve these docs!get-env
macro
clj
added in Encore v3.75.0 (2024-01-29)
(get-env {:keys [as default return]} spec)(get-env {:keys [as default return spec], :or {as :str, return :value}})
Cross-platform util for embedding flexible environmental config during
macro expansion. Used by other Taoensso libraries.
Given a const kw/string id or vector of desc-priority alternative ids,
parse and return the first of the following that exists:
- JVM property value for id ("prop")
- Environment variable value for id ("env")
- Classpath resource content for id ("res")
Ids may include optional segment in `<>` tag (e.g. `<.edn>`).
Ids may include `<.?platform.?>` tag for auto replacement, useful
for supporting platform-specific config.
Search order: desc by combined [alt-index platform(y/n) optional(y/n)].
(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 (content type)
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 (content type)
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 (content type)
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 (content type)
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 if no value found during search (default nil).
`:return` - Return type ∈ #{:value :map :debug} (default :value).
TIP: Use `:debug` to inspect/verify search behaviour!
Result must be something that can be safely embedded in code during
macro-expansion. Symbols in edn will be evaluated during expansion.get-filters
clj
(get-filters)
Returns current ?{:keys [compile-time runtime]} filter config.
get-handlers
clj
(get-handlers)
Returns ?{<handler-id> {:keys [dispatch-opts handler-fn]}} for all
registered signal handlers.get-min-level
clj
(get-min-level)(get-min-level kind)(get-min-level kind ns)
Returns current ?{:keys [compile-time runtime]} minimum levels.
handlers-help
clj
The handler API consists of the following:
`get-handlers` - Returns info on currently registered handlers
`add-handler!` - Used to register handlers
`remove-handler!` - Used to unregister handlers
See the relevant docstrings for details.
If anything is unclear, please ping me (@ptaoussanis) so that I can
improve these docs!
hostname
clj
(hostname)(hostname timeout-msecs timeout-val)
Returns local cached hostname string, or `timeout-val` (default "UnknownHost").
level-aliases
clj
Map of {<level-keyword> <level-integer>} aliases.
log!
macro
clj
(log! msg)(log! level msg)(log! {:as opts, :keys [elidable? location instant uid middleware sample-rate ns kind id level filter when rate-limit ctx parent trace? let data msg error & user-opts]} msg)
TODO Docstring [msg] [level-or-opts msg] => allowed?
msg-splice
clj
(msg-splice args)
newline
clj
added in Encore v3.68.0 (2023-09-25)
rate-limiter
clj
(rate-limiter spec)(rate-limiter opts spec)
Takes a map spec of form {<limit-id> [<n-max-reqs> <msecs-window>]},
and returns a basic stateful (fn rate-limiter [req-id] [command req-id]).
Call fn with a single request id (e.g. username) by which to count/limit.
Will return:
- nil when all limits pass for that id, or
- [<worst-limit-id> <worst-backoff-msecs> {<limit-id> <backoff-msecs>}]
when any limits fail for that id.
Or call fn with an additional command argument:
`:rl/peek` <req-id> - Check limits w/o incrementing count.
`:rl/reset` <req-id> - Reset all limits for given req-id.
Example:
(defonce my-rate-limiter
(rate-limiter
{"1 per sec" [1 1000]
"10 per min" [10 60000]}))
(defn send-message! [username msg-content]
(if-let [fail (my-rate-limiter username)]
(throw (ex-info "Sorry, rate limited!" {:fail fail}))
<send message>))remove-handler!
clj
(remove-handler! handler-id)
Deregisters signal handler with given id, and returns
?{<handler-id> {:keys [dispatch-opts handler-fn]}} for all signal handlers
still registered.set-ctx!
macro
clj
(set-ctx! root-val)
Set `*ctx*` var's root (base) value. See `*ctx*` for details.
set-id-filter!
clj
(set-id-filter! id-filter)
Sets signal call id filter based on given `id-filter` spec.
`id-filter` may be:
- A regex pattern of id/s to allow.
- A str/kw/sym, in which "*"s act as wildcards.
- A vector or set of regex patterns or strs/kws/syms.
- {:allow <spec> :deny <spec>} with specs as above.set-kind-filter!
clj
(set-kind-filter! kind-filter)
Sets signal call kind filter based on given `kind-filter` spec.
`kind-filter` may be:
- A regex pattern of kind/s to allow.
- A str/kw/sym, in which "*"s act as wildcards.
- A vector or set of regex patterns or strs/kws/syms.
- {:allow <spec> :deny <spec>} with specs as above.set-middleware!
macro
clj
(set-middleware! root-val)
Set `*middleware*` var's root (base) value. See `*middleware*` for details.
set-min-level!
clj
(set-min-level! min-level)(set-min-level! kind min-level)(set-min-level! kind ns-filter min-level)
Sets minimum signal call level based on given `min-level` spec.
`min-level` may be:
- An integer.
- A level keyword (see `level-aliases` var for details).
If `ns-filter` is provided, then the given minimum level
will apply only for namespaces 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.
set-ns-filter!
clj
(set-ns-filter! ns-filter)
Sets signal call namespace filter based on given `ns-filter` spec.
`ns-filter` may be:
- A regex pattern of namespace/s to allow.
- A str/kw/sym, in which "*"s act as wildcards.
- A vector or set of regex patterns or strs/kws/syms.
- {:allow <spec> :deny <spec>} with specs as above.set-var-root!
macro
clj
added in Encore v3.75.0 (2024-01-29)
(set-var-root! var-sym root-val)
Sets root binding (value) of the var identified by given symbol, and returns
the new value. Cross-platform. See also `update-var-root!`.
signal!
macro
clj
(signal! {:as opts, :keys [elidable? location instant uid middleware sample-rate ns kind id level filter when rate-limit ctx parent trace? let data msg error run & user-opts]})
Expands to a low-level signal call.
TODO Docstring
- How low-level is this? Should location, ctx, etc. be in public arglists?
- Describe
- Reference diagram link [1]
- Mention ability to delay-wrap :data
- Mention combo `:sample-rate` stuff (call * handler)
- If :run => returns body run-result (re-throwing)
Otherwise returns true iff call allowed
[1] Ref. <https://github.com/taoensso/telemere/blob/master/signal-flow.svg>
spy!
macro
clj
(spy! form)(spy! id form)(spy! {:as opts, :keys [elidable? location instant uid middleware sample-rate ns kind id level filter when rate-limit ctx parent trace? let data msg error run & user-opts]} form)
TODO Docstring [form] [level-or-opts form] => run result (value or throw)
streams->reset!
clj
(streams->reset!)
Experimental, subject to change without notice!
Resets `System/out` and `System/err` to their original value (prior to any
`streams->telemere!` call).
streams->telemere!
clj
(streams->telemere!)(streams->telemere! {:keys [out err], :or {out default-out-opts, err default-err-opts}})
Experimental, subject to change without notice!
When given `out`, sets JVM's `System/out` to flush to Telemere signals with those opts.
When given `err`, sets JVM's `System/err` to flush to Telemere signals with those opts.
Note that setting `System/out` won't necessarily affect Clojure's `*out*`,
and setting `System/err` won't necessarily affect Clojure's `*err*`.
See also:
`with-out->telemere`,
`with-err->telemere`,
`with-streams->telemere`.
thread-name
clj
(thread-name)
trace!
macro
clj
(trace! form)(trace! id form)(trace! {:as opts, :keys [elidable? location instant uid middleware sample-rate ns kind id level filter when rate-limit ctx parent trace? let data msg error run & user-opts]} form)
TODO Docstring [form] [id-or-opts form] => run result (value or throw)
uncaught->error!
macro
clj
(uncaught->error!)(uncaught->error! id)(uncaught->error! {:as opts, :keys [elidable? location instant uid middleware sample-rate ns kind id level filter when rate-limit ctx parent trace? let data msg error & user-opts]})
TODO Docstring
See also `uncaught->handler!`.
uncaught->handler!
clj
(uncaught->handler! handler)
Sets JVM's global `DefaultUncaughtExceptionHandler` to given
(fn handler [`<java.lang.Thread>` `<java.lang.Throwable>`]).
See also `uncaught->error!`.
update-var-root!
macro
clj
added in Encore v3.68.0 (2023-09-25)
(update-var-root! var-sym update-fn)
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!`.
with-ctx
macro
clj
(with-ctx init-val form)
Evaluates given form with given `*ctx*` value. See `*ctx*` for details.
with-ctx+
macro
clj
(with-ctx+ update-map-or-fn form)
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.
with-err->telemere
macro
clj
(with-err->telemere form)(with-err->telemere opts form)
Executes form with `*err*` bound to flush to Telemere signals with given opts.
with-handler
macro
clj
(with-handler handler-id handler-fn dispatch-opts form)
Executes form with ONLY the given handler-fn registered.
Useful for tests/debugging. See also `with-handler+`.
with-handler+
macro
clj
(with-handler+ handler-id handler-fn dispatch-opts form)
Executes form with the given handler-fn registered.
Useful for tests/debugging. See also `with-handler`.
with-id-filter
macro
clj
(with-id-filter id-filter form)
Executes form with given signal call id filter in effect.
See `set-id-filter!` for details.
with-kind-filter
macro
clj
(with-kind-filter kind-filter form)
Executes form with given signal call kind filter in effect.
See `set-kind-filter!` for details.
with-middleware
macro
clj
(with-middleware init-val form)
Evaluates given form with given `*middleware*` value.
See `*middleware*` for details.
with-min-level
macro
clj
(with-min-level min-level form)(with-min-level kind min-level form)(with-min-level kind ns-filter min-level form)
Executes form with given minimum signal call level in effect.
See `set-min-level!` for details.
with-ns-filter
macro
clj
(with-ns-filter ns-filter form)
Executes form with given signal call namespace filter in effect.
See `set-ns-filter!` for details.
with-out->telemere
macro
clj
(with-out->telemere form)(with-out->telemere opts form)
Executes form with `*out*` bound to flush to Telemere signals with given opts.
with-signal
macro
clj
(with-signal form)(with-signal {:keys [return trap-errors? stop-propagation? force-msg?]} form)
Util for tests/debugging.
Executes given form and returns [<form-result> <last-signal-dispatched-by-form>].
If `trap-errors?` is true, form result will be wrapped by {:keys [okay error]}.with-streams->telemere
macro
clj
(with-streams->telemere form)(with-streams->telemere {:keys [out err], :or {out default-out-opts, err default-err-opts}} form)
Executes form with `*out*` and/or `*err*` bound to flush to Telemere signals
with given opts.
without-filters
macro
clj
(without-filters form)
Executes form without any runtime filters.