https://github.com/taoensso/tufte
Simple performance monitoring library for Clojure/Script
https://github.com/taoensso/tufte
benchmarking clojure clojurescript epl performance-monitoring profiling taoensso
Last synced: 7 months ago
JSON representation
Simple performance monitoring library for Clojure/Script
- Host: GitHub
- URL: https://github.com/taoensso/tufte
- Owner: taoensso
- License: epl-1.0
- Created: 2016-07-07T04:50:01.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2024-04-11T13:28:30.000Z (about 2 years ago)
- Last Synced: 2024-05-01T21:41:21.153Z (about 2 years ago)
- Topics: benchmarking, clojure, clojurescript, epl, performance-monitoring, profiling, taoensso
- Language: Clojure
- Homepage: https://www.taoensso.com/tufte
- Size: 683 KB
- Stars: 529
- Watchers: 13
- Forks: 22
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: FUNDING.yml
- License: LICENSE.txt
Awesome Lists containing this project
- stars - taoensso/tufte - Simple performance monitoring library for Clojure/Script \[*Eclipse Public License 1.0*\] (⭐️558) (Clojure)
README
[**API**][cljdoc] | [**Wiki**][GitHub wiki] | [Latest releases](#latest-releases) | [Slack channel][]
# Tufte
### Simple performance monitoring library for Clojure/Script
**Tufte** allows you to **easily monitor the ongoing performance** of your Clojure and ClojureScript applications in production and other environments.
It provides **sensible application-level metrics**, and gives them to you as **Clojure data** that can be easily analyzed programatically.
Use it alone, or as part of a suite of complementary **observability tools** for modern Clojure/Script applications:
- [Telemere](https://www.taoensso.com/telemere) for logging, tracing, and general telemetry
- [Tufte](https://www.taoensso.com/tufte) for performance monitoring
- [Truss](https://www.taoensso.com/truss) for assertions and error handling
- [Trove](https://www.taoensso.com/trove) for library authors that want to do structured logging

> [Carte Figurative](https://en.wikipedia.org/wiki/Charles_Joseph_Minard#The_map_of_Napoleon's_Russian_campaign), one of [Edward Tufte](https://en.wikipedia.org/wiki/Edward_Tufte)'s favourite data visualizations.
## Latest release/s
- `2025-06-23` `v3.0.0`: [release info](../../releases/tag/v3.0.0)
[![Clj tests][Clj tests SVG]][Clj tests URL]
[![Cljs tests][Cljs tests SVG]][Cljs tests URL]
[![Graal tests][Graal tests SVG]][Graal tests URL]
See [here][GitHub releases] for earlier releases.
## Why Tufte?
- Small, **fast**, cross-platform Clojure/Script codebase.
- Sensible **form-level** profiling without the low-level JVM noise.
- **Metrics as Clojure maps**: easily aggregate, **analyse**, log, serialize to db, etc.
- **Tiny**, flexible API: [`p`](https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte#p), [`profiled`](https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte#profiled), [`profile`](https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte#profile).
- Full support for **thread-local** and dynamic (**multi-threaded**) profiling.
- Rich [filtering](https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte#help:filters): **conditional profiling** by namespace, id pattern, level, level by namespace pattern, etc.
- Rich a/sync [handling](https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte#help:handler-dispatch-options): with sampling, rate limiting, back-pressure monitoring, etc.
- Includes handlers for [Telemere](https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte.telemere#handler:telemere), [Timbre](https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte.timbre#handler:timbre), and [consoles](https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte#handler:console) (`*out*`, etc.).
## Quick example
Using Tufte v3:
```clojure
(require '[taoensso.tufte :as tufte])
;; Send `profile` signals to console
(tufte/add-handler! :my-console-handler (tufte/handler:console))
;;; Define a couple dummy fns to simulate doing some expensive work
(defn get-x [] (Thread/sleep 500) "x val")
(defn get-y [] (Thread/sleep (rand-int 1000)) "y val")
;; Let's check how these fns perform:
(tufte/profile ; Profile any `p` forms called during body execution
{:level :info} ; Rich set of filtering options available
(dotimes [_ 5]
(tufte/p :get-x (get-x))
(tufte/p :get-y (get-y))))
;; The following will be printed to *out*:
;; 2025-04-18T11:23:08.820786Z INFO MyHost readme-examples[15,1] Tufte pstats
;; pId nCalls Min 50% ≤ 90% ≤ 95% ≤ 99% ≤ Max Mean MAD Clock Total
;;
;; :get-y 5 238ms 501ms 981ms 981ms 981ms 981ms 618ms ±42% 3.09s 55%
;; :get-x 5 501ms 502ms 505ms 505ms 505ms 505ms 503ms ±0% 2.51s 45%
;;
;; Accounted 5.60s 100%
;; Clock 5.60s 100%
```
## Documentation
- [Wiki][GitHub wiki] (getting started, usage, etc.)
- API reference via [cljdoc][cljdoc]
- Support via [Slack channel][] or [GitHub issues][]
## Funding
You can [help support][sponsor] continued work on this project, thank you!! 🙏
## License
Copyright © 2016-2025 [Peter Taoussanis][].
Licensed under [EPL 1.0](LICENSE.txt) (same as Clojure).
[GitHub releases]: ../../releases
[GitHub issues]: ../../issues
[GitHub wiki]: ../../wiki
[Slack channel]: https://www.taoensso.com/tufte/slack
[Peter Taoussanis]: https://www.taoensso.com
[sponsor]: https://www.taoensso.com/sponsor
[cljdoc]: https://cljdoc.org/d/com.taoensso/tufte/CURRENT/api/taoensso.tufte
[Clojars SVG]: https://img.shields.io/clojars/v/com.taoensso/tufte.svg
[Clojars URL]: https://clojars.org/com.taoensso/tufte
[Clj tests SVG]: https://github.com/taoensso/tufte/actions/workflows/clj-tests.yml/badge.svg
[Clj tests URL]: https://github.com/taoensso/tufte/actions/workflows/clj-tests.yml
[Cljs tests SVG]: https://github.com/taoensso/tufte/actions/workflows/cljs-tests.yml/badge.svg
[Cljs tests URL]: https://github.com/taoensso/tufte/actions/workflows/cljs-tests.yml
[Graal tests SVG]: https://github.com/taoensso/tufte/actions/workflows/graal-tests.yml/badge.svg
[Graal tests URL]: https://github.com/taoensso/tufte/actions/workflows/graal-tests.yml