mirror of
https://github.com/taoensso/telemere.git
synced 2025-12-16 17:41:12 +00:00
[mod] [#53] Breaking: change return value of log!, event!
This change will only affect rare advanced users that depend on the return value of `log!` or `event!`. For all other users this will be a non-breaking change. Before this commit: `log!` and `event!` returned true iff signal was allowed. After this commit: `log!` and `event!` now ALWAYS return nil. `log!?` and `event!?` have been added that keep the old behaviour. Motivation: It's pretty rare to use the return value when generating log or event signals. I originally included the return value since it CAN be handy, and I figured it could just be ignored by those that don't need it. But #53 showed that there's a downside I hadn't anticipated - some users may actually depend on / prefer a nil return to prevent accidentally affecting program flow. I think that's a legitimate enough concern to still make a change now before v1 final. Apologies for the nuissance!
This commit is contained in:
parent
e32ed8deb5
commit
ac5feb4723
13 changed files with 93 additions and 69 deletions
|
|
@ -235,13 +235,13 @@ See relevant docstrings (links below) for usage info-
|
|||
|
||||
| Name | Kind | Args | Returns |
|
||||
| :---------------------------------------------------------------------------------------------------------- | :--------- | :--------------- | :--------------------------- |
|
||||
| [`signal!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#signal!) | `:generic` | `opts` | Depends on opts |
|
||||
| [`event!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#event!) | `:event` | `id` + `?level` | Signal allowed? |
|
||||
| [`log!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#log!) | `:log` | `?level` + `msg` | Signal allowed? |
|
||||
| [`log!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#log!) | `:log` | `?level` + `msg` | nil |
|
||||
| [`event!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#event!) | `:event` | `id` + `?level` | nil |
|
||||
| [`trace!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#trace!) | `:trace` | `?id` + `run` | Form result |
|
||||
| [`spy!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#spy!) | `:spy` | `?level` + `run` | Form result |
|
||||
| [`error!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#error!) | `:error` | `?id` + `error` | Given error |
|
||||
| [`catch->error!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#catch-%3Eerror!) | `:error` | `?id` | Form value or given fallback |
|
||||
| [`signal!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#signal!) | `:generic` | `opts` | Depends on opts |
|
||||
|
||||
### Internal help
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
ALWAYS (unconditionally) executes given `run` form and:
|
||||
If `run` form succeeds: returns the form's result.
|
||||
If `run` form throws ANYTHING:
|
||||
Calls `error!` with the thrown error and given signal options [2], then
|
||||
either returns given (:catch-val opts), or rethrows.
|
||||
|
||||
Default kind: `:error`
|
||||
Default level: `:error`
|
||||
Returns:
|
||||
- If given `run` form succeeds: returns the form's result.
|
||||
- If given `run` form throws ANYTHING:
|
||||
Calls `error!` with the thrown error and given signal options [2], then
|
||||
either returns given (:catch-val opts), or rethrows.
|
||||
|
||||
Just a convenience util. For more flexibility use your own `try/catch`.
|
||||
See `taoensso.encore/try*` for easily catching cross-platform errors.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
"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.
|
||||
|
||||
Default kind: `:error`
|
||||
Default level: `:error`
|
||||
Returns:
|
||||
ALWAYS (unconditionally) returns the given error, so can conveniently be
|
||||
wrapped by `throw`: (throw (error! (ex-info ...)), etc.
|
||||
|
||||
Examples:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
"Event" signal creator, emphasizing id + (optional level).
|
||||
Returns true iff signal was created (allowed by filtering).
|
||||
|
||||
Default kind: `:event`
|
||||
Default level: `:info`
|
||||
Returns:
|
||||
- For `event!` variant: nil, unconditionally.
|
||||
- For `event!?` variant: true iff signal was created (allowed by filtering).
|
||||
|
||||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||||
dispatches it to registered handlers for processing (e.g. writing to
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
"Log" signal creator, emphasizing (optional level) + message.
|
||||
Returns true iff signal was created (allowed by filtering).
|
||||
|
||||
Default kind: `:log`
|
||||
Default level: `:info`
|
||||
Returns:
|
||||
- For `log!` variant: nil, unconditionally.
|
||||
- For `log!?` variant: true iff signal was created (allowed by filtering).
|
||||
|
||||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||||
dispatches it to registered handlers for processing (e.g. writing to
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
Low-level "generic" signal creator for creating signals of any "kind".
|
||||
Takes a single map of options [2] with compile-time keys.
|
||||
|
||||
Return value depends on options:
|
||||
- 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`
|
||||
Returns:
|
||||
- If given `:run` form: unconditionally returns run value, or rethrows run error.
|
||||
- Otherwise: returns true iff signal was created (allowed by filtering).
|
||||
|
||||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||||
dispatches it to registered handlers for processing (e.g. writing to
|
||||
|
|
|
|||
|
|
@ -14,13 +14,14 @@ various keys:
|
|||
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:
|
||||
|
||||
`signal!` ------- opts => allowed? / unconditional run result (value or throw)
|
||||
`event!` -------- id + ?level => allowed?
|
||||
`log!` ---------- ?level + msg => allowed?
|
||||
`trace!` -------- ?id + run => unconditional run result (value or throw)
|
||||
`spy!` ---------- ?level + run => unconditional run result (value or throw)
|
||||
`error!` -------- ?id + error => unconditional given error
|
||||
`catch->error!` - ?id + run => unconditional run value or ?catch-val
|
||||
`log!` ------------- ?level + msg => nil
|
||||
`event!` ----------- id + ?level => nil
|
||||
`trace!` ----------- ?id + run => run result (value or throw)
|
||||
`spy!` ------------- ?level + run => run result (value or throw)
|
||||
`error!` ----------- ?id + error => given error
|
||||
`catch->error!` ---- ?id + run => run value or ?catch-val
|
||||
`uncaught->error!` - ?id => nil
|
||||
`signal!` ---------- opts => allowed? / run result (value or throw)
|
||||
|
||||
- `log!` and `event!` are both good default/general-purpose signal creators.
|
||||
- `log!` emphasizes messages, while `event!` emphasizes ids.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
"Spy" signal creator, emphasizing (optional level) + form to run.
|
||||
ALWAYS (unconditionally) returns run value, or rethrows run error.
|
||||
|
||||
Default kind: `:spy`
|
||||
Default level: `:info`
|
||||
Returns: ALWAYS (unconditionally) returns run value, or rethrows run error.
|
||||
|
||||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||||
dispatches it to registered handlers for processing (e.g. writing to
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
"Trace" signal creator, emphasizing (optional id) + form to run.
|
||||
ALWAYS (unconditionally) returns run value, or rethrows run error.
|
||||
|
||||
Default kind: `:trace`
|
||||
Default level: `:info` (intentionally NOT `:trace`!)
|
||||
Returns: ALWAYS (unconditionally) returns run value, or rethrows run error.
|
||||
|
||||
When filtering conditions are met [4], creates a Telemere signal [3] and
|
||||
dispatches it to registered handlers for processing (e.g. writing to
|
||||
|
|
|
|||
|
|
@ -197,14 +197,14 @@
|
|||
(comment (enc/qb 1e6 (force *otel-tracer*))) ; 51.23
|
||||
|
||||
;;;; Signal creators
|
||||
;; - signal! ---------- opts => allowed? / unconditional run result (value or throw)
|
||||
;; - event! ----------- id + ?level => allowed?
|
||||
;; - log! ------------- ?level + msg => allowed?
|
||||
;; - trace! ----------- ?id + run => unconditional run result (value or throw)
|
||||
;; - spy! ------------- ?level + run => unconditional run result (value or throw)
|
||||
;; - error! ----------- ?id + error => unconditional given error
|
||||
;; - catch->error! ---- ?id + run => unconditional run value or ?catch-val
|
||||
;; - log! ------------- ?level + msg => nil
|
||||
;; - event! ----------- id + ?level => nil
|
||||
;; - trace! ----------- ?id + run => run result (value or throw)
|
||||
;; - spy! ------------- ?level + run => run result (value or throw)
|
||||
;; - error! ----------- ?id + error => given error
|
||||
;; - catch->error! ---- ?id + run => run value or ?catch-val
|
||||
;; - uncaught->error! - ?id => nil
|
||||
;; - signal! ---------- opts => allowed? / run result (value or throw)
|
||||
|
||||
#?(:clj
|
||||
(defn- args->opts [args]
|
||||
|
|
@ -251,28 +251,46 @@
|
|||
(merge m v)
|
||||
(assoc m k v)))))
|
||||
|
||||
#?(:clj
|
||||
(let [base-opts {:kind :event, :level :info}]
|
||||
(defmacro event!
|
||||
"id + ?level => allowed? Note unique arg order: [x opts] rather than [opts x]!"
|
||||
{:doc (impl/signal-docstring :event!)
|
||||
:arglists (impl/signal-arglists :event!)}
|
||||
([ opts-or-id] `(impl/signal! ~(merge-or-assoc-opts base-opts &form :id opts-or-id)))
|
||||
([id opts-or-level] `(impl/signal! ~(assoc (merge-or-assoc-opts base-opts &form :level opts-or-level) :id id))))))
|
||||
|
||||
(comment (:coords (with-signal (event! ::my-id :info))))
|
||||
|
||||
#?(:clj
|
||||
(let [base-opts {:kind :log, :level :info}]
|
||||
(defmacro log!
|
||||
(defmacro log!?
|
||||
"?level + msg => allowed?"
|
||||
{:doc (impl/signal-docstring :log!)
|
||||
:arglists (impl/signal-arglists :log!)}
|
||||
([opts-or-msg ] `(impl/signal! ~(merge-or-assoc-opts base-opts &form :msg opts-or-msg)))
|
||||
([opts-or-level msg] `(impl/signal! ~(assoc (merge-or-assoc-opts base-opts &form :level opts-or-level) :msg msg))))))
|
||||
|
||||
(comment (:coords (with-signal (log!? :info "My msg"))))
|
||||
|
||||
#?(:clj
|
||||
(defmacro log!
|
||||
"Like `log!?` but always returns nil."
|
||||
{:doc (impl/signal-docstring :log!)
|
||||
:arglists (impl/signal-arglists :log!)}
|
||||
[& args] `(do ~(truss/keep-callsite `(log!? ~@args)) nil)))
|
||||
|
||||
(comment (:coords (with-signal (log! :info "My msg"))))
|
||||
|
||||
#?(:clj
|
||||
(let [base-opts {:kind :event, :level :info}]
|
||||
(defmacro event!?
|
||||
"id + ?level => allowed? Note unique arg order: [x opts] rather than [opts x]!"
|
||||
{:doc (impl/signal-docstring :event!)
|
||||
:arglists (impl/signal-arglists :event!)}
|
||||
([ opts-or-id] `(impl/signal! ~(merge-or-assoc-opts base-opts &form :id opts-or-id)))
|
||||
([id opts-or-level] `(impl/signal! ~(assoc (merge-or-assoc-opts base-opts &form :level opts-or-level) :id id))))))
|
||||
|
||||
(comment (:coords (with-signal (event!? ::my-id :info))))
|
||||
|
||||
#?(:clj
|
||||
(defmacro event!
|
||||
"Like `event!?` but always returns nil."
|
||||
{:doc (impl/signal-docstring :event!)
|
||||
:arglists (impl/signal-arglists :event!)}
|
||||
[& args] `(do ~(truss/keep-callsite `(event!? ~@args)) nil)))
|
||||
|
||||
(comment (:coords (with-signal (event! ::my-id :info))))
|
||||
|
||||
#?(:clj
|
||||
(let [base-opts {:kind :trace, :level :info, :msg `impl/default-trace-msg}]
|
||||
(defmacro trace!
|
||||
|
|
|
|||
|
|
@ -405,16 +405,6 @@
|
|||
sample-rate kind ns id level when rate-limit rate-limit-by,
|
||||
ctx ctx+ parent root trace?, do let data msg error run & kvs]}])
|
||||
|
||||
:event! ; id + ?level => allowed?
|
||||
'([opts-or-id]
|
||||
[id level]
|
||||
[id
|
||||
{:as opts-map :keys
|
||||
[#_elide? #_allow? #_callsite-id,
|
||||
elidable? coords 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]}])
|
||||
|
||||
:log! ; ?level + msg => allowed?
|
||||
'([opts-or-msg]
|
||||
[level msg]
|
||||
|
|
@ -425,6 +415,16 @@
|
|||
ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}
|
||||
msg])
|
||||
|
||||
:event! ; id + ?level => allowed?
|
||||
'([opts-or-id]
|
||||
[id level]
|
||||
[id
|
||||
{:as opts-map :keys
|
||||
[#_elide? #_allow? #_callsite-id,
|
||||
elidable? coords 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]}])
|
||||
|
||||
:trace! ; ?id + run => unconditional run result (value or throw)
|
||||
'([opts-or-run]
|
||||
[id run]
|
||||
|
|
@ -532,7 +532,7 @@
|
|||
#?(:clj
|
||||
(defmacro signal!
|
||||
"Generic low-level signal creator. Wrapped for public API."
|
||||
([ opts] (truss/keep-callsite `(signal!? nil ~opts)))
|
||||
([ opts] (truss/keep-callsite `(signal! nil ~opts)))
|
||||
([base-opts opts]
|
||||
(valid-opts! (or base-opts {}))
|
||||
(valid-opts! (or opts {}))
|
||||
|
|
|
|||
|
|
@ -574,19 +574,19 @@
|
|||
;;;;
|
||||
|
||||
(deftest _common-signals
|
||||
[(testing "event!" ; id + ?level => allowed?
|
||||
[(let [{rv :value, [sv] :signals} (with-sigs (tel/event! :id1 ))] [(is (= rv true)) (is (sm? sv {:kind :event, :coords coords?, :level :info, :id :id1}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/event! :id1 :warn)) ] [(is (= rv true)) (is (sm? sv {:kind :event, :coords coords?, :level :warn, :id :id1}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/event! :id1 {:level :warn}))] [(is (= rv true)) (is (sm? sv {:kind :event, :coords coords?, :level :warn, :id :id1}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/event! {:id :id1, :level :warn}))] [(is (= rv true)) (is (sm? sv {:kind :event, :coords coords?, :level :warn, :id :id1}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/event! :id1 {:allow? false})) ] [(is (= rv nil)) (is (nil? sv))])])
|
||||
[(testing "event!?" ; id + ?level => allowed?
|
||||
[(let [{rv :value, [sv] :signals} (with-sigs (tel/event!? :id1 ))] [(is (= rv true)) (is (sm? sv {:kind :event, :coords coords?, :level :info, :id :id1}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/event!? :id1 :warn)) ] [(is (= rv true)) (is (sm? sv {:kind :event, :coords coords?, :level :warn, :id :id1}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/event!? :id1 {:level :warn}))] [(is (= rv true)) (is (sm? sv {:kind :event, :coords coords?, :level :warn, :id :id1}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/event!? {:id :id1, :level :warn}))] [(is (= rv true)) (is (sm? sv {:kind :event, :coords coords?, :level :warn, :id :id1}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/event!? :id1 {:allow? false})) ] [(is (= rv nil)) (is (nil? sv))])])
|
||||
|
||||
(testing "log!" ; ?level + msg => allowed?
|
||||
[(let [{rv :value, [sv] :signals} (with-sigs (tel/log! "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :coords coords?, :msg_ "msg", :level :info}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/log! :warn "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :coords coords?, :msg_ "msg", :level :warn}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/log! {:level :warn} "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :coords coords?, :msg_ "msg", :level :warn}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/log! {:level :warn, :msg "msg"}))] [(is (= rv true)) (is (sm? sv {:kind :log, :coords coords?, :msg_ "msg", :level :warn}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/log! {:allow? false} "msg")) ] [(is (= rv nil)) (is (nil? sv))])])
|
||||
(testing "log!?" ; ?level + msg => allowed?
|
||||
[(let [{rv :value, [sv] :signals} (with-sigs (tel/log!? "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :coords coords?, :msg_ "msg", :level :info}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/log!? :warn "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :coords coords?, :msg_ "msg", :level :warn}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/log!? {:level :warn} "msg")) ] [(is (= rv true)) (is (sm? sv {:kind :log, :coords coords?, :msg_ "msg", :level :warn}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/log!? {:level :warn, :msg "msg"}))] [(is (= rv true)) (is (sm? sv {:kind :log, :coords coords?, :msg_ "msg", :level :warn}))])
|
||||
(let [{rv :value, [sv] :signals} (with-sigs (tel/log!? {:allow? false} "msg")) ] [(is (= rv nil)) (is (nil? sv))])])
|
||||
|
||||
(testing "trace!" ; ?id + run => unconditional run result (value or throw)
|
||||
[(let [{rv :value, [sv] :signals} (with-sigs (tel/trace! (+ 1 2))) ] [(is (= rv 3)) (is (sm? sv {:kind :trace, :coords coords?, :level :info, :id nil, :msg_ "(+ 1 2) => 3"}))])
|
||||
|
|
|
|||
|
|
@ -131,13 +131,13 @@ Use whichever signal creator is most convenient for your needs:
|
|||
|
||||
| Name | Kind | Args | Returns |
|
||||
| :---------------------------------------------------------------------------------------------------------- | :--------- | :--------------- | :--------------------------- |
|
||||
| [`signal!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#signal!) | `:generic` | `opts` | Depends on opts |
|
||||
| [`event!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#event!) | `:event` | `id` + `?level` | Signal allowed? |
|
||||
| [`log!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#log!) | `:log` | `?level` + `msg` | Signal allowed? |
|
||||
| [`log!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#log!) | `:log` | `?level` + `msg` | nil |
|
||||
| [`event!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#event!) | `:event` | `id` + `?level` | nil |
|
||||
| [`trace!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#trace!) | `:trace` | `?id` + `run` | Form result |
|
||||
| [`spy!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#spy!) | `:spy` | `?level` + `run` | Form result |
|
||||
| [`error!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#error!) | `:error` | `?id` + `error` | Given error |
|
||||
| [`catch->error!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#catch-%3Eerror!) | `:error` | `?id` | Form value or given fallback |
|
||||
| [`signal!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#signal!) | `:generic` | `opts` | Depends on opts |
|
||||
|
||||
- See relevant docstrings (links above) for usage info.
|
||||
- See [`help:signal-creators`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-creators) for more about signal creators.
|
||||
|
|
|
|||
Loading…
Reference in a new issue