mirror of
https://github.com/taoensso/telemere.git
synced 2025-12-17 09:51:12 +00:00
[new] Add signal-allowed? util
Useful for using Telemere's filtering features without generating any signals, etc.
This commit is contained in:
parent
a9005e7f1c
commit
d12b0b145b
4 changed files with 118 additions and 31 deletions
|
|
@ -68,6 +68,7 @@
|
||||||
#?(:clj impl/with-signal)
|
#?(:clj impl/with-signal)
|
||||||
#?(:clj impl/with-signals)
|
#?(:clj impl/with-signals)
|
||||||
#?(:clj impl/signal!)
|
#?(:clj impl/signal!)
|
||||||
|
#?(:clj impl/signal-allowed?)
|
||||||
|
|
||||||
;; Utils
|
;; Utils
|
||||||
utils/format-signal-fn
|
utils/format-signal-fn
|
||||||
|
|
|
||||||
|
|
@ -381,6 +381,13 @@
|
||||||
sample-rate kind ns id level when rate-limit,
|
sample-rate kind ns id level when rate-limit,
|
||||||
ctx parent root trace?, do let data msg error run & kvs]}])
|
ctx parent root trace?, do let data msg error run & kvs]}])
|
||||||
|
|
||||||
|
:signal-allowed?
|
||||||
|
'([{:as opts :keys
|
||||||
|
[#_defaults #_elide? #_allow? #_expansion-id, ; Undocumented
|
||||||
|
elidable? location #_location* #_inst #_uid #_middleware,
|
||||||
|
sample-rate kind ns id level when rate-limit,
|
||||||
|
#_ctx #_parent #_root #_trace?, #_do #_let #_data #_msg #_error #_run #_& #_kvs]}])
|
||||||
|
|
||||||
:event! ; [id] [id level-or-opts] => allowed?
|
:event! ; [id] [id level-or-opts] => allowed?
|
||||||
'([id ]
|
'([id ]
|
||||||
[id level]
|
[id level]
|
||||||
|
|
@ -762,11 +769,27 @@
|
||||||
(signal! {:level :info, :run "run"}))))
|
(signal! {:level :info, :run "run"}))))
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defmacro signal-allowed?
|
(defmacro ^:public signal-allowed?
|
||||||
"Used only for interop (tools.logging, SLF4J, etc.)."
|
"Returns true iff signal with given opts would meet filtering conditions:
|
||||||
{:arglists (signal-arglists :signal!)}
|
(when (signal-allowed? {:level :warn, <...>}) (my-custom-code))
|
||||||
|
|
||||||
|
Allows you to use Telemere's rich filtering system for conditionally
|
||||||
|
executing arbitrary code. Also handy for batching multiple signals
|
||||||
|
under a single set of conditions (incl. rate-limiting, sampling, etc.):
|
||||||
|
|
||||||
|
;; Logs exactly 2 or 0 messages (never 1):
|
||||||
|
(when (signal-allowed? {:level :info, :sample-rate 0.5})
|
||||||
|
(log! {:allow? true} \"Message 1\")
|
||||||
|
(log! {:allow? true} \"Message 2\"))"
|
||||||
|
|
||||||
|
;; Used also for interop (tools.logging, SLF4J), etc.
|
||||||
|
{:arglists (signal-arglists :signal-allowed?)}
|
||||||
[opts]
|
[opts]
|
||||||
(let [{:keys [#_expansion-id #_location elide? allow?]}
|
(have? map? opts)
|
||||||
|
(let [defaults (get opts :defaults)
|
||||||
|
opts (merge defaults (dissoc opts :defaults))
|
||||||
|
|
||||||
|
{:keys [#_expansion-id #_location elide? allow?]}
|
||||||
(sigs/filterable-expansion
|
(sigs/filterable-expansion
|
||||||
{:sf-arity 4
|
{:sf-arity 4
|
||||||
:ct-sig-filter ct-sig-filter
|
:ct-sig-filter ct-sig-filter
|
||||||
|
|
@ -774,7 +797,9 @@
|
||||||
(assoc opts :location*
|
(assoc opts :location*
|
||||||
(get opts :location* (enc/get-source &form &env))))]
|
(get opts :location* (enc/get-source &form &env))))]
|
||||||
|
|
||||||
(and (not elide?) allow?))))
|
(if elide? false `(if ~allow? true false)))))
|
||||||
|
|
||||||
|
(comment (macroexpand '(signal-allowed? {:level :info})))
|
||||||
|
|
||||||
;;;; Interop
|
;;;; Interop
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,10 @@
|
||||||
|
|
||||||
[(is (= sv1 (read-string (pr-str sv1))))])))
|
[(is (= sv1 (read-string (pr-str sv1))))])))
|
||||||
|
|
||||||
(is (sm? (with-sig (shell/signal! {:level :info})) {:level :info, :ns "taoensso.telemere-tests", :line :submap/some}) "Shell API")])
|
(testing "Shell API"
|
||||||
|
[(is (sm? (with-sig (shell/signal! {:level :info})) {:level :info, :ns "taoensso.telemere-tests", :line :submap/some}))
|
||||||
|
(is (true? (tel/with-min-level :debug (shell/signal-allowed? {:level :debug}))))
|
||||||
|
(is (false? (tel/with-min-level :debug (shell/signal-allowed? {:level :trace}))))])])
|
||||||
|
|
||||||
(deftest _handlers
|
(deftest _handlers
|
||||||
;; Basic handler tests are in Encore
|
;; Basic handler tests are in Encore
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,58 @@
|
||||||
(remove-ns 'taoensso.telemere.shell)
|
(remove-ns 'taoensso.telemere.shell)
|
||||||
(:api (enc/interns-overview)))
|
(:api (enc/interns-overview)))
|
||||||
|
|
||||||
|
;;;; Private
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defmacro ^:private compile-if [test then else]
|
(defmacro ^:private compile-if [test then else]
|
||||||
(if (try (eval test) (catch Throwable _ false)) then else)))
|
(if (try (eval test) (catch Throwable _ false)) then else)))
|
||||||
|
|
||||||
(def ^:private telemere-present?
|
#?(:clj
|
||||||
|
(def ^:private telemere-present?
|
||||||
"Is Telemere present (not necessarily loaded)?"
|
"Is Telemere present (not necessarily loaded)?"
|
||||||
(compile-if (jio/resource "taoensso/telemere.cljc") true false))
|
(compile-if (jio/resource "taoensso/telemere.cljc") true false)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defn- require-telemere! []
|
||||||
|
(try
|
||||||
|
(require 'taoensso.telemere) ; For macro expansion
|
||||||
|
(catch Exception e
|
||||||
|
(throw
|
||||||
|
(ex-info "Failed to require `taoensso.telemere` - `(require-telemere-if-present)` call missing?"
|
||||||
|
{} e))))))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defn- get-source "From Encore" [macro-form macro-env]
|
||||||
|
(let [{:keys [line column file]} (meta macro-form)
|
||||||
|
file
|
||||||
|
(if-not (:ns macro-env)
|
||||||
|
*file* ; Compiling Clj
|
||||||
|
(or ; Compiling Cljs
|
||||||
|
(when-let [url (and file (try (jio/resource file) (catch Exception _)))]
|
||||||
|
(try (.getPath (jio/file url)) (catch Exception _))
|
||||||
|
(do (str url)))
|
||||||
|
file))
|
||||||
|
|
||||||
|
file
|
||||||
|
(when (string? file)
|
||||||
|
(when-not (contains? #{"NO_SOURCE_PATH" "NO_SOURCE_FILE" ""} file)
|
||||||
|
file))
|
||||||
|
|
||||||
|
m {:ns (str *ns*)}
|
||||||
|
m (if line (assoc m :line line) m)
|
||||||
|
m (if column (assoc m :column column) m)
|
||||||
|
m (if file (assoc m :file file) m)]
|
||||||
|
m)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defn- signal-opts [macro-form macro-env opts]
|
||||||
|
(if (map? opts)
|
||||||
|
(conj {:location* (get-source macro-form macro-env)} (dissoc opts :fallback))
|
||||||
|
(throw
|
||||||
|
(ex-info "Signal opts must be a map"
|
||||||
|
{:given {:value opts, :type (type opts)}})))))
|
||||||
|
|
||||||
|
;;;; Public
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(defmacro if-telemere
|
(defmacro if-telemere
|
||||||
|
|
@ -92,28 +137,12 @@
|
||||||
ctx parent root trace?, do let data msg error run & kvs]}])}
|
ctx parent root trace?, do let data msg error run & kvs]}])}
|
||||||
|
|
||||||
[opts]
|
[opts]
|
||||||
(if (map? opts)
|
|
||||||
(if telemere-present?
|
(if telemere-present?
|
||||||
(do
|
(do (require-telemere!) `(taoensso.telemere/signal! ~(signal-opts &form &env opts)))
|
||||||
(try
|
|
||||||
(require 'taoensso.telemere) ; For macro expansion
|
|
||||||
(catch Exception e
|
|
||||||
(throw
|
|
||||||
(ex-info "Failed to require `taoensso.telemere` - `(require-telemere-if-present)` call missing?"
|
|
||||||
{} e))))
|
|
||||||
|
|
||||||
(with-meta ; Keep callsite
|
|
||||||
`(taoensso.telemere/signal! ~(dissoc opts :fallback))
|
|
||||||
(meta &form)))
|
|
||||||
|
|
||||||
(let [fb-form (get opts :fallback)]
|
(let [fb-form (get opts :fallback)]
|
||||||
(if-let [run-form (get opts :run)]
|
(if-let [run-form (get opts :run)]
|
||||||
`(let [run-result# ~run-form] ~fb-form run-result#)
|
`(let [run-result# ~run-form] ~fb-form run-result#)
|
||||||
(do fb-form))))
|
(do fb-form))))))
|
||||||
|
|
||||||
(throw
|
|
||||||
(ex-info "`signal!` expects map opts"
|
|
||||||
{:given {:value opts, :type (type opts)}})))))
|
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(macroexpand
|
(macroexpand
|
||||||
|
|
@ -123,3 +152,32 @@
|
||||||
:msg ["Hello" "world" x]
|
:msg ["Hello" "world" x]
|
||||||
:data {:a :A :x x}
|
:data {:a :A :x x}
|
||||||
:fallback (println (str "Hello world " x))})))
|
:fallback (println (str "Hello world " x))})))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defmacro signal-allowed?
|
||||||
|
"Experimental, subject to change.
|
||||||
|
Returns true iff Telemere is present and signal with given opts would meet
|
||||||
|
filtering conditions.
|
||||||
|
|
||||||
|
MUST be used with `require-telemere-if-present`, example:
|
||||||
|
|
||||||
|
(ns my-lib (:require [taoensso.telemere.shell :as t]))
|
||||||
|
(t/require-telemere-if-present) ; Just below `ns` form!
|
||||||
|
|
||||||
|
(when (t/signal-allowed? {:level :warn, <...>})
|
||||||
|
(my-custom-code))"
|
||||||
|
|
||||||
|
{:arglists
|
||||||
|
'([{:as opts :keys
|
||||||
|
[#_fallback, ; Unique to shell
|
||||||
|
#_defaults #_elide? #_allow? #_expansion-id, ; Undocumented
|
||||||
|
elidable? location #_location* #_inst #_uid #_middleware,
|
||||||
|
sample-rate kind ns id level when rate-limit,
|
||||||
|
#_ctx #_parent #_root #_trace?, #_do #_let #_data #_msg #_error #_run #_& #_kvs]}])}
|
||||||
|
|
||||||
|
[opts]
|
||||||
|
(if telemere-present?
|
||||||
|
(do (require-telemere!) `(taoensso.telemere/signal-allowed? ~(signal-opts &form &env opts)))
|
||||||
|
(get opts :fallback nil))))
|
||||||
|
|
||||||
|
(comment (macroexpand '(signal-allowed? {:level :warn, :sample-rate 0.5})))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue