mirror of
https://github.com/taoensso/telemere.git
synced 2025-12-17 01:51:10 +00:00
[new] Refactor impln of common signal creators
Objectives:
- Support single map opts arg in all cases.
- Make it easier for folks to inspect the source to understand how
the common creators use/wrap underlying `signal!`.
Also updated relevant docstrings, etc.
This commit is contained in:
parent
ace6e2dd2c
commit
d2386d62f1
12 changed files with 265 additions and 376 deletions
|
|
@ -1,10 +1,9 @@
|
||||||
Unconditionally executes given form and-
|
ALWAYS (unconditionally) executes given `run` form and:
|
||||||
If form succeeds: return the form's result.
|
If `run` form succeeds: return the form's result.
|
||||||
If form throws:
|
If `run` form throws:
|
||||||
Call `error!` with the thrown error and the given signal options [2],
|
Call `error!` with the thrown error and the given signal options [2],
|
||||||
then return (:catch-val opts) if it exists, or rethrow the error.
|
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 kind: `:error`
|
||||||
Default level: `:error`
|
Default level: `:error`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"Error" signal creator, emphasizing error + id.
|
"Error" signal creator, emphasizing (optional id) + error (Exception, etc.).
|
||||||
|
ALWAYS (unconditionally) returns the given error, so can conveniently be wrapped
|
||||||
|
by `throw`: (throw (error! (ex-info ...)), etc.
|
||||||
|
|
||||||
API: [error] [id-or-opts error] => given error (unconditional)
|
|
||||||
Default kind: `:error`
|
Default kind: `:error`
|
||||||
Default level: `:error`
|
Default level: `:error`
|
||||||
|
|
||||||
|
|
@ -22,7 +23,6 @@ Tips:
|
||||||
- Supports the same options [2] as other signals [1].
|
- Supports the same options [2] as other signals [1].
|
||||||
|
|
||||||
- `error` arg is a platform error (`java.lang.Throwable` or `js/Error`).
|
- `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!`, ...)
|
[1] See `help:signal-creators` - (`signal!`, `log!`, `event!`, ...)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"Event" signal creator, emphasizing id + level.
|
"Event" signal creator, emphasizing id + (optional level).
|
||||||
|
Returns true iff signal was created (allowed by filtering).
|
||||||
|
|
||||||
API: [id] [id level-or-opts] => true iff signal was allowed
|
|
||||||
Default kind: `:event`
|
Default kind: `:event`
|
||||||
Default level: `:info`
|
Default level: `:info`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"Log" signal creator, emphasizing message + level.
|
"Log" signal creator, emphasizing (optional level) + message.
|
||||||
|
Returns true iff signal was created (allowed by filtering).
|
||||||
|
|
||||||
API: [msg] [level-or-opts msg] => true iff signal was allowed.
|
|
||||||
Default kind: `:log`
|
Default kind: `:log`
|
||||||
Default level: `:info`
|
Default level: `:info`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
Low-level generic signal creator.
|
Low-level "generic" signal creator for creating signals of any "kind".
|
||||||
|
Takes a single map of options [2] with compile-time keys.
|
||||||
|
|
||||||
API: [opts] => depends on options [2]
|
Return value depends on options:
|
||||||
Default kind: `:generic`
|
- If given `:run` form: unconditionally returns run value, or rethrows run error.
|
||||||
|
- Otherwise: returns true iff signal was created (allowed by filtering).
|
||||||
|
|
||||||
|
Default kind: `:generic` (feel free to change!)
|
||||||
Default level: `:info`
|
Default level: `:info`
|
||||||
|
|
||||||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||||||
dispatches it to registered handlers for processing (e.g. writing to
|
dispatches it to registered handlers for processing (e.g. writing to
|
||||||
console/file/queue/db, etc.).
|
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
|
Generic signals are fairly low-level and useful mostly for library authors or
|
||||||
advanced users writing their own wrapper macros. Regular users will typically
|
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
|
prefer one of the higher-level signal creators optimized for ease-of-use in
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@ various keys:
|
||||||
Creators vary only in in their default options and call APIs (expected args
|
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:
|
and return values), making them more/less convenient for certain use cases:
|
||||||
|
|
||||||
`event!` -------- [id ] or [id opts/level] => true iff signal was created (allowed)
|
`signal!` ------- opts => allowed? / unconditional run result (value or throw)
|
||||||
`log!` ---------- [msg ] or [opts/level msg] => true iff signal was created (allowed)
|
`event!` -------- id + ?level => allowed?
|
||||||
`error!` -------- [error] or [opts/id error] => given error (unconditional)
|
`log!` ---------- ?level + msg => allowed?
|
||||||
`trace!` -------- [form ] or [opts/id form] => form result (value/throw) (unconditional)
|
`trace!` -------- ?id + run => unconditional run result (value or throw)
|
||||||
`spy!` ---------- [form ] or [opts/level form] => form result (value/throw) (unconditional)
|
`spy!` ---------- ?level + run => unconditional run result (value or throw)
|
||||||
`catch->error!` - [form ] or [opts/id form] => form value, or given fallback
|
`error!` -------- ?id + error => unconditional given error
|
||||||
`signal!` ------- [opts ] => depends on options
|
`catch->error!` - ?id + run => unconditional run value or ?catch-val
|
||||||
|
|
||||||
- `log!` and `event!` are both good default/general-purpose signal creators.
|
- `log!` and `event!` are both good default/general-purpose signal creators.
|
||||||
- `log!` emphasizes messages, while `event!` emphasizes ids.
|
- `log!` emphasizes messages, while `event!` emphasizes ids.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"Spy" signal creator, emphasizing form + level.
|
"Spy" signal creator, emphasizing (optional level) + form to run.
|
||||||
|
ALWAYS (unconditionally) returns run value, or rethrows run error.
|
||||||
|
|
||||||
API: [form] [level-or-opts form] => form's result (value/throw) (unconditional)
|
|
||||||
Default kind: `:spy`
|
Default kind: `:spy`
|
||||||
Default level: `:info`
|
Default level: `:info`
|
||||||
|
|
||||||
|
|
@ -8,14 +8,14 @@ When filtering conditions are met [4], creates a Telemere signal [3] and
|
||||||
dispatches it to registered handlers for processing (e.g. writing to
|
dispatches it to registered handlers for processing (e.g. writing to
|
||||||
console/file/queue/db, etc.).
|
console/file/queue/db, etc.).
|
||||||
|
|
||||||
Enables tracing of given `form` arg:
|
Enables tracing of given `run` form:
|
||||||
|
|
||||||
- Resulting signal will include {:keys [run-form run-val run-nsecs]}.
|
- Resulting signal will include {:keys [run-form run-val run-nsecs]}.
|
||||||
- Nested signals will include this signal's id and uid under `:parent`.
|
- Nested signals will include this signal's id and uid under `:parent`.
|
||||||
|
|
||||||
Limitations:
|
Limitations:
|
||||||
|
|
||||||
1. Traced code (`form` arg) is usually expected to be synchronous and eager.
|
1. Traced `run` form is usually expected to be synchronous and eager.
|
||||||
So no lazy seqs, async calls, or inversion of flow control (IoC) macros like
|
So no lazy seqs, async calls, or inversion of flow control (IoC) macros like
|
||||||
core.async `go` blocks, etc.
|
core.async `go` blocks, etc.
|
||||||
|
|
||||||
|
|
@ -47,18 +47,18 @@ Tips:
|
||||||
- Test using `with-signal`: (with-signal (spy! ...)).
|
- Test using `with-signal`: (with-signal (spy! ...)).
|
||||||
- Supports the same options [2] as other signals [1].
|
- Supports the same options [2] as other signals [1].
|
||||||
|
|
||||||
- Identical to `trace!`, but emphasizes form + level rather than form + id.
|
- Like `trace!`, but takes optional level rather than optional id.
|
||||||
|
|
||||||
- Useful for debugging/monitoring forms, and tracing (nested) execution flow.
|
- Useful for debugging/monitoring forms, and tracing (nested) execution flow.
|
||||||
- Execution of `form` arg may create additional (nested) signals.
|
- Execution of `run` form may create additional (nested) signals.
|
||||||
Each signal's `:parent` key will indicate its immediate parent.
|
Each signal's `:parent` key will indicate its immediate parent.
|
||||||
|
|
||||||
- Can be useful to wrap with `catch->error!`:
|
- Can be useful to wrap with `catch->error!`:
|
||||||
(catch->error! ::error-id (spy! ...)).
|
(catch->error! ::error-id (spy! ...)).
|
||||||
|
|
||||||
- Runtime of async or lazy code in `form` will intentionally NOT be included
|
- Runtime of async or lazy code in `run` form will intentionally NOT be
|
||||||
in resulting signal's `:run-nsecs` value. If you want to measure such
|
included in resulting signal's `:run-nsecs` value. If you want to measure
|
||||||
runtimes, make sure that your form wraps where the relevant costs are
|
such runtimes, make sure that your form wraps where the relevant costs are
|
||||||
actually realized. Compare:
|
actually realized. Compare:
|
||||||
(spy! (delay (my-slow-code))) ; Doesn't measure slow code
|
(spy! (delay (my-slow-code))) ; Doesn't measure slow code
|
||||||
(spy! @(delay (my-slow-code))) ; Does measure slow code
|
(spy! @(delay (my-slow-code))) ; Does measure slow code
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"Trace" signal creator, emphasizing form + id.
|
"Trace" signal creator, emphasizing (optional id) + form to run.
|
||||||
|
ALWAYS (unconditionally) returns run value, or rethrows run error.
|
||||||
|
|
||||||
API: [form] [id-or-opts form] => form's result (value/throw) (unconditional)
|
|
||||||
Default kind: `:trace`
|
Default kind: `:trace`
|
||||||
Default level: `:info` (intentionally NOT `:trace`!)
|
Default level: `:info` (intentionally NOT `:trace`!)
|
||||||
|
|
||||||
|
|
@ -8,14 +8,14 @@ When filtering conditions are met [4], creates a Telemere signal [3] and
|
||||||
dispatches it to registered handlers for processing (e.g. writing to
|
dispatches it to registered handlers for processing (e.g. writing to
|
||||||
console/file/queue/db, etc.).
|
console/file/queue/db, etc.).
|
||||||
|
|
||||||
Enables tracing of given `form` arg:
|
Enables tracing of given `run` form:
|
||||||
|
|
||||||
- Resulting signal will include {:keys [run-form run-val run-nsecs]}.
|
- Resulting signal will include {:keys [run-form run-val run-nsecs]}.
|
||||||
- Nested signals will include this signal's id and uid under `:parent`.
|
- Nested signals will include this signal's id and uid under `:parent`.
|
||||||
|
|
||||||
Limitations:
|
Limitations:
|
||||||
|
|
||||||
1. Traced code (`form` arg) is usually expected to be synchronous and eager.
|
1. Traced `run` form is usually expected to be synchronous and eager.
|
||||||
So no lazy seqs, async calls, or inversion of flow control (IoC) macros like
|
So no lazy seqs, async calls, or inversion of flow control (IoC) macros like
|
||||||
core.async `go` blocks, etc.
|
core.async `go` blocks, etc.
|
||||||
|
|
||||||
|
|
@ -47,10 +47,10 @@ Tips:
|
||||||
- Test using `with-signal`: (with-signal (trace! ...)).
|
- Test using `with-signal`: (with-signal (trace! ...)).
|
||||||
- Supports the same options [2] as other signals [1].
|
- Supports the same options [2] as other signals [1].
|
||||||
|
|
||||||
- Identical to `spy!`, but emphasizes form + id rather than form + level.
|
- Like `spy!`, but takes optional id rather than optional level.
|
||||||
|
|
||||||
- Useful for debugging/monitoring forms, and tracing (nested) execution flow.
|
- Useful for debugging/monitoring forms, and tracing (nested) execution flow.
|
||||||
- Execution of `form` arg may create additional (nested) signals.
|
- Execution of `run` form may create additional (nested) signals.
|
||||||
Each signal's `:parent` key will indicate its immediate parent.
|
Each signal's `:parent` key will indicate its immediate parent.
|
||||||
|
|
||||||
- Can be useful to wrap with `catch->error!`:
|
- Can be useful to wrap with `catch->error!`:
|
||||||
|
|
@ -60,9 +60,9 @@ Tips:
|
||||||
refers to the general action of tracing program flow rather than to the
|
refers to the general action of tracing program flow rather than to the
|
||||||
common logging level of the same name.
|
common logging level of the same name.
|
||||||
|
|
||||||
- Runtime of async or lazy code in `form` will intentionally NOT be included
|
- Runtime of async or lazy code in `run` form will intentionally NOT be
|
||||||
in resulting signal's `:run-nsecs` value. If you want to measure such
|
included in resulting signal's `:run-nsecs` value. If you want to measure
|
||||||
runtimes, make sure that your form wraps where the relevant costs are
|
such runtimes, make sure that your form wraps where the relevant costs are
|
||||||
actually realized. Compare:
|
actually realized. Compare:
|
||||||
(trace! (delay (my-slow-code))) ; Doesn't measure slow code
|
(trace! (delay (my-slow-code))) ; Doesn't measure slow code
|
||||||
(trace! @(delay (my-slow-code))) ; Does measure slow code
|
(trace! @(delay (my-slow-code))) ; Does measure slow code
|
||||||
|
|
|
||||||
|
|
@ -198,154 +198,102 @@
|
||||||
(comment (enc/qb 1e6 (force *otel-tracer*))) ; 51.23
|
(comment (enc/qb 1e6 (force *otel-tracer*))) ; 51.23
|
||||||
|
|
||||||
;;;; Signal creators
|
;;;; Signal creators
|
||||||
;; - event! [id ] [id opts/level] ; id + ?level => allowed? ; Sole signal with descending main arg!
|
;; - signal! ---------- opts => allowed? / unconditional run result (value or throw)
|
||||||
;; - log! [msg ] [opts/level msg] ; msg + ?level => allowed?
|
;; - event! ----------- id + ?level => allowed?
|
||||||
;; - error! [error] [opts/id error] ; error + ?id => given error
|
;; - log! ------------- ?level + msg => allowed?
|
||||||
;; - trace! [form ] [opts/id form] ; run + ?id => run result (value or throw)
|
;; - trace! ----------- ?id + run => unconditional run result (value or throw)
|
||||||
;; - spy! [form ] [opts/level form] ; run + ?level => run result (value or throw)
|
;; - spy! ------------- ?level + run => unconditional run result (value or throw)
|
||||||
;; - catch->error! [form ] [opts/id form] ; run + ?id => run value or ?return
|
;; - error! ----------- ?id + error => unconditional given error
|
||||||
;; - signal! [opts ] ; => allowed? / run result (value or throw)
|
;; - catch->error! ---- ?id + run => unconditional run value or ?catch-val
|
||||||
;; - uncaught->error! [opts/id] ; ?id => nil
|
;; - uncaught->error! - ?id => nil
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
|
(defn- merge-or-assoc-opts [m &form &env k v]
|
||||||
|
(let [m (assoc m :location* (enc/get-source &form &env))]
|
||||||
|
(if (map? v)
|
||||||
|
(merge m v)
|
||||||
|
(assoc m k v)))))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(let [base-opts {:kind :event, :level :info}]
|
||||||
(defmacro event!
|
(defmacro event!
|
||||||
"[id] [id level-or-opts] => allowed?"
|
"id + ?level => allowed? Note unique arg order: [x opts] rather than [opts x]!"
|
||||||
{:doc (impl/signal-docstring :event!)
|
{:doc (impl/signal-docstring :event!)
|
||||||
:arglists (impl/signal-arglists :event!)}
|
:arglists (impl/signal-arglists :event!)}
|
||||||
[& args]
|
([ opts-or-id] `(impl/signal! ~(merge-or-assoc-opts base-opts &form &env :id opts-or-id)))
|
||||||
(let [opts
|
([id opts-or-level] `(impl/signal! ~(assoc (merge-or-assoc-opts base-opts &form &env :level opts-or-level) :id id))))))
|
||||||
(impl/signal-opts `event! (enc/get-source &form &env)
|
|
||||||
{:kind :event, :level :info} :id :level :dsc args)]
|
|
||||||
`(impl/signal! ~opts))))
|
|
||||||
|
|
||||||
(comment (with-signal (event! ::my-id :info)))
|
(comment (with-signal (event! ::my-id :info)))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
|
(let [base-opts {:kind :log, :level :info}]
|
||||||
(defmacro log!
|
(defmacro log!
|
||||||
"[msg] [level-or-opts msg] => allowed?"
|
"?level + msg => allowed?"
|
||||||
{:doc (impl/signal-docstring :log!)
|
{:doc (impl/signal-docstring :log!)
|
||||||
:arglists (impl/signal-arglists :log!)}
|
:arglists (impl/signal-arglists :log!)}
|
||||||
[& args]
|
([opts-or-msg ] `(impl/signal! ~(merge-or-assoc-opts base-opts &form &env :msg opts-or-msg)))
|
||||||
(let [opts
|
([opts-or-level msg] `(impl/signal! ~(assoc (merge-or-assoc-opts base-opts &form &env :level opts-or-level) :msg msg))))))
|
||||||
(impl/signal-opts `log! (enc/get-source &form &env)
|
|
||||||
{:kind :log, :level :info} :msg :level :asc args)]
|
|
||||||
`(impl/signal! ~opts))))
|
|
||||||
|
|
||||||
(comment (with-signal (log! :info "My msg")))
|
(comment (with-signal (log! :info "My msg")))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
|
(let [base-opts {:kind :trace, :level :info, :msg `impl/default-trace-msg}]
|
||||||
|
(defmacro trace!
|
||||||
|
"?id + run => unconditional run result (value or throw)."
|
||||||
|
{:doc (impl/signal-docstring :trace!)
|
||||||
|
:arglists (impl/signal-arglists :trace!)}
|
||||||
|
([opts-or-run] `(impl/signal! ~(merge-or-assoc-opts base-opts &form &env :run opts-or-run)))
|
||||||
|
([opts-or-id run] `(impl/signal! ~(assoc (merge-or-assoc-opts base-opts &form &env :id opts-or-id) :run run))))))
|
||||||
|
|
||||||
|
(comment (with-signal (trace! ::my-id (+ 1 2))))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(let [base-opts {:kind :spy, :level :info, :msg `impl/default-trace-msg}]
|
||||||
|
(defmacro spy!
|
||||||
|
"?level + run => unconditional run result (value or throw)."
|
||||||
|
{:doc (impl/signal-docstring :spy!)
|
||||||
|
:arglists (impl/signal-arglists :spy!)}
|
||||||
|
([opts-or-run] `(impl/signal! ~(merge-or-assoc-opts base-opts &form &env :run opts-or-run)))
|
||||||
|
([opts-or-level run] `(impl/signal! ~(assoc (merge-or-assoc-opts base-opts &form &env :level opts-or-level) :run run))))))
|
||||||
|
|
||||||
|
(comment (with-signals (spy! :info (+ 1 2))))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(let [base-opts {:kind :error, :level :error}]
|
||||||
(defmacro error!
|
(defmacro error!
|
||||||
"[error] [error id-or-opts] => error"
|
"?id + error => unconditional given error."
|
||||||
{:doc (impl/signal-docstring :error!)
|
{:doc (impl/signal-docstring :error!)
|
||||||
:arglists (impl/signal-arglists :error!)}
|
:arglists (impl/signal-arglists :error!)}
|
||||||
[& args]
|
([opts-or-id error] `(error! ~(assoc (merge-or-assoc-opts base-opts &form &env :id opts-or-id) :error error)))
|
||||||
(let [opts
|
([opts-or-error]
|
||||||
(impl/signal-opts `error! (enc/get-source &form &env)
|
(let [opts (merge-or-assoc-opts base-opts &form &env :error opts-or-error)]
|
||||||
{:kind :error, :level :error} :error :id :asc args)
|
`(let [~'__error ~(get opts :error)]
|
||||||
error-form (get opts :error)]
|
|
||||||
|
|
||||||
`(let [~'__error ~error-form]
|
|
||||||
(impl/signal! ~(assoc opts :error '__error))
|
(impl/signal! ~(assoc opts :error '__error))
|
||||||
~'__error ; Unconditional!
|
(do ~'__error)))))))
|
||||||
))))
|
|
||||||
|
|
||||||
(comment (with-signal (throw (error! ::my-id (ex-info "MyEx" {})))))
|
(comment (with-signal (throw (error! ::my-id (ex-info "MyEx" {})))))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
|
(let [base-opts {:kind :error, :level :error}]
|
||||||
(defmacro catch->error!
|
(defmacro catch->error!
|
||||||
"[form] [id-or-opts form] => run value or ?catch-val"
|
"?id + run => unconditional run value or ?catch-val."
|
||||||
{:doc (impl/signal-docstring :catch-to-error!)
|
{:doc (impl/signal-docstring :catch->error!)
|
||||||
:arglists (impl/signal-arglists :catch->error!)}
|
:arglists (impl/signal-arglists :catch->error!)}
|
||||||
[& args]
|
([opts-or-id run] `(catch->error! ~(assoc (merge-or-assoc-opts base-opts &form &env :id opts-or-id) :run run)))
|
||||||
(let [opts
|
([opts-or-run]
|
||||||
(impl/signal-opts `catch->error! (enc/get-source &form &env)
|
(let [opts (merge-or-assoc-opts base-opts &form &env :run opts-or-run)
|
||||||
{:kind :error, :level :error} ::__form :id :asc args)
|
|
||||||
|
|
||||||
rethrow? (if (contains? opts :catch-val) false (get opts :rethrow? true))
|
rethrow? (if (contains? opts :catch-val) false (get opts :rethrow? true))
|
||||||
catch-val (get opts :catch-val)
|
catch-val (get opts :catch-val)
|
||||||
catch-sym (get opts :catch-sym '__caught-error) ; Undocumented
|
catch-sym (get opts :catch-sym '__caught-error) ; Undocumented
|
||||||
form (get opts ::__form)
|
run-form (get opts :run)
|
||||||
opts (dissoc opts ::__form :catch-val :catch-sym :rethrow?)]
|
opts (dissoc opts :run :catch-val :catch-sym :rethrow?)]
|
||||||
|
|
||||||
`(enc/try* ~form
|
`(enc/try* ~run-form
|
||||||
(catch :all ~catch-sym
|
(catch :all ~catch-sym
|
||||||
(impl/signal! ~(assoc opts :error catch-sym))
|
(impl/signal! ~(assoc opts :error catch-sym))
|
||||||
(if ~rethrow? (throw ~catch-sym) ~catch-val))))))
|
(if ~rethrow? (throw ~catch-sym) ~catch-val))))))))
|
||||||
|
|
||||||
(comment
|
(comment (with-signal (catch->error! ::my-id (/ 1 0))))
|
||||||
(with-signal (catch->error! ::my-id (/ 1 0)))
|
|
||||||
(with-signal (catch->error! { :msg ["Error:" __caught-error]} (/ 1 0)))
|
|
||||||
(with-signal (catch->error! {:catch-sym my-err :msg ["Error:" my-err]} (/ 1 0))))
|
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(defmacro trace!
|
|
||||||
"[form] [id-or-opts form] => run result (value or throw)"
|
|
||||||
{:doc (impl/signal-docstring :trace!)
|
|
||||||
:arglists (impl/signal-arglists :trace!)}
|
|
||||||
[& args]
|
|
||||||
(let [opts
|
|
||||||
(impl/signal-opts `trace! (enc/get-source &form &env)
|
|
||||||
{:kind :trace, :level :info, :msg `impl/default-trace-msg}
|
|
||||||
:run :id :asc args)
|
|
||||||
|
|
||||||
;; :catch->error <id-or-opts> currently undocumented
|
|
||||||
[opts catch-opts] (impl/signal-catch-opts opts)]
|
|
||||||
|
|
||||||
(if catch-opts
|
|
||||||
`(catch->error! ~catch-opts (impl/signal! ~opts))
|
|
||||||
(do `(impl/signal! ~opts))))))
|
|
||||||
|
|
||||||
(comment
|
|
||||||
(with-signal (trace! ::my-id (+ 1 2)))
|
|
||||||
(let [[_ [s1 s2]]
|
|
||||||
(with-signals
|
|
||||||
(trace! {:id :id1, :catch->error :id2}
|
|
||||||
(throw (ex-info "Ex1" {}))))]
|
|
||||||
[s2]))
|
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(defmacro spy!
|
|
||||||
"[form] [level-or-opts form] => run result (value or throw)"
|
|
||||||
{:doc (impl/signal-docstring :spy!)
|
|
||||||
:arglists (impl/signal-arglists :spy!)}
|
|
||||||
[& args]
|
|
||||||
(let [opts
|
|
||||||
(impl/signal-opts `spy! (enc/get-source &form &env)
|
|
||||||
{:kind :spy, :level :info, :msg `impl/default-trace-msg}
|
|
||||||
:run :level :asc args)
|
|
||||||
|
|
||||||
;; :catch->error <id-or-opts> currently undocumented
|
|
||||||
[opts catch-opts] (impl/signal-catch-opts opts)]
|
|
||||||
|
|
||||||
(if catch-opts
|
|
||||||
`(catch->error! ~catch-opts (impl/signal! ~opts))
|
|
||||||
(do `(impl/signal! ~opts))))))
|
|
||||||
|
|
||||||
(comment (with-signal :force (spy! :info (+ 1 2))))
|
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(defmacro uncaught->error!
|
|
||||||
"Uses `uncaught->handler!` so that `error!` will be called for
|
|
||||||
uncaught JVM errors.
|
|
||||||
|
|
||||||
See `uncaught->handler!` and `error!` for details."
|
|
||||||
{:arglists (impl/signal-arglists :uncaught->error!)}
|
|
||||||
[& args]
|
|
||||||
(let [msg-form ["Uncaught Throwable on thread:" `(.getName ~(with-meta '__thread-arg {:tag 'java.lang.Thread}))]
|
|
||||||
opts
|
|
||||||
(impl/signal-opts `uncaught->error! (enc/get-source &form &env)
|
|
||||||
{:kind :error, :level :error, :msg msg-form}
|
|
||||||
:error :id :dsc (into ['__throwable-arg] args))]
|
|
||||||
|
|
||||||
`(uncaught->handler!
|
|
||||||
(fn [~'__thread-arg ~'__throwable-arg]
|
|
||||||
(impl/signal! ~opts))))))
|
|
||||||
|
|
||||||
(comment
|
|
||||||
(macroexpand '(uncaught->error! ::uncaught))
|
|
||||||
(do
|
|
||||||
(uncaught->error! ::uncaught)
|
|
||||||
(enc/threaded :user (/ 1 0))))
|
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defn uncaught->handler!
|
(defn uncaught->handler!
|
||||||
|
|
@ -361,6 +309,31 @@
|
||||||
(handler thread throwable)))))
|
(handler thread throwable)))))
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(let [base-opts
|
||||||
|
{:kind :error, :level :error,
|
||||||
|
:msg `["Uncaught Throwable on thread:" (.getName ~(with-meta '__thread-arg {:tag 'java.lang.Thread}))]
|
||||||
|
:error '__throwable-arg}]
|
||||||
|
|
||||||
|
(defmacro uncaught->error!
|
||||||
|
"Uses `uncaught->handler!` so that `error!` will be called for
|
||||||
|
uncaught JVM errors.
|
||||||
|
|
||||||
|
See `uncaught->handler!` and `error!` for details."
|
||||||
|
{:arglists (impl/signal-arglists :uncaught->error!)}
|
||||||
|
([ ] (enc/keep-callsite `(uncaught->error! {})))
|
||||||
|
([opts-or-id]
|
||||||
|
(let [opts (merge-or-assoc-opts base-opts &form &env :id opts-or-id)]
|
||||||
|
`(uncaught->handler!
|
||||||
|
(fn [~'__thread-arg ~'__throwable-arg]
|
||||||
|
(impl/signal! ~opts))))))))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(macroexpand '(uncaught->error! ::uncaught))
|
||||||
|
(do
|
||||||
|
(uncaught->error! ::uncaught)
|
||||||
|
(enc/threaded :user (/ 1 0))))
|
||||||
|
|
||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
(defn dispatch-signal!
|
(defn dispatch-signal!
|
||||||
|
|
|
||||||
|
|
@ -376,84 +376,84 @@
|
||||||
(defn signal-arglists [macro-id]
|
(defn signal-arglists [macro-id]
|
||||||
(case macro-id
|
(case macro-id
|
||||||
|
|
||||||
:signal! ; [opts] => allowed? / run result (value or throw)
|
:signal! ; opts => allowed? / unconditional run result (value or throw)
|
||||||
'([{:as opts :keys
|
'([{:as opts-map :keys
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id, ; Undocumented
|
[#_defaults #_elide? #_allow? #_expansion-id, ; Undocumented
|
||||||
elidable? location #_location* inst uid middleware middleware+,
|
elidable? location #_location* inst uid middleware middleware+,
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
ctx ctx+ parent root trace?, do let data msg error run & kvs]}])
|
ctx ctx+ parent root trace?, do let data msg error run & kvs]}])
|
||||||
|
|
||||||
:signal-allowed?
|
:signal-allowed? ; opts => allowed?
|
||||||
'([{:as opts :keys
|
'([{:as opts-map :keys
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id, ; Undocumented
|
[#_defaults #_elide? #_allow? #_expansion-id, ; Undocumented
|
||||||
elidable? location #_location* #_inst #_uid #_middleware #_middleware+,
|
elidable? location #_location* #_inst #_uid #_middleware #_middleware+,
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
#_ctx #_ctx+ #_parent #_root #_trace?, #_do #_let #_data #_msg #_error #_run #_& #_kvs]}])
|
#_ctx #_ctx+ #_parent #_root #_trace?, #_do #_let #_data #_msg #_error #_run #_& #_kvs]}])
|
||||||
|
|
||||||
:event! ; [id] [id level-or-opts] => allowed?
|
:event! ; id + ?level => allowed?
|
||||||
'([id ]
|
'([opts-or-id]
|
||||||
[id level]
|
[id level]
|
||||||
[id
|
[id
|
||||||
{:as opts :keys
|
{:as opts-map :keys
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id,
|
[#_defaults #_elide? #_allow? #_expansion-id,
|
||||||
elidable? location #_location* inst uid middleware middleware+,
|
elidable? location #_location* inst uid middleware middleware+,
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}])
|
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}])
|
||||||
|
|
||||||
:log! ; [msg] [level-or-opts msg] => allowed?
|
:log! ; ?level + msg => allowed?
|
||||||
'([ msg]
|
'([opts-or-msg]
|
||||||
[level msg]
|
[level msg]
|
||||||
[{:as opts :keys
|
[{:as opts-map :keys
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id,
|
[#_defaults #_elide? #_allow? #_expansion-id,
|
||||||
elidable? location #_location* inst uid middleware middleware+,
|
elidable? location #_location* inst uid middleware middleware+,
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}
|
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}
|
||||||
msg])
|
msg])
|
||||||
|
|
||||||
:error! ; [error] [id-or-opts error] => given error
|
:trace! ; ?id + run => unconditional run result (value or throw)
|
||||||
'([ error]
|
'([opts-or-run]
|
||||||
|
[id run]
|
||||||
|
[{:as opts-map :keys
|
||||||
|
[#_defaults #_elide? #_allow? #_expansion-id,
|
||||||
|
elidable? location #_location* inst uid middleware middleware+,
|
||||||
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
|
ctx ctx+ parent root trace?, do let data msg error run & kvs]}
|
||||||
|
run])
|
||||||
|
|
||||||
|
:spy! ; ?level + run => unconditional run result (value or throw)
|
||||||
|
'([opts-or-run]
|
||||||
|
[level run]
|
||||||
|
[{:as opts-map :keys
|
||||||
|
[#_defaults #_elide? #_allow? #_expansion-id,
|
||||||
|
elidable? location #_location* inst uid middleware middleware+,
|
||||||
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
|
ctx ctx+ parent root trace?, do let data msg error run & kvs]}
|
||||||
|
run])
|
||||||
|
|
||||||
|
:error! ; ?id + error => unconditional given error
|
||||||
|
'([opts-or-error]
|
||||||
[id error]
|
[id error]
|
||||||
[{:as opts :keys
|
[{:as opts-map :keys
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id,
|
[#_defaults #_elide? #_allow? #_expansion-id,
|
||||||
elidable? location #_location* inst uid middleware middleware+,
|
elidable? location #_location* inst uid middleware middleware+,
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}
|
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}
|
||||||
error])
|
error])
|
||||||
|
|
||||||
:trace! ; [form] [id-or-opts form] => run result (value or throw)
|
:catch->error! ; ?id + run => unconditional run value or ?catch-val
|
||||||
'([ form]
|
'([opts-or-run]
|
||||||
[id form]
|
[id run]
|
||||||
[{:as opts :keys
|
[{:as opts-map :keys
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id,
|
|
||||||
elidable? location #_location* inst uid middleware middleware+,
|
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
|
||||||
ctx ctx+ parent root trace?, do let data msg error run & kvs]}
|
|
||||||
form])
|
|
||||||
|
|
||||||
:spy! ; [form] [level-or-opts form] => run result (value or throw)
|
|
||||||
'([ form]
|
|
||||||
[level form]
|
|
||||||
[{:as opts :keys
|
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id,
|
|
||||||
elidable? location #_location* inst uid middleware middleware+,
|
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
|
||||||
ctx ctx+ parent root trace?, do let data msg error run & kvs]}
|
|
||||||
form])
|
|
||||||
|
|
||||||
:catch->error! ; [form] [id-or-opts form] => run result (value or throw)
|
|
||||||
'([ form]
|
|
||||||
[id form]
|
|
||||||
[{:as opts :keys
|
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id, rethrow? catch-val,
|
[#_defaults #_elide? #_allow? #_expansion-id, rethrow? catch-val,
|
||||||
elidable? location #_location* inst uid middleware middleware+,
|
elidable? location #_location* inst uid middleware middleware+,
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}
|
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}
|
||||||
form])
|
run])
|
||||||
|
|
||||||
:uncaught->error! ; [] [id-or-opts] => nil
|
:uncaught->error! ; ?id => nil
|
||||||
'([]
|
'([]
|
||||||
[id]
|
[opts-or-id]
|
||||||
[{:as opts :keys
|
[{:as opts-map :keys
|
||||||
[#_defaults #_elide? #_allow? #_expansion-id,
|
[#_defaults #_elide? #_allow? #_expansion-id,
|
||||||
elidable? location #_location* inst uid middleware middleware+,
|
elidable? location #_location* inst uid middleware middleware+,
|
||||||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||||
|
|
@ -461,75 +461,6 @@
|
||||||
|
|
||||||
(enc/unexpected-arg! macro-id))))
|
(enc/unexpected-arg! macro-id))))
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(defn signal-opts
|
|
||||||
"Util to help write common signal wrapper macros."
|
|
||||||
[context location* defaults main-key extra-key arg-order args]
|
|
||||||
(enc/cond
|
|
||||||
:let [context-name (str "`" (name context) "`")
|
|
||||||
num-args (count args)
|
|
||||||
bad-args!
|
|
||||||
(fn [msg data]
|
|
||||||
(throw
|
|
||||||
(ex-info (str "Invalid " context-name " args: " msg)
|
|
||||||
(conj
|
|
||||||
{:context context
|
|
||||||
:args args}
|
|
||||||
data))))]
|
|
||||||
|
|
||||||
(not (#{1 2} num-args))
|
|
||||||
(bad-args! (str "wrong number of args (" num-args ")")
|
|
||||||
{:actual num-args, :expected #{1 2}})
|
|
||||||
|
|
||||||
:let [[main-arg extra-arg]
|
|
||||||
(case arg-order
|
|
||||||
:dsc args ; [main ...]
|
|
||||||
:asc (reverse args) ; [... main]
|
|
||||||
(enc/unexpected-arg!
|
|
||||||
arg-order))
|
|
||||||
|
|
||||||
extra-arg? (= num-args 2)
|
|
||||||
extra-opts? (and extra-arg? (map? extra-arg))]
|
|
||||||
|
|
||||||
:do
|
|
||||||
(enc/cond
|
|
||||||
(and (map? main-arg) (not extra-arg?))
|
|
||||||
(bad-args! "single map arg is USUALLY a mistake, so isn't allowed. Please use 2 arg arity instead, or `signal!`." {})
|
|
||||||
|
|
||||||
(and extra-opts? (contains? extra-arg main-key))
|
|
||||||
(bad-args! (str "given opts should not contain `" main-key "`.") {}))
|
|
||||||
|
|
||||||
:let [base (merge defaults {:location* location*, main-key main-arg})]
|
|
||||||
extra-opts? (merge base extra-arg)
|
|
||||||
extra-arg? (merge base {extra-key extra-arg})
|
|
||||||
:else base)))
|
|
||||||
|
|
||||||
(comment (signal-opts `foo! :loc* {:level :info} :id :level :dsc [::my-id {:level :warn}]))
|
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(defn signal-catch-opts
|
|
||||||
"For use within `trace!` and `spy!`, etc."
|
|
||||||
[main-opts]
|
|
||||||
(let [catch-id-or-opts (get main-opts :catch->error)
|
|
||||||
main-opts (dissoc main-opts :catch->error)
|
|
||||||
catch-opts
|
|
||||||
(when catch-id-or-opts
|
|
||||||
(let [base ; Inherit some opts from main
|
|
||||||
(enc/assoc-some {}
|
|
||||||
:location* (get main-opts :location*)
|
|
||||||
:id (get main-opts :id))]
|
|
||||||
(cond
|
|
||||||
(true? catch-id-or-opts) (do base)
|
|
||||||
(map? catch-id-or-opts) (conj base catch-id-or-opts)
|
|
||||||
:else (conj base {:id catch-id-or-opts}))))]
|
|
||||||
|
|
||||||
[main-opts catch-opts])))
|
|
||||||
|
|
||||||
(comment
|
|
||||||
(signal-catch-opts {:id :main-id, :catch->error true})
|
|
||||||
(signal-catch-opts {:id :main-id, :catch->error :error-id})
|
|
||||||
(signal-catch-opts {:id :main-id, :catch->error {:id :error-id}}))
|
|
||||||
|
|
||||||
;;;; Signal macro
|
;;;; Signal macro
|
||||||
|
|
||||||
(deftype RunResult [value error ^long run-nsecs]
|
(deftype RunResult [value error ^long run-nsecs]
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,8 @@
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(macroexpand '(trace "foo"))
|
(macroexpand '(trace "foo"))
|
||||||
(tel/with-signal :force-msg (trace "foo"))
|
(tel/with-signal (trace "foo"))
|
||||||
(tel/with-signal :force-msg (infof "Hello %s" "world")))
|
(tel/with-signal (infof "Hello %s" "world")))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(do
|
(do
|
||||||
|
|
@ -103,24 +103,27 @@
|
||||||
([ form] (enc/keep-callsite `(spy! :debug nil ~form)))
|
([ form] (enc/keep-callsite `(spy! :debug nil ~form)))
|
||||||
([level form] (enc/keep-callsite `(spy! ~level nil ~form)))
|
([level form] (enc/keep-callsite `(spy! ~level nil ~form)))
|
||||||
([level form-name form]
|
([level form-name form]
|
||||||
(let [msg
|
(let [location* (enc/get-source &form &env)
|
||||||
(if-not form-name
|
msg
|
||||||
`impl/default-trace-msg
|
(if form-name
|
||||||
`(fn [_form# value# error# nsecs#]
|
`(fn [_form# value# error# nsecs#] (impl/default-trace-msg ~form-name value# error# nsecs#))
|
||||||
(impl/default-trace-msg ~form-name value# error# nsecs#)))]
|
`(fn [_form# value# error# nsecs#] (impl/default-trace-msg '~form value# error# nsecs#)))]
|
||||||
|
|
||||||
(enc/keep-callsite
|
|
||||||
`(tel/spy!
|
`(tel/spy!
|
||||||
{:kind :spy
|
{:location* ~location*
|
||||||
:level ~level
|
|
||||||
:id shim-id
|
:id shim-id
|
||||||
:msg ~msg
|
:level ~level
|
||||||
:catch->error true}
|
:msg ~msg}
|
||||||
|
|
||||||
|
(tel/catch->error!
|
||||||
|
{:location* ~location*
|
||||||
|
:id shim-id}
|
||||||
~form))))))
|
~form))))))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(select-keys (tel/with-signal :force-msg (spy! :info "my-form-name" (+ 1 2))) [:level :msg_])
|
(:level (tel/with-signal (spy! (/ 1 0))))
|
||||||
(select-keys (tel/with-signal :force-msg (spy! :info "my-form-name" (throw (Exception. "Ex")))) [:level #_:msg_]))
|
(select-keys (tel/with-signal (spy! :info #_"my-form-name" (+ 1 2))) [:level :msg_])
|
||||||
|
(select-keys (tel/with-signal (spy! :info #_"my-form-name" (throw (Exception. "Ex")))) [:level :msg_]))
|
||||||
|
|
||||||
#?(:clj (defmacro log-errors "Prefer `telemere/catch->error!`." [& body] (enc/keep-callsite `(tel/catch->error! {:id shim-id, :catch-val nil} (do ~@body)))))
|
#?(:clj (defmacro log-errors "Prefer `telemere/catch->error!`." [& body] (enc/keep-callsite `(tel/catch->error! {:id shim-id, :catch-val nil} (do ~@body)))))
|
||||||
#?(:clj (defmacro log-and-rethrow-errors "Prefer `telemere/catch->error!`." [& body] (enc/keep-callsite `(tel/catch->error! {:id shim-id} (do ~@body)))))
|
#?(:clj (defmacro log-and-rethrow-errors "Prefer `telemere/catch->error!`." [& body] (enc/keep-callsite `(tel/catch->error! {:id shim-id} (do ~@body)))))
|
||||||
|
|
|
||||||
|
|
@ -568,42 +568,61 @@
|
||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
(deftest _common-signals
|
(deftest _common-signals
|
||||||
[#?(:clj
|
[(testing "event!" ; id + ?level => allowed?
|
||||||
(testing "signal-opts"
|
|
||||||
[(is (= (impl/signal-opts `foo! :loc* {:level :info} :id :level :dsc [::my-id ]) {:level :info, :id ::my-id, :location* :loc*}))
|
|
||||||
(is (= (impl/signal-opts `foo! :loc* {:level :info} :id :level :dsc [::my-id :warn ]) {:level :warn, :id ::my-id, :location* :loc*}))
|
|
||||||
(is (= (impl/signal-opts `foo! :loc* {:level :info} :id :level :dsc [::my-id {:level :warn}]) {:level :warn, :id ::my-id, :location* :loc*}))
|
|
||||||
|
|
||||||
(is (= (impl/signal-opts `foo! :loc* {:level :info} :id :level :asc [ ::my-id]) {:level :info, :id ::my-id, :location* :loc*}))
|
|
||||||
(is (= (impl/signal-opts `foo! :loc* {:level :info} :id :level :asc [:warn ::my-id]) {:level :warn, :id ::my-id, :location* :loc*}))
|
|
||||||
(is (= (impl/signal-opts `foo! :loc* {:level :info} :id :level :asc [{:level :warn} ::my-id]) {:level :warn, :id ::my-id, :location* :loc*}))
|
|
||||||
|
|
||||||
(is (= (impl/signal-catch-opts {:id :main-id, :location* {:ns "ns"}, :catch->error true}) [{:id :main-id, :location* {:ns "ns"}} {:location* {:ns "ns"}, :id :main-id}]))
|
|
||||||
(is (= (impl/signal-catch-opts {:id :main-id, :location* {:ns "ns"}, :catch->error :error-id}) [{:id :main-id, :location* {:ns "ns"}} {:location* {:ns "ns"}, :id :error-id}]))
|
|
||||||
(is (= (impl/signal-catch-opts {:id :main-id, :location* {:ns "ns"}, :catch->error {:id :error-id}}) [{:id :main-id, :location* {:ns "ns"}} {:location* {:ns "ns"}, :id :error-id}]))
|
|
||||||
|
|
||||||
(is (throws? :ex-info "Invalid `foo!` args: single map arg is USUALLY a mistake" (impl/signal-opts `foo! :loc* {:level :info} :id :level :dsc [{:msg "msg"}])))
|
|
||||||
(is (throws? :ex-info "Invalid `foo!` args: given opts should not contain `:id`" (impl/signal-opts `foo! :loc* {:level :info} :id :level :dsc [:my-id1 {:id ::my-id2}])))]))
|
|
||||||
|
|
||||||
(testing "event!" ; id + ?level => allowed?
|
|
||||||
[(let [[[rv] [sv]] (with-sigs (tel/event! :id1 )) ] [(is (= rv true)) (is (sm? sv {:kind :event, :line :submap/some, :level :info, :id :id1}))])
|
[(let [[[rv] [sv]] (with-sigs (tel/event! :id1 )) ] [(is (= rv true)) (is (sm? sv {:kind :event, :line :submap/some, :level :info, :id :id1}))])
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/event! :id1 :warn)) ] [(is (= rv true)) (is (sm? sv {:kind :event, :line :submap/some, :level :warn, :id :id1}))])
|
(let [[[rv] [sv]] (with-sigs (tel/event! :id1 :warn)) ] [(is (= rv true)) (is (sm? sv {:kind :event, :line :submap/some, :level :warn, :id :id1}))])
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/event! :id1 {:level :warn}))] [(is (= rv true)) (is (sm? sv {:kind :event, :line :submap/some, :level :warn, :id :id1}))])
|
(let [[[rv] [sv]] (with-sigs (tel/event! :id1 {:level :warn}))] [(is (= rv true)) (is (sm? sv {:kind :event, :line :submap/some, :level :warn, :id :id1}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/event! {:id :id1, :level :warn}))] [(is (= rv true)) (is (sm? sv {:kind :event, :line :submap/some, :level :warn, :id :id1}))])
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/event! :id1 {:allow? false})) ] [(is (= rv nil)) (is (nil? sv))])])
|
(let [[[rv] [sv]] (with-sigs (tel/event! :id1 {:allow? false})) ] [(is (= rv nil)) (is (nil? sv))])])
|
||||||
|
|
||||||
(testing "error!" ; error + ?id => error
|
(testing "log!" ; ?level + msg => allowed?
|
||||||
[(let [[[rv] [sv]] (with-sigs (tel/error! ex1))] [(is (ex1? rv)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id nil}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/error! :id1 ex1))] [(is (ex1? rv)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id :id1}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/error! {:id :id1} ex1))] [(is (ex1? rv)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id :id1}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/error! {:allow? false} ex1))] [(is (ex1? rv)) (is (nil? sv))])])
|
|
||||||
|
|
||||||
(testing "log!" ; msg + ?level => allowed?
|
|
||||||
[(let [[[rv] [sv]] (with-sigs (tel/log! "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :line :submap/some, :msg_ "msg", :level :info}))])
|
[(let [[[rv] [sv]] (with-sigs (tel/log! "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :line :submap/some, :msg_ "msg", :level :info}))])
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/log! :warn "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :line :submap/some, :msg_ "msg", :level :warn}))])
|
(let [[[rv] [sv]] (with-sigs (tel/log! :warn "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :line :submap/some, :msg_ "msg", :level :warn}))])
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/log! {:level :warn} "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :line :submap/some, :msg_ "msg", :level :warn}))])
|
(let [[[rv] [sv]] (with-sigs (tel/log! {:level :warn} "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :line :submap/some, :msg_ "msg", :level :warn}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/log! {:level :warn, :msg "msg"}))] [(is (= rv true)) (is (sm? sv {:kind :log, :line :submap/some, :msg_ "msg", :level :warn}))])
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/log! {:allow? false} "msg")) ] [(is (= rv nil)) (is (nil? sv))])])
|
(let [[[rv] [sv]] (with-sigs (tel/log! {:allow? false} "msg")) ] [(is (= rv nil)) (is (nil? sv))])])
|
||||||
|
|
||||||
(testing "catch->error!" ; form + ?id => run value or ?return
|
(testing "trace!" ; ?id + run => unconditional run result (value or throw)
|
||||||
|
[(let [[[rv] [sv]] (with-sigs (tel/trace! (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id nil, :msg_ "(+ 1 2) => 3"}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/trace! {:msg nil} (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id nil, :msg_ nil}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/trace! :id1 (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id :id1}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/trace! {:id :id1} (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id :id1}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/trace! {:id :id1, :run (+ 1 2)}))] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id :id1}))])
|
||||||
|
(let [[[_ re] [sv]] (with-sigs (tel/trace! :id1 (ex1!))) ] [(is (ex1? re)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id :id1, :error pex1?,
|
||||||
|
:msg_ #?(:clj "(ex1!) !> clojure.lang.ExceptionInfo"
|
||||||
|
:cljs "(ex1!) !> cljs.core/ExceptionInfo")}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/trace! {:allow? false} (+ 1 2))) ] [(is (= rv 3)) (is (nil? sv))])
|
||||||
|
|
||||||
|
(testing ":run-form" ; Undocumented, experimental
|
||||||
|
[(is (sm? (with-sig (tel/trace! :non-list)) {:run-form :non-list}))
|
||||||
|
(is (sm? (with-sig (tel/trace! (+ 1 2 3 4))) {:run-form '(+ 1 2 3 4)}))
|
||||||
|
(is (sm? (with-sig (tel/trace! (+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16))) {:run-form '(+ ...)}))
|
||||||
|
(is (sm? (with-sig (tel/trace! {:run-form my-run-form} (+ 1 2 3 4))) {:run-form 'my-run-form :kvs nil}))])
|
||||||
|
|
||||||
|
(testing ":run-val" ; Undocumented, experimental
|
||||||
|
[(is (sm? (with-sig (tel/trace! (+ 2 2))) {:run-val 4, :msg_ "(+ 2 2) => 4"}))
|
||||||
|
(is (sm? (with-sig (tel/trace! {:run-val "custom"} (+ 2 2))) {:run-val "custom", :msg_ "(+ 2 2) => custom", :kvs nil}))])])
|
||||||
|
|
||||||
|
(testing "spy" ; ?level + run => unconditional run result (value or throw)
|
||||||
|
[(let [[[rv] [sv]] (with-sigs (tel/spy! (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :info, :msg_ "(+ 1 2) => 3"}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/spy! {:msg nil} (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :info, :msg_ nil}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/spy! :warn (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :warn}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/spy! {:level :warn} (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :warn}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/spy! {:level :warn, :run (+ 1 2)}))] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :warn}))])
|
||||||
|
(let [[[_ re] [sv]] (with-sigs (tel/spy! :warn (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :spy, :line :submap/some, :level :warn, :error pex1?,
|
||||||
|
:msg_ #?(:clj "(ex1!) !> clojure.lang.ExceptionInfo"
|
||||||
|
:cljs "(ex1!) !> cljs.core/ExceptionInfo")}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/spy! {:allow? false} (+ 1 2))) ] [(is (= rv 3)) (is (nil? sv))])])
|
||||||
|
|
||||||
|
(testing "error!" ; ?id + error => unconditional given error
|
||||||
|
[(let [[[rv] [sv]] (with-sigs (tel/error! ex1)) ] [(is (ex1? rv)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id nil}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/error! :id1 ex1)) ] [(is (ex1? rv)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id :id1}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/error! {:id :id1} ex1)) ] [(is (ex1? rv)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id :id1}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/error! {:id :id1, :error ex1}))] [(is (ex1? rv)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id :id1}))])
|
||||||
|
(let [[[rv] [sv]] (with-sigs (tel/error! {:allow? false} ex1)) ] [(is (ex1? rv)) (is (nil? sv))])
|
||||||
|
(let [c (enc/counter)] (tel/error! (do (c) ex1)) (is (= @c 1) "Error form evaluated exactly once"))])
|
||||||
|
|
||||||
|
(testing "catch->error!" ; ?id + run => unconditional run value or ?return
|
||||||
[(let [[[rv re] [sv]] (with-sigs (tel/catch->error! (+ 1 2)))] [(is (= rv 3)) (is (nil? sv))])
|
[(let [[[rv re] [sv]] (with-sigs (tel/catch->error! (+ 1 2)))] [(is (= rv 3)) (is (nil? sv))])
|
||||||
(let [[[rv re] [sv]] (with-sigs (tel/catch->error! (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id nil}))])
|
(let [[[rv re] [sv]] (with-sigs (tel/catch->error! (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id nil}))])
|
||||||
(let [[[rv re] [sv]] (with-sigs (tel/catch->error! :id1 (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id :id1}))])
|
(let [[[rv re] [sv]] (with-sigs (tel/catch->error! :id1 (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :error, :line :submap/some, :level :error, :error pex1?, :id :id1}))])
|
||||||
|
|
@ -619,46 +638,6 @@
|
||||||
:data {:my-err my-err}} (ex1!)))]
|
:data {:my-err my-err}} (ex1!)))]
|
||||||
[(is (= rv nil)) (is (sm? sv {:kind :error, :data {:my-err pex1?}}))])])
|
[(is (= rv nil)) (is (sm? sv {:kind :error, :data {:my-err pex1?}}))])])
|
||||||
|
|
||||||
(testing "trace!" ; run + ?id => run result (value or throw)
|
|
||||||
[(let [[[rv] [sv]] (with-sigs (tel/trace! (+ 1 2)))] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id nil, :msg_ "(+ 1 2) => 3"}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/trace! {:msg nil} (+ 1 2)))] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id nil, :msg_ nil}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/trace! :id1 (+ 1 2)))] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id :id1}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/trace! {:id :id1} (+ 1 2)))] [(is (= rv 3)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id :id1}))])
|
|
||||||
(let [[[_ re] [sv]] (with-sigs (tel/trace! :id1 (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :trace, :line :submap/some, :level :info, :id :id1, :error pex1?,
|
|
||||||
:msg_ #?(:clj "(ex1!) !> clojure.lang.ExceptionInfo"
|
|
||||||
:cljs "(ex1!) !> cljs.core/ExceptionInfo")}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/trace! {:allow? false} (+ 1 2)))] [(is (= rv 3)) (is (nil? sv))])
|
|
||||||
(let [[_ [sv1 sv2]]
|
|
||||||
(with-sigs (tel/trace! {:id :id1, :catch->error :id2} (ex1!)))]
|
|
||||||
[(is (sm? sv1 {:kind :trace, :line :submap/some, :level :info, :id :id1}))
|
|
||||||
(is (sm? sv2 {:kind :error, :line :submap/some, :level :error, :id :id2}))
|
|
||||||
(is (= (:location sv1) (:location sv2)) "Error inherits exact same location")])
|
|
||||||
|
|
||||||
(testing ":run-form" ; Undocumented, experimental
|
|
||||||
[(is (sm? (with-sig (tel/trace! :non-list)) {:run-form :non-list}))
|
|
||||||
(is (sm? (with-sig (tel/trace! (+ 1 2 3 4))) {:run-form '(+ 1 2 3 4)}))
|
|
||||||
(is (sm? (with-sig (tel/trace! (+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16))) {:run-form '(+ ...)}))
|
|
||||||
(is (sm? (with-sig (tel/trace! {:run-form my-run-form} (+ 1 2 3 4))) {:run-form 'my-run-form :kvs nil}))])
|
|
||||||
|
|
||||||
(testing ":run-val" ; Undocumented, experimental
|
|
||||||
[(is (sm? (with-sig (tel/trace! (+ 2 2))) {:run-val 4, :msg_ "(+ 2 2) => 4"}))
|
|
||||||
(is (sm? (with-sig (tel/trace! {:run-val "custom"} (+ 2 2))) {:run-val "custom", :msg_ "(+ 2 2) => custom", :kvs nil}))])])
|
|
||||||
|
|
||||||
(testing "spy" ; run + ?level => run result (value or throw)
|
|
||||||
[(let [[[rv] [sv]] (with-sigs (tel/spy! (+ 1 2)))] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :info, :msg_ "(+ 1 2) => 3"}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/spy! {:msg nil} (+ 1 2)))] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :info, :msg_ nil}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/spy! :warn (+ 1 2)))] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :warn}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/spy! {:level :warn} (+ 1 2)))] [(is (= rv 3)) (is (sm? sv {:kind :spy, :line :submap/some, :level :warn}))])
|
|
||||||
(let [[[_ re] [sv]] (with-sigs (tel/spy! :warn (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :spy, :line :submap/some, :level :warn, :error pex1?,
|
|
||||||
:msg_ #?(:clj "(ex1!) !> clojure.lang.ExceptionInfo"
|
|
||||||
:cljs "(ex1!) !> cljs.core/ExceptionInfo")}))])
|
|
||||||
(let [[[rv] [sv]] (with-sigs (tel/spy! {:allow? false} (+ 1 2)))] [(is (= rv 3)) (is (nil? sv))])
|
|
||||||
(let [[_ [sv1 sv2]]
|
|
||||||
(with-sigs (tel/spy! {:id :id1, :catch->error :id2} (ex1!)))]
|
|
||||||
[(is (sm? sv1 {:kind :spy, :line :submap/some, :level :info, :id :id1}))
|
|
||||||
(is (sm? sv2 {:kind :error, :line :submap/some, :level :error, :id :id2}))
|
|
||||||
(is (= (:location sv1) (:location sv2)) "Error inherits exact same location")])])
|
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(testing "uncaught->error!"
|
(testing "uncaught->error!"
|
||||||
(let [sv_ (atom ::nx)]
|
(let [sv_ (atom ::nx)]
|
||||||
|
|
@ -770,8 +749,11 @@
|
||||||
(is (sm? (with-sig (timbre/info ex1 "x1" "x2")) {:kind :log, :level :info, :error pex1?, :msg_ "x1 x2", :data {:vargs ["x1" "x2"]}}) "First-arg error")
|
(is (sm? (with-sig (timbre/info ex1 "x1" "x2")) {:kind :log, :level :info, :error pex1?, :msg_ "x1 x2", :data {:vargs ["x1" "x2"]}}) "First-arg error")
|
||||||
|
|
||||||
(is (sm? (with-sig (timbre/spy! :info "my-name" (+ 1 2))) {:kind :spy, :level :info, :id timbre/shim-id, :msg_ "my-name => 3", :ns pstr?}))
|
(is (sm? (with-sig (timbre/spy! :info "my-name" (+ 1 2))) {:kind :spy, :level :info, :id timbre/shim-id, :msg_ "my-name => 3", :ns pstr?}))
|
||||||
(is (sm? (with-sig (timbre/spy! (+ 1 2))) {:kind :spy, :level :debug, :id timbre/shim-id, :msg_ "(+ 1 2) => 3", :ns pstr?}))
|
(is (sm? (tel/with-min-level :debug (with-sig (timbre/spy! (+ 1 2)))) {:kind :spy, :level :debug, :id timbre/shim-id, :msg_ "(+ 1 2) => 3", :ns pstr?}))
|
||||||
(is (sm? (with-sig (timbre/spy! (ex1!))) {:kind :error, :level :error, :id timbre/shim-id, :msg_ nil, :error pex1?, :ns pstr?}))
|
|
||||||
|
(let [[_ [sv1 sv2]] (tel/with-min-level :debug (with-sigs (timbre/spy! (ex1!))))]
|
||||||
|
[(is (sm? sv1 {:kind :error, :level :error, :id timbre/shim-id, :msg_ nil, :error pex1?, :ns pstr?}))
|
||||||
|
(is (sm? sv2 {:kind :spy, :level :debug, :id timbre/shim-id, :msg_ pstr? :error pex1?, :ns pstr?}))])
|
||||||
|
|
||||||
(let [[[rv re] [sv]] (with-sigs (timbre/log-errors (ex1!)))] [(is (nil? re)) (is (sm? sv {:kind :error, :level :error, :error pex1?, :id timbre/shim-id}))])
|
(let [[[rv re] [sv]] (with-sigs (timbre/log-errors (ex1!)))] [(is (nil? re)) (is (sm? sv {:kind :error, :level :error, :error pex1?, :id timbre/shim-id}))])
|
||||||
(let [[[rv re] [sv]] (with-sigs (timbre/log-and-rethrow-errors (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :error, :level :error, :error pex1?, :id timbre/shim-id}))])])
|
(let [[[rv re] [sv]] (with-sigs (timbre/log-and-rethrow-errors (ex1!)))] [(is (ex1? re)) (is (sm? sv {:kind :error, :level :error, :error pex1?, :id timbre/shim-id}))])])
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue