mirror of
https://github.com/taoensso/telemere.git
synced 2026-01-27 08:40:35 +00:00
[doc] Documentation improvements
This commit is contained in:
parent
c4d9dd09a3
commit
12f4b35d71
16 changed files with 165 additions and 83 deletions
|
|
@ -41,7 +41,7 @@ See [here][GitHub releases] for earlier releases.
|
|||
#### Flexibility
|
||||
|
||||
- Config via plain **Clojure vals and fns** for easy customization, composition, and REPL debugging.
|
||||
- Unmatched support for **system-level config** (JVM props, ENV vars, classpath resources).
|
||||
- Unmatched **environmental config** support (JVM properties, environment variables, or classpath resources).
|
||||
- Expressive **per-call** and **per-handler** filtering at both **runtime** and **compile-time**.
|
||||
- Filter by namespace and id pattern, level, **level by namespace pattern**, etc.
|
||||
- **Sampling**, **rate-limiting**, and **back-pressure monitoring**.
|
||||
|
|
|
|||
|
|
@ -160,7 +160,8 @@
|
|||
|
||||
(defn handler:my-handler ; Note naming convention
|
||||
"Returns a (fn handler [signal] that:
|
||||
- Does something.
|
||||
- Takes a Telemere signal.
|
||||
- Does something with it.
|
||||
|
||||
Options:
|
||||
`:option1` - Description
|
||||
|
|
@ -169,8 +170,9 @@
|
|||
([] (handler:my-handler nil)) ; Use default opts
|
||||
([{:as constructor-opts}]
|
||||
|
||||
;; Do expensive prep outside returned handler fn whenever possible -
|
||||
;; i.e. at (one-off) construction time rather than handling time.
|
||||
;; Do option validation and expensive prep *outside* returned handler
|
||||
;; fn whenever possible - i.e. at (one-off) construction time rather than
|
||||
;; at every handler call.
|
||||
(let []
|
||||
|
||||
(fn a-handler:my-handler ; Note naming convention
|
||||
|
|
|
|||
52
resources/signal-docstrings/filter-env-config.txt
Normal file
52
resources/signal-docstrings/filter-env-config.txt
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
Environmental filter config includes:
|
||||
|
||||
Kind filter:
|
||||
JVM property: `taoensso.telemere.rt-kind-filter.edn`
|
||||
Env variable: `TAOENSSO_TELEMERE_RT_KIND_FILTER_EDN`
|
||||
Classpath resource: `taoensso.telemere.rt-kind-filter.edn`
|
||||
|
||||
Namespace filter:
|
||||
JVM property: `taoensso.telemere.rt-ns-filter.edn`
|
||||
Env variable: `TAOENSSO_TELEMERE_RT_NS_FILTER_EDN`
|
||||
Classpath resource: `taoensso.telemere.rt-ns-filter.edn`
|
||||
|
||||
Id filter:
|
||||
JVM property: `taoensso.telemere.rt-id-filter.edn`
|
||||
Env variable: `TAOENSSO_TELEMERE_RT_ID_FILTER_EDN`
|
||||
Classpath resource: `taoensso.telemere.rt-id-filter.edn`
|
||||
|
||||
Minimum level:
|
||||
JVM property: `taoensso.telemere.rt-min-level.edn`
|
||||
Env variable: `TAOENSSO_TELEMERE_RT_MIN_LEVEL_EDN`
|
||||
Classpath resource: `taoensso.telemere.rt-min-level.edn`
|
||||
|
||||
Examples:
|
||||
|
||||
`taoensso.telemere.rt-min-level.edn` -> ":info"
|
||||
`TAOENSSO_TELEMERE_RT_NS_FILTER_EDN` -> "{:deny \"taoensso.*\"}"
|
||||
`taoensso.telemere.rt-id-filter.cljs.edn` -> "#{:my-id1 :my-id2}"
|
||||
`TAOENSSO_TELEMERE_RT_KIND_FILTER_CLJ_EDN` -> "nil"
|
||||
|
||||
Tips:
|
||||
|
||||
- The above ids are for runtime filters (the most common).
|
||||
For compile-time filters, change `rt`->`ct` / `RT`->`CT`.
|
||||
|
||||
- The above ids will affect both Clj AND Cljs.
|
||||
For platform-specific filters, use
|
||||
".clj.edn" / "_CLJ_EDN" or
|
||||
".cljs.edn" / "_CLJS_EDN" suffixes instead.
|
||||
|
||||
- ".edn" / "_EDN" suffixes are optional.
|
||||
|
||||
- Config values should be edn. To get the right syntax, first set
|
||||
your runtime filters using the standard utils (`set-min-level!`,
|
||||
etc.). Then call `get-filters` and serialize the relevant parts
|
||||
to edn with `pr-str`.
|
||||
|
||||
- All environmental config uses `get-env` underneath.
|
||||
See the `get-env` docstring for more/advanced details.
|
||||
|
||||
- Classpath resources are files accessible on your project's
|
||||
classpath. This usually includes files in your project's
|
||||
`resources/` dir.
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
These include:
|
||||
|
||||
Compile-time:
|
||||
|
||||
ns-filter: (get-env {:as :edn} :taoensso.telemere/ct-ns-filter<.platform><.edn>)
|
||||
id-filter: (get-env {:as :edn} :taoensso.telemere/ct-id-filter<.platform><.edn>)
|
||||
min-level: (get-env {:as :edn} :taoensso.telemere/ct-min-level<.platform><.edn>)
|
||||
|
||||
Runtime:
|
||||
|
||||
ns-filter: (get-env {:as :edn} :taoensso.telemere/rt-ns-filter<.platform><.edn>)
|
||||
id-filter: (get-env {:as :edn} :taoensso.telemere/rt-id-filter<.platform><.edn>)
|
||||
min-level: (get-env {:as :edn, :default :info} :taoensso.telemere/rt-min-level<.platform><.edn>)
|
||||
|
||||
See `get-env` for details.
|
||||
|
|
@ -28,7 +28,9 @@ Default signal keys:
|
|||
`:file` -------- ?str filename of signal creator callsite, same as (:file location)
|
||||
`:sample-rate` - ?rate ∈ℝ[0,1] for combined signal AND handler sampling (0.75 => allow 75% of signals, nil => allow all)
|
||||
|
||||
<kvs> ---------- Arb other user-level ?kvs given to signal creator
|
||||
<kvs> ---------- Other arb user-level ?kvs given to signal creator. Typically NOT included
|
||||
in handler output, so a great way to provide custom data/opts for use
|
||||
(only) by custom middleware/handlers.
|
||||
|
||||
If anything is unclear, please ping me (@ptaoussanis) so that I can improve these docs!
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
A signal will be provided to a handler iff ALL of the following are true:
|
||||
|
||||
1. Signal (creation) is allowed by compile-time filters
|
||||
2. Signal (creation) is allowed by runtime filters
|
||||
3. Signal (handling) is allowed by handler filters
|
||||
|
|
@ -7,18 +8,40 @@ A signal will be provided to a handler iff ALL of the following are true:
|
|||
5. Handler middleware does not suppress the signal (return nil)
|
||||
|
||||
For 1-3, filtering may depend on (in order):
|
||||
|
||||
Sample rate → namespace → kind → id → level → when form/fn → rate limit
|
||||
|
||||
Note that sample rates are multiplicative:
|
||||
If a signal is created with 20% sampling and a handler handles 50%
|
||||
of given signals, then 10% of possible signals will be handled.
|
||||
Compile-time vs runtime filtering:
|
||||
|
||||
This multiplicative rate is helpfully reflected in each signal's final
|
||||
Compile-time filtering is an advanced feature that can be tricky to set
|
||||
and use correctly. Most folks will want ONLY runtime filtering.
|
||||
|
||||
Compile-time filtering works by eliding (completely removing the code for)
|
||||
disallowed signals. This means zero performance cost for these signals,
|
||||
but also means that compile-time filtering is PERMANENT once applied.
|
||||
|
||||
So if you set `:info` as the compile-time minimum level, that'll REMOVE
|
||||
CODE for every signal call below `:info` level. To decrease that minimum
|
||||
level, you'll need to rebuild.
|
||||
|
||||
Compile-time filtering can be set ONLY with environmental config
|
||||
(JVM properties, environment variables, or classpath resources).
|
||||
|
||||
Signal and handler sampling is multiplicative:
|
||||
|
||||
Both signals and handlers can have independent sample rates, and these
|
||||
MULTIPLY!
|
||||
|
||||
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%).
|
||||
|
||||
The multiplicative rate is helpfully reflected in each signal's final
|
||||
`:sample-rate` value.
|
||||
|
||||
For a visual flowchart, see: Ref. <https://www.taoensso.com/telemere/flow>
|
||||
|
||||
For more info:
|
||||
|
||||
- Signal visual flowchart, Ref. <https://www.taoensso.com/telemere/flow>
|
||||
- On signal filters, see: `help:signal-filters` docstring
|
||||
- On handler filters, see: `help:signal-handlers` docstring
|
||||
|
||||
|
|
|
|||
|
|
@ -18,14 +18,18 @@ Signal options (shared by all signal creators):
|
|||
`:parent` ------ Custom ?{:keys [id uid]} to override auto (dynamic) parent signal info in signal
|
||||
`:location` ---- Custom ?{:keys [ns line column file]} to override auto signal creator callsite location
|
||||
|
||||
`:elidable?` --- Should signal be subject to compile-time elision? (Default: true).
|
||||
`:elidable?` --- Should signal be subject to compile-time elision? (Default: true)
|
||||
`:sample-rate` - ?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
|
||||
`:middleware` -- ?[(fn [signal])=>modified-signal ...] signal middleware
|
||||
`:trace?` ------ Should tracing be enabled for `:run` form?
|
||||
|
||||
<kvs> ---------- Arb other user-level ?kvs to incl. in signal
|
||||
<kvs> ---------- Other arb user-level ?kvs to incl. in signal. Typically NOT included in
|
||||
handler output, so a great way to provide custom data/opts for use
|
||||
(only) by custom middleware/handlers.
|
||||
|
||||
handler-specific data that can just be ignored by other handlers
|
||||
|
||||
If anything is unclear, please ping me (@ptaoussanis) so that I can improve these docs!
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@
|
|||
:ct-sig-filter impl/ct-sig-filter
|
||||
:*rt-sig-filter* impl/*rt-sig-filter*
|
||||
:*sig-handlers* impl/*sig-handlers*
|
||||
:sig-filter-system-vals-info
|
||||
(impl/signal-docstring :filter-system-vals)})
|
||||
:sig-filter-env-config-help
|
||||
(impl/signal-docstring :filter-env-config)})
|
||||
|
||||
(comment help:filters)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,29 +34,35 @@
|
|||
;;;; Config
|
||||
|
||||
#?(:clj
|
||||
(let [base (enc/get-env {:as :edn} :taoensso.telemere/ct-filters<.platform><.edn>)
|
||||
ns-filter (enc/get-env {:as :edn} :taoensso.telemere/ct-ns-filter<.platform><.edn>)
|
||||
id-filter (enc/get-env {:as :edn} :taoensso.telemere/ct-id-filter<.platform><.edn>)
|
||||
min-level (enc/get-env {:as :edn} :taoensso.telemere/ct-min-level<.platform><.edn>)]
|
||||
(let [base (enc/get-env {:as :edn} :taoensso.telemere/ct-filters<.platform><.edn>)
|
||||
kind-filter (enc/get-env {:as :edn} :taoensso.telemere/ct-kind-filter<.platform><.edn>)
|
||||
ns-filter (enc/get-env {:as :edn} :taoensso.telemere/ct-ns-filter<.platform><.edn>)
|
||||
id-filter (enc/get-env {:as :edn} :taoensso.telemere/ct-id-filter<.platform><.edn>)
|
||||
min-level (enc/get-env {:as :edn} :taoensso.telemere/ct-min-level<.platform><.edn>)]
|
||||
|
||||
(enc/defonce ct-sig-filter
|
||||
"`SigFilter` used for compile-time elision, or nil."
|
||||
(sigs/sig-filter
|
||||
{:ns-filter (or ns-filter (get base :ns-filter))
|
||||
:id-filter (or id-filter (get base :id-filter))
|
||||
:min-level (or min-level (get base :min-level))}))))
|
||||
{:kind-filter (or kind-filter (get base :kind-filter))
|
||||
:ns-filter (or ns-filter (get base :ns-filter))
|
||||
:id-filter (or id-filter (get base :id-filter))
|
||||
:min-level (or min-level (get base :min-level))}))))
|
||||
|
||||
(let [base (enc/get-env {:as :edn} :taoensso.telemere/rt-filters<.platform><.edn>)
|
||||
ns-filter (enc/get-env {:as :edn} :taoensso.telemere/rt-ns-filter<.platform><.edn>)
|
||||
id-filter (enc/get-env {:as :edn} :taoensso.telemere/rt-id-filter<.platform><.edn>)
|
||||
min-level (enc/get-env {:as :edn, :default :info} :taoensso.telemere/rt-min-level<.platform><.edn>)]
|
||||
(let [base (enc/get-env {:as :edn} :taoensso.telemere/rt-filters<.platform><.edn>)
|
||||
kind-filter (enc/get-env {:as :edn} :taoensso.telemere/rt-kind-filter<.platform><.edn>)
|
||||
ns-filter (enc/get-env {:as :edn} :taoensso.telemere/rt-ns-filter<.platform><.edn>)
|
||||
id-filter (enc/get-env {:as :edn} :taoensso.telemere/rt-id-filter<.platform><.edn>)
|
||||
min-level (enc/get-env {:as :edn, :default :info} :taoensso.telemere/rt-min-level<.platform><.edn>)]
|
||||
|
||||
(enc/defonce ^:dynamic *rt-sig-filter*
|
||||
"`SigFilter` used for runtime filtering, or nil."
|
||||
(sigs/sig-filter
|
||||
{:ns-filter (or ns-filter (get base :ns-filter))
|
||||
:id-filter (or id-filter (get base :id-filter))
|
||||
:min-level (or min-level (get base :min-level))})))
|
||||
{:kind-filter (or kind-filter (get base :kind-filter))
|
||||
:ns-filter (or ns-filter (get base :ns-filter))
|
||||
:id-filter (or id-filter (get base :id-filter))
|
||||
:min-level (or min-level (get base :min-level))})))
|
||||
|
||||
(comment (enc/get-env {:as :edn, :return :explain} :taoensso.telemere/rt-filters<.platform><.edn>))
|
||||
|
||||
;;;; Context (optional arb app-level state)
|
||||
;; taoensso.telemere/*ctx*
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@
|
|||
(defn tools-logging->telemere!
|
||||
"Configures `clojure.tools.logging` to use Telemere as its logging implementation.
|
||||
|
||||
Called automatically if the following is true:
|
||||
(get-env {:as :bool} :clojure.tools.logging/to-telemere)
|
||||
|
||||
See `get-env` for details."
|
||||
Called automatically if one of the following is \"true\":
|
||||
JVM property: `clojure.tools.logging.to-telemere`
|
||||
Env variable: `CLOJURE_TOOLS_LOGGING_TO_TELEMERE`
|
||||
Classpath resource: `clojure.tools.logging.to-telemere`"
|
||||
[]
|
||||
(impl/signal!
|
||||
{:kind :event
|
||||
|
|
|
|||
|
|
@ -188,11 +188,11 @@ Quick examples of some basic filtering:
|
|||
```
|
||||
|
||||
- Filtering is always O(1), except for rate limits which are O(n_windows).
|
||||
- Sample rates are *multiplicative*: if a signal is created with *20%* sampling and a handler handles *50%* of given signals, then *10%* of possible signals will be handled. This multiplicative rate is helpfully reflected in each signal's final `:sample-rate` value.
|
||||
- Signal and handler sampling is *multiplicative*: if a signal is created with *20%* sampling and a handler handles *50%* of received signals, then *10%* of possible signals will be handled. This multiplicative rate is helpfully reflected in each signal's final `:sample-rate` value.
|
||||
- See [`help:signal-flow`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-flow) for internal docs on signal flow.
|
||||
- See section [2-Architecture](./2-Architecture) for a flowchart / visual aid.
|
||||
|
||||
Runtime signal filters can be configured with:
|
||||
Runtime signal filters can be set with:
|
||||
|
||||
| Global | Dynamic | Filters by |
|
||||
| :-------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------- |
|
||||
|
|
@ -202,7 +202,7 @@ Runtime signal filters can be configured with:
|
|||
| [`set-min-level`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#set-min-level) | [`with-min-level`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#with-min-level) | Signal level (minimum can be specified by kind and/or ns) |
|
||||
|
||||
- See relevant docstrings (links above) for usage info.
|
||||
- Compile-time filters are controlled by system-level config, see section [3-Config](./3-Config).
|
||||
- Compile-time filters are set with environmental config, see section [3-Config](./3-Config).
|
||||
|
||||
# Internal help
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ A signal will be provided to a handler iff ALL of the following are true:
|
|||
For 1-3, filtering may depend on (in order):
|
||||
Sample rate → namespace → kind → id → level → when form/fn → rate limit
|
||||
|
||||
- See [`help:signal-filters`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-filters) for info on signal creation filters.
|
||||
- See [`help:signal-filters`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-filters) for info on signal creation filters, **environmental config**, etc.
|
||||
- See [`add-handler!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#add-handler!) for info on signal handler filters.
|
||||
|
||||
# Signal handlers
|
||||
|
|
@ -29,7 +29,7 @@ See section [4-Handlers](./4-Handlers).
|
|||
To do this:
|
||||
|
||||
1. Ensure that you have the `clojure.tools.logging` dependency, and
|
||||
2. Call [`tools-logging->telemere!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.tools-logging#tools-logging-%3Etelemere!), or set the relevant system config as described in its docstring.
|
||||
2. Call [`tools-logging->telemere!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.tools-logging#tools-logging-%3Etelemere!), or set the relevant environmental config as described in its docstring.
|
||||
|
||||
Verify successful intake with [`check-intakes`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#check-intakes):
|
||||
|
||||
|
|
|
|||
|
|
@ -2,18 +2,22 @@ Signal handlers process created signals to *do something with them* (analyse the
|
|||
|
||||
# Included handlers
|
||||
|
||||
The following handlers are included out-the-box:
|
||||
The following signal handlers are currently included out-the-box:
|
||||
|
||||
| Name | Platform | Writes signals to | Writes signals as |
|
||||
| :------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------- |
|
||||
| [`handler:console`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) | Clj | `*out*` or `*err*` | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
||||
| [`handler:console`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) | Cljs | Browser console | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
||||
| [`handler:console-raw`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console-raw) | Cljs | Browser console | Raw data (for [cljs-devtools](https://github.com/binaryage/cljs-devtools), etc.) |
|
||||
| [`handler:file`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:file) | Clj | File/s on disk | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
||||
| [`handler:open-telemetry-logger`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.open-telemetry#handler:open-telemetry-logger) | Clj | [OpenTelemetry](https://opentelemetry.io/) [Java client](https://github.com/open-telemetry/opentelemetry-java) | [LogRecord](https://opentelemetry.io/docs/specs/otel/logs/data-model/) |
|
||||
| Name | Platform | Output target | Output format |
|
||||
| :------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------- |
|
||||
| [`handler:console`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) | Clj | `*out*` or `*err*` | Formatted string [1] |
|
||||
| [`handler:console`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) | Cljs | Browser console | Formatted string [1] |
|
||||
| [`handler:console-raw`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console-raw) | Cljs | Browser console | Raw signal data [2] |
|
||||
| [`handler:file`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:file) | Clj | File/s on disk | Formatted string [1] |
|
||||
| [`handler:postal`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.postal#handler:postal) | Clj | Email (via [postal](https://github.com/drewr/postal)) | Formatted string [1] |
|
||||
| [`handler:open-telemetry-logger`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.open-telemetry#handler:open-telemetry-logger) | Clj | [OpenTelemetry](https://opentelemetry.io/) [Java client](https://github.com/open-telemetry/opentelemetry-java) | [LogRecord](https://opentelemetry.io/docs/specs/otel/logs/data-model/) |
|
||||
|
||||
- See relevant docstrings (links above) for more info.
|
||||
- See section [8-Community](8-Community.md) for additional handlers.
|
||||
- \[1] [Configurable](https://cljdoc.org/d/com.taoensso/telemere/1.0.0-beta3/api/taoensso.telemere#help:signal-formatters): human-readable (default), [edn](https://github.com/edn-format/edn), [JSON](https://www.json.org/), etc.
|
||||
- \[2] For use with browser formatting tools like [cljs-devtools](https://github.com/binaryage/cljs-devtools).
|
||||
- See relevant docstrings (links above) for features, usage, etc.
|
||||
- See section [8-Community](8-Community.md) for more (community-supported) handlers.
|
||||
- If there's other handlers you'd like to see, feel free to [ping me](https://github.com/taoensso/telemere/issues), or ask on the [`#telemere` Slack channel](https://www.taoensso.com/telemere/slack). It helps to know what people most need!
|
||||
|
||||
# Configuring handlers
|
||||
|
||||
|
|
@ -97,11 +101,11 @@ Want to add or remove a particular handler when your application starts?
|
|||
|
||||
Just make an appropriate call to [`add-handler!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#add-handler!) or [`remove-handler!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#remove-handler!).
|
||||
|
||||
## System-level config
|
||||
## Environmental config
|
||||
|
||||
If you want to manage handlers **conditionally** based on **system-level config** (e.g. JVM prop, ENV var, or classpath resource) - Telemere provides the highly flexible [`get-env`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#get-env) util.
|
||||
If you want to manage handlers **conditionally** based on **environmental config** (JVM properties, environment variables, or classpath resources) - Telemere provides the highly flexible [`get-env`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#get-env) util.
|
||||
|
||||
Use this to easily check your own cross-platform system config, and make whatever conditional handler management decisions you'd like.
|
||||
Use this to easily define your own arbitrary cross-platform config, and make whatever conditional handler management decisions you'd like.
|
||||
|
||||
# Writing handlers
|
||||
|
||||
|
|
@ -120,7 +124,8 @@ For more complex cases, or for handlers that you want to make available for use
|
|||
```clojure
|
||||
(defn handler:my-handler ; Note naming convention
|
||||
"Returns a (fn handler [signal] that:
|
||||
- Does something.
|
||||
- Takes a Telemere signal.
|
||||
- Does something with it.
|
||||
|
||||
Options:
|
||||
`:option1` - Description
|
||||
|
|
@ -129,8 +134,9 @@ For more complex cases, or for handlers that you want to make available for use
|
|||
([] (handler:my-handler nil)) ; Use default opts
|
||||
([{:as constructor-opts}]
|
||||
|
||||
;; Do expensive prep outside returned handler fn whenever possible -
|
||||
;; i.e. at (one-off) construction time rather than handling time.
|
||||
;; Do option validation and expensive prep *outside* returned handler
|
||||
;; fn whenever possible - i.e. at (one-off) construction time rather than
|
||||
;; at every handler call.
|
||||
(let []
|
||||
|
||||
(fn a-handler:my-handler ; Note naming convention
|
||||
|
|
@ -181,4 +187,4 @@ Chrome console, with [cljs-devtools](https://github.com/binaryage/cljs-devtools)
|
|||
|
||||
MacOS terminal:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/taoensso/telemere/master/imgs/handler-output-clj-file.png" alt="Default Clojure file handler output" width="640"/>
|
||||
<img src="https://raw.githubusercontent.com/taoensso/telemere/master/imgs/handler-output-clj-file.png" alt="Default Clojure file handler output" width="640"/>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ If not, you may need to [write something yourself](./4-Handlers#writing-handlers
|
|||
|
||||
This may be easier than it sounds. Remember that signals are just plain Clojure/Script [maps](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-content), and handlers just plain Clojure/Script functions that do something with those maps.
|
||||
|
||||
Feel free to [ping me](https://github.com/taoensso/telemere/issues) for assistance, or ask on the [`#telemere` Slack channel](https://clojurians.slack.com/archives/C06ALA6EEUA).
|
||||
Feel free to [ping me](https://github.com/taoensso/telemere/issues) for assistance, or ask on the [`#telemere` Slack channel](https://www.taoensso.com/telemere/slack).
|
||||
|
||||
### 2. Imports
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ Consider the [differences](https://www.youtube.com/watch?v=oyLBGkS5ICk) between
|
|||
|
||||
- [`log!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#log!) and [`event!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#event!) are both **good general-purpose** signal creators.
|
||||
|
||||
- Try **always provide an id** for all signals you create.
|
||||
- **Provide an id** for all signals you create.
|
||||
|
||||
Qualified keywords are perfect! Downstream behaviour (e.g. alerts) can then look for these ids rather than messages (which are harder to match and more likely to change).
|
||||
|
||||
|
|
@ -84,11 +84,13 @@ Consider the [differences](https://www.youtube.com/watch?v=oyLBGkS5ICk) between
|
|||
|
||||
The result of signal middleware is cached and *shared between all handlers* making it an efficient place to transform signals. For this reason - prefer signal middleware to handler middleware when possible/convenient.
|
||||
|
||||
- **Signal sampling** and **handler sampling** are **multiplicative**.
|
||||
- Signal and handler **sampling is multiplicative**.
|
||||
|
||||
If a signal is created with *20%* sampling and a handler handles *50%* of given signals, then *10%* of possible signals will be handled.
|
||||
Both signals and handlers can have independent sample rates, and these MULTIPLY!
|
||||
|
||||
This multiplicative rate is helpfully reflected in each signal's final `:sample-rate` value, making it possible to estimate unsampled cardinalities in relevant cases.
|
||||
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.
|
||||
|
||||
|
|
@ -117,7 +119,7 @@ Consider the [differences](https://www.youtube.com/watch?v=oyLBGkS5ICk) between
|
|||
|
||||
Note that all user kvs will *also* be available *together* under the signal's `:kvs` key.
|
||||
|
||||
User kvs are a great way of controlling the per-signal behaviour of custom/advanced handlers.
|
||||
User kvs are typically *not* included in handler output, so are a great way of providing custom data/opts for use (only) by custom middleware or handlers.
|
||||
|
||||
- Signal `kind` can be useful in advanced cases.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ If there's demand, additional stuff can then be authored by Telemere's *communit
|
|||
|
||||
**PRs very welcome** to add links to this page for:
|
||||
|
||||
- Handlers (see [Writing handlers](./4-Handlers#writing-handlers))
|
||||
- Handler libraries or examples (see [Writing handlers](./4-Handlers#writing-handlers))
|
||||
- Handler utils (formatters, etc.)
|
||||
- Middleware
|
||||
- Tutorials / demos / etc.
|
||||
|
|
@ -12,9 +12,9 @@ If there's demand, additional stuff can then be authored by Telemere's *communit
|
|||
|
||||
If you spot issues with any linked resources, please **contact the relevant authors** to let them know! Thank you! 🙏
|
||||
|
||||
| Contributor | Link | Description |
|
||||
| :--------------------------------------------- | :-------------------------------------------------------------------------- | :------------------------------------------------------------ |
|
||||
| [@ptaoussanis](https://github.com/ptaoussanis) | [Official Slack channel](https://clojurians.slack.com/archives/C06ALA6EEUA) | For questions, support, etc. |
|
||||
| [@ptaoussanis](https://github.com/ptaoussanis) | [GitHub issues](https://github.com/taoensso/telemere/issues) | For questions, support, bug reports, PRs, etc. |
|
||||
| _ | _ | Your link here? [PRs](../wiki#contributions-welcome) welcome! |
|
||||
| [@username](https://github.com/username) | [Project](https://github.com/username/project) | Short description of resource |
|
||||
| Contributor | Link | Description |
|
||||
| :--------------------------------------------- | :---------------------------------------------------------------- | :------------------------------------------------------------ |
|
||||
| [@ptaoussanis](https://github.com/ptaoussanis) | [Official Slack channel](https://www.taoensso.com/telemere/slack) | For questions, support, etc. |
|
||||
| [@ptaoussanis](https://github.com/ptaoussanis) | [GitHub issues](https://github.com/taoensso/telemere/issues) | For questions, support, bug reports, PRs, etc. |
|
||||
| _ | _ | Your link here? [PRs](../wiki#contributions-welcome) welcome! |
|
||||
| [@username](https://github.com/username) | [Project](https://github.com/username/project) | Short description of resource |
|
||||
|
|
|
|||
Loading…
Reference in a new issue