Documentation | Latest releases | Get support
Telemere is a next-generation replacement for Timbre. It handles structured and traditional logging, tracing, and basic performance monitoring with a simple unified API.
It helps enable the creation of Clojure/Script systems that are highly observable, robust, and debuggable - and it represents the refinement and culmination of ideas brewing over 12+ years in Timbre, Tufte, Truss, etc.
[Terminology] Telemetry is derived from the Greek roots tele (remote) and metron (measure). It refers to the collection of in situ (in position) information, for transmission to other systems for monitoring/analysis. Logs are the most common form of software telemetry. So think of telemetry as the superset of logging-like activities that help monitor and understand (software) systems.
This library is still under development, ETA: end April 2024.
v1.0.0-alpha5
(dev): release info (for early adopters)See here for earlier releases.
See for intro and usage:
TODO: soon
(require '[taoensso.telemere :as t])
;; Start simple
(t/log! "This will send a `:log` signal to the Clj/s console")
(t/log! :info "This will do the same, but only when the current level is >= `:info`")
;; Easily construct messages
(let [x "constructed"] (t/log! :info ["Here's a" x "message!"]))
;; Attach an id
(t/log! {:level :info, :id ::my-id} "This signal has an id")
;; Attach arb user data
(t/log! {:level :info, :data {:x :y}} "This signal has structured data")
;; Capture for debug/testing
(t/with-signal (t/log! "This will be captured"))
;; => {:keys [location level id data msg_ ...]}
;; `:let` bindings available to `:data` and message, only paid for
;; when allowed by minimum level and other filtering criteria
(t/log!
{:level :info
:let [expensive-metric1 (last (for [x (range 100), y (range 100)] (* x y)))]
:data {:metric1 expensive-metric1}}
["Message with metric value:" expensive-metric1])
;; With sampling 50% and 1/sec rate limiting
(t/log!
{:sample-rate 0.5
:rate-limit {"1 per sec" [1 1000]}}
"This signal will be sampled and rate limited")
;;; A quick taste of filtering...
(t/set-ns-filter! {:deny "taoensso.*" :allow "taoensso.sente.*"}) ; Set namespace filter
(t/set-id-filter! {:allow #{::my-particular-id "my-app/*"}}) ; Set id filter
(t/set-min-level! :warn) ; Set minimum level
(t/set-min-level! :log :debug) ; Set minimul level for `:log` signals
;; Set minimum level for `:event` signals originating in the "taoensso.sente.*" ns
(t/set-min-level! :event "taoensso.sente.*" :warn)
See links below for docstrings/usage, and documentation for lots more info.
Name | Signal kind | Main arg | Optional arg | Returns |
---|---|---|---|---|
signal! | <arb> | opts | - | Signal allowed? / form result (value or throw) |
log! | :log | msg | opts /level | Signal allowed? |
event! | :event | id | opts /level | Signal allowed? |
error! | :error | error | opts /id | Given error |
trace! | :trace | form | opts /id | Form result |
spy! | :spy | form | opts /level | Form result |
catch->error! | :error | form | opts /id | Form value or given fallback |
Global | Dynamic | Filters by |
---|---|---|
set-kind-filter! | with-kind-filter | Signal kind (:log , :event , etc.) |
set-ns-filter! | with-ns-filter | Signal namespace |
set-id-filter! | with-id-filter | Signal id |
set-min-level | with-min-level | Signal level (minimum can be specified by kind and/or ns) |
Telemere includes extensive internal help docstrings:
Var | Help with |
---|---|
help:signal-options | Options for standard signal creators |
help:signal-content | Content of signal maps |
help:signal-flow | Ordered flow from signal creation to handling |
help:signal-filters | API for configuring signal filters |
help:signal-handlers | API for configuring signal handlers |
help:signal-formatters | Signal formatters for use by handlers |
(t/log! {:id ::my-id, :data {:x1 :x2}} "My message") =>
2024-04-11T10:54:57.202869Z INFO LOG Schrebermann.local examples(56,1) ::my-id - My message
data: {:x1 :x2}
See here for general advice re: building and maintaining observable Clojure/Script systems.
Telemere is highly optimized and offers terrific performance at any scale:
Compile-time filtering? | Runtime filtering? | Time? | Trace? | nsecs |
---|---|---|---|---|
✓ (elide) | - | - | - | 0 |
- | ✓ | - | - | 200 |
- | ✓ | ✓ | - | 280 |
- | ✓ | ✓ | ✓ | 650 |
Measurements:
Tip: Telemere offers extensive per-call and per-handler filtering, sampling, and rate-limiting. Use these to ensure that you're not capturing useless/low-value information in production. See here for more tips!
You can help support continued work on this project, thank you!! 🙏
Copyright © 2023-2024 Peter Taoussanis.
Licensed under EPL 1.0 (same as Clojure).
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close