diff --git a/README.md b/README.md index 967bbe2..c9b6c67 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ It enables you to write code that is **information-verbose by default**. ;; Getting fancy (all costs are conditional!) (t/log! {:level :debug - :sample-rate 0.75 ; 75% sampling (noop 25% of the time) + :sample 0.75 ; 75% sampling (noop 25% of the time) :when (my-conditional) :rate-limit {"1 per sec" [1 1000] "5 per min" [5 60000]} @@ -146,11 +146,11 @@ It enables you to write code that is **information-verbose by default**. ([] (println "Handler has shut down"))) {:async {:mode :dropping, :buffer-size 1024, :n-threads 1} - :priority 100 - :sample-rate 0.5 - :min-level :info - :ns-filter {:disallow "taoensso.*"} - :rate-limit {"1 per sec" [1 1000]} + :priority 100 + :sample 0.5 + :min-level :info + :ns-filter {:disallow "taoensso.*"} + :rate-limit {"1 per sec" [1 1000]} ;; See `t/help:handler-dispatch-options` for more }) diff --git a/examples.cljc b/examples.cljc index d6639f9..2f1c6ad 100644 --- a/examples.cljc +++ b/examples.cljc @@ -29,7 +29,7 @@ ;; Getting fancy (all costs are conditional!) (t/log! {:level :debug - :sample-rate 0.75 ; 75% sampling (noop 25% of the time) + :sample 0.75 ; 75% sampling (noop 25% of the time) :when (my-conditional) :rate-limit {"1 per sec" [1 1000] "5 per min" [5 60000]} @@ -89,7 +89,7 @@ {:async {:mode :dropping, :buffer-size 1024, :n-threads 1} :priority 100 - :sample-rate 0.5 + :sample 0.5 :min-level :info :ns-filter {:disallow "taoensso.*"} :rate-limit {"1 per sec" [1 1000]} @@ -360,8 +360,8 @@ ;; With sampling 50% and 1/sec rate limiting (t/log! - {:sample-rate 0.5 - :rate-limit {"1 per sec" [1 1000]}} + {:sample 0.5 + :rate-limit {"1 per sec" [1 1000]}} "This signal will be sampled and rate limited") ;; Several signal creators are available for convenience. diff --git a/main/resources/signal-docstrings/signal-content.txt b/main/resources/signal-docstrings/signal-content.txt index 85640a4..7606ed6 100644 --- a/main/resources/signal-docstrings/signal-content.txt +++ b/main/resources/signal-docstrings/signal-content.txt @@ -29,7 +29,7 @@ Default signal keys: `:host` -------- (Clj only) {:keys [name ip]} info for network host `:thread` ------ (Clj only) {:keys [name id group]} info for thread that created signal -`:sample-rate` - ?rate ∈ℝ[0,1] for combined signal AND handler sampling (0.75 => allow 75% of signals, nil => allow all) +`:sample` ------ Sample ?rate ∈ℝ[0,1] for combined call AND handler sampling (0.75 => allow 75% of signals, nil => allow all) ---------- Other arb app-level ?kvs given to signal creator. Typically NOT included in handler output, so a great way to provide custom data/opts for use diff --git a/main/resources/signal-docstrings/signal-options.txt b/main/resources/signal-docstrings/signal-options.txt index 1d549b6..0f64698 100644 --- a/main/resources/signal-docstrings/signal-options.txt +++ b/main/resources/signal-docstrings/signal-options.txt @@ -27,7 +27,7 @@ All options are available for all signal creator calls: `:elidable?` --- Should signal be subject to compile-time elision? (Default: true) `:trace?` ------ Should tracing be enabled for `:run` form? -`:sample-rate` - ?rate ∈ℝ[0,1] for signal sampling (0.75 => allow 75% of signals, nil => allow all) +`:sample` ------ Optional sample rate ∈ℝ[0,1] for signal sampling (0.75 => allow 75% of signals, nil => allow all) `:when` -------- Arb ?form; when present, form must return truthy to allow signal `:rate-limit` -- ?spec as given to `taoensso.telemere/rate-limiter`, see its docstring for details `:rate-limit-by` When present, rate limits will be enforced independently for each id (any Clojure value!) diff --git a/main/src/taoensso/telemere.cljc b/main/src/taoensso/telemere.cljc index 92e07fb..1e375d9 100644 --- a/main/src/taoensso/telemere.cljc +++ b/main/src/taoensso/telemere.cljc @@ -241,7 +241,7 @@ 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}) + (when (signal-allowed? {:level :info, :sample 0.5}) (log! {:allow? true} \"Message 1\") (log! {:allow? true} \"Message 2\"))" diff --git a/main/src/taoensso/telemere/impl.cljc b/main/src/taoensso/telemere/impl.cljc index d96af87..f41ba59 100644 --- a/main/src/taoensso/telemere/impl.cljc +++ b/main/src/taoensso/telemere/impl.cljc @@ -250,7 +250,7 @@ ;; Telemere's main public data type, we avoid nesting and duplication [schema inst uid, ns coords, #?@(:clj [host thread _otel-context]), - sample-rate, kind id level, ctx parent root, data kvs msg_, + sample, kind id level, ctx parent root, data kvs msg_, error run-form run-val end-inst run-nsecs] Object (toString [sig] (str "taoensso.telemere.Signal" (into {} sig)))) @@ -394,7 +394,7 @@ [{:as opts-map :keys [#_elide? #_allow? #_callsite-id, ; Undocumented elidable? coords #_inst #_uid #_xfn #_xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample kind ns id level when rate-limit rate-limit-by, #_ctx #_ctx+ #_parent #_root #_trace?, #_do #_let #_data #_msg #_error #_run #_& #_kvs]}]) :signal! ; opts => allowed? / run result (value or throw) @@ -402,7 +402,7 @@ [{:as opts-map :keys [#_elide? #_allow? #_callsite-id, ; Undocumented elidable? coords inst uid xfn xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample 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 => nil / allowed? @@ -411,7 +411,7 @@ [{:as opts-map :keys [#_elide? #_allow? #_callsite-id, elidable? coords inst uid xfn xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample kind ns id level when rate-limit rate-limit-by, ctx ctx+ parent root trace?, do let data msg error #_run & kvs]} msg]) @@ -422,7 +422,7 @@ {:as opts-map :keys [#_elide? #_allow? #_callsite-id, elidable? coords inst uid xfn xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample 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 => run result (value or throw) @@ -431,7 +431,7 @@ [{:as opts-map :keys [#_elide? #_allow? #_callsite-id, elidable? coords inst uid xfn xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample kind ns id level when rate-limit rate-limit-by, ctx ctx+ parent root trace?, do let data msg error run & kvs]} run]) @@ -441,7 +441,7 @@ [{:as opts-map :keys [#_elide? #_allow? #_callsite-id, elidable? coords inst uid xfn xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample kind ns id level when rate-limit rate-limit-by, ctx ctx+ parent root trace?, do let data msg error run & kvs]} run]) @@ -451,7 +451,7 @@ [{:as opts-map :keys [#_elide? #_allow? #_callsite-id, elidable? coords inst uid xfn xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample kind ns id level when rate-limit rate-limit-by, ctx ctx+ parent root trace?, do let data msg error #_run & kvs]} error]) @@ -461,7 +461,7 @@ [{:as opts-map :keys [#_elide? #_allow? #_callsite-id, catch-val, elidable? coords inst uid xfn xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample kind ns id level when rate-limit rate-limit-by, ctx ctx+ parent root trace?, do let data msg error #_run & kvs]} run]) @@ -471,7 +471,7 @@ [{:as opts-map :keys [#_elide? #_allow? #_callsite-id, elidable? coords inst uid xfn xfn+, - sample-rate kind ns id level when rate-limit rate-limit-by, + sample kind ns id level when rate-limit rate-limit-by, ctx ctx+ parent root trace?, do let data msg error #_run & kvs]}]) (truss/unexpected-arg! macro-id)))) @@ -603,12 +603,12 @@ uid-form (get opts :uid (when trace? :auto)) signal-delay-form - (let [{do-form :do - let-form :let - msg-form :msg - data-form :data - error-form :error - sample-rate-form :sample-rate} opts + (let [{do-form :do + let-form :let + msg-form :msg + data-form :data + error-form :error + sample-form :sample} opts let-form (or let-form '[]) msg-form (parse-msg-form msg-form) @@ -627,7 +627,7 @@ (not-empty (dissoc opts :elidable? :coords :inst :uid :xfn :xfn+, - :sample-rate :ns :kind :id :level :filter :when #_:rate-limit #_:rate-limit-by, + :sample :ns :kind :id :level :filter :when #_:rate-limit #_:rate-limit-by, :ctx :ctx+ :parent #_:trace?, :do :let :data :msg :error, :run :run-form :run-val, :elide? :allow? #_:callsite-id :otel/context)) @@ -649,10 +649,10 @@ (let [record-form (let [clause [(if run-form :run :no-run) (if clj? :clj :cljs)]] (case clause - [:run :clj ] `(Signal. 1 ~'__inst ~'__uid, ~'__ns ~coords (enc/host-info) ~'__thread ~'__otel-context1, ~sample-rate-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form ~'__root1, ~data-form ~kvs-form ~'_msg_, ~'_run-err '~show-run-form ~show-run-val ~'_end-inst ~'_run-nsecs) - [:run :cljs] `(Signal. 1 ~'__inst ~'__uid, ~'__ns ~coords ~sample-rate-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form ~'__root1, ~data-form ~kvs-form ~'_msg_, ~'_run-err '~show-run-form ~show-run-val ~'_end-inst ~'_run-nsecs) - [:no-run :clj ] `(Signal. 1 ~'__inst ~'__uid, ~'__ns ~coords (enc/host-info) ~'__thread ~'__otel-context1, ~sample-rate-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form ~'__root1, ~data-form ~kvs-form ~msg-form, ~error-form nil nil nil nil) - [:no-run :cljs] `(Signal. 1 ~'__inst ~'__uid, ~'__ns ~coords ~sample-rate-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form ~'__root1, ~data-form ~kvs-form ~msg-form, ~error-form nil nil nil nil) + [:run :clj ] `(Signal. 1 ~'__inst ~'__uid, ~'__ns ~coords (enc/host-info) ~'__thread ~'__otel-context1, ~sample-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form ~'__root1, ~data-form ~kvs-form ~'_msg_, ~'_run-err '~show-run-form ~show-run-val ~'_end-inst ~'_run-nsecs) + [:run :cljs] `(Signal. 1 ~'__inst ~'__uid, ~'__ns ~coords ~sample-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form ~'__root1, ~data-form ~kvs-form ~'_msg_, ~'_run-err '~show-run-form ~show-run-val ~'_end-inst ~'_run-nsecs) + [:no-run :clj ] `(Signal. 1 ~'__inst ~'__uid, ~'__ns ~coords (enc/host-info) ~'__thread ~'__otel-context1, ~sample-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form ~'__root1, ~data-form ~kvs-form ~msg-form, ~error-form nil nil nil nil) + [:no-run :cljs] `(Signal. 1 ~'__inst ~'__uid, ~'__ns ~coords ~sample-form, ~'__kind ~'__id ~'__level, ~ctx-form ~parent-form ~'__root1, ~data-form ~kvs-form ~msg-form, ~error-form nil nil nil nil) (truss/unexpected-arg! clause {:context :signal-constructor-args}))) record-form diff --git a/main/src/taoensso/telemere/open_telemetry.clj b/main/src/taoensso/telemere/open_telemetry.clj index 9708a03..64451d5 100644 --- a/main/src/taoensso/telemere/open_telemetry.clj +++ b/main/src/taoensso/telemere/open_telemetry.clj @@ -183,7 +183,7 @@ (put-attr! ab "run.val" run-val) (put-attr! ab "run.nsecs" run-nsecs))) - (put-attr! ab "sample" (get signal :sample-rate)) + (put-attr! ab "sample" (get signal :sample)) (when-let [{:keys [id uid]} (get signal :parent)] (put-attr! ab "parent.id" id) diff --git a/main/src/taoensso/telemere/utils.cljc b/main/src/taoensso/telemere/utils.cljc index a973c7d..9bb0de7 100644 --- a/main/src/taoensso/telemere/utils.cljc +++ b/main/src/taoensso/telemere/utils.cljc @@ -608,8 +608,8 @@ (let [af append-fn vf val-fn] - (let [{:keys [ns uid parent root data kvs ctx #?@(:clj [host thread]) sample-rate]} signal] - (when sample-rate (af " sample: " (vf sample-rate))) + (let [{:keys [ns uid parent root data kvs ctx #?@(:clj [host thread]) sample]} signal] + (when sample (af " sample: " (vf sample))) (when uid (af " uid: " (vf uid))) (when (and parent (not= parent root)) (af " parent: " (vf (format-parent ns parent)))) ; {:keys [id uid]} (when root (af " root: " (vf (format-parent ns root)))) ; {:keys [id uid]} diff --git a/main/test/taoensso/telemere_tests.cljc b/main/test/taoensso/telemere_tests.cljc index 9873071..622918b 100644 --- a/main/test/taoensso/telemere_tests.cljc +++ b/main/test/taoensso/telemere_tests.cljc @@ -549,11 +549,11 @@ (let [c (enc/counter) sr_ (atom nil)] (tel/with-handler "h1" - (fn h1 [x] (c) (compare-and-set! sr_ nil (:sample-rate x))) - {:async nil, :sample-rate handler-sample-rate} + (fn h1 [x] (c) (compare-and-set! sr_ nil (:sample x))) + {:async nil, :sample handler-sample-rate} (do ;; Repeat to ensure >=1 gets through sampling - (dotimes [_ 1000] (sig! {:level :info, :sample-rate call-sample-rate})) + (dotimes [_ 1000] (sig! {:level :info, :sample call-sample-rate})) [@sr_ @c]))))] [(is (= (test1 nil nil) [nil 1000]) "[none none] = none") @@ -1023,10 +1023,10 @@ :parent {:id ::parent-id1 :uid #uuid "443154cf-b6cf-47bf-b86a-8b185afee256"} :root {:id ::root-id1 :uid #uuid "82a53b6a-b28a-4102-8025-9e735dee103c"} - :run-form '(+ 3 2) - :run-val 5 - :run-nsecs 100 - :sample-rate 0.5 + :run-form '(+ 3 2) + :run-val 5 + :run-nsecs 100 + :sample 0.5 :data {:key-kw :val-kw diff --git a/wiki/7-Tips.md b/wiki/7-Tips.md index ab5d0e7..f114854 100644 --- a/wiki/7-Tips.md +++ b/wiki/7-Tips.md @@ -90,9 +90,7 @@ Consider the [differences](https://www.youtube.com/watch?v=oyLBGkS5ICk) between If a signal is created with *20%* sampling and a handler handles *50%* of received signals, then *10%* of possible signals will be handled (50% of 20%). - This multiplicative rate is helpfully reflected in each signal's final `:sample-rate` value, making it possible to estimate *unsampled* cardinalities in relevant cases. - - So for `n` randomly sampled signals matching some criteria, you'd have seen an estimated `Σ(1.0/sample-rate_i)` such signals _without_ sampling, etc. + When sampling is active, the final (combined multiplicative) rate is helpfully reflected in each signal's `:sample` rate value ∈ℝ[0,1]. This makes it possible to estimate _unsampled_ cardinalities: for `n` randomly sampled signals matching some criteria, you'd have seen an estimated `Σ(1.0/sample-rate_i)` such signals _without_ sampling, etc. - Transforms can technically return any type, but it's best to return only `nil` or a map. This ensures maximum compatibility with community transforms, handlers, and tools.