← Home

Open source update

A big thanks to Clojurists Together, Nubank, and other sponsors of my open source work! I realise that it’s a tough time for a lot of folks and businesses lately, and that sponsorships aren’t always easy 🙏

- Peter Taoussanis

2024 Jul - Aug

Recent work

Hi folks! 👋 I hope those of you in summer are enjoying the nice weather ☀️

Have some chonky updates for today!

Timbre

Timbre is a pure Clojure/Script logging library.

Timbre v6.6.0-RC1 is out now. There’s some internal improvements, but the highlight is added out-the-box support for Java logging interop via SLF4J.

This is handled via a new SLF4J provider/backend dependency available on Clojars - instructions here.

The implementation is back-ported from Telemere and includes support for legacy and modern (“fluent”) SLF4J logging APIs, MDC (context key/vals), markers, etc.

This was one of the upvoted items on my open source roadmap, and definitely something nice to have officially supported.

Previously many Timbre users used the separate slf4j-timbre library for such interop - and I’d like to say a warm thanks to that library’s original author Farid Zakaria and steward / maintainer rufoa.

Their job was a challenging one - needing to keep up with internal changes to Timbre over time, etc. With the new approach, Timbre’s SLF4J support will now always be automatically kept in sync and tested with Timbre’s latest release, which should help minimize future maintenance headaches.

Telemere

Telemere is a modern rewrite of Timbre that offers an improved API to cover traditional logging, structured logging, tracing, basic performance measurement, and more.

My big focus recently has been Telemere, with 8 new beta releases since June.

The latest as of this post is v1.0.0-beta22 (2024-08-28).

The basic API has been stable, including re: signal creation and signal content - but I’ve been continuing to polish things in preparation for RC1 (expected next month).

Recent improvements include:

Significantly improved OpenTelemetry interop

This was another upvoted item from my open source roadmap, and quite a bit of work to get just right.

Telemere can now send signals as OpenTelemetry LogRecords with correlated tracing data to configured OpenTelemetry Java exporters.

This allows output to go (via configured exporters) to a wide variety of targets like JaegerZipkinAWS X-RayAWS CloudWatch, etc.

See here for instructions.

A couple nice properties of the way Telemere handles OpenTelemetry interop:

  1. Aside from configuring OpenTelemetry Java itself, Telemere’s OpenTelemetry interop doesn’t require any use of or familiarity with the OpenTelemetry Java API or concepts. So if you’re like me, you’ll be pleased to know that you can basically avoid all the usual OpenTelemetry API nonsense. You just use Telemere as you normally would, and it’ll act as your Clojure interface to OTel.

  2. Creating OpenTelemetry tracing spans and attaching attributes can be expensive, which violates a unique design goal of Telemere - to make it possible to dynamically filter costs as you filter signals. Telemere works around this by creating only minimal spans at first (to enable full interop with auto-instrumentation and other OTel tools), and saving all the expensive work for the post-filter signal handlers. Basically this gives you best of both worlds: full auto interop, but also lazy costs well-suited to Telemere’s rich filtering architecture.

For feedback and/or experience reports, please feel free to ping me on the Slack channel or GitHub.

Significant doc improvements

A major focus for Telemere has been the docs and examples.

My hope is to build something friendly enough for complete beginners.

If you haven’t looked at them yet (or recently), it might be worth checking out the README, Wiki, or API docs.

Some good starting points:

  1. Introduction (concepts, terminology)
  2. Creating signals (how to log stuff)
  3. Signal content (what gets logged)
  4. Filtering signals (decide what does/not get logged)
  5. Video demo (concepts, usage - 24 mins)
Facade API for library authors

Telemere now offers guidance for library authors/maintainers that might like to use Telemere in their own library, and offers a new super lightweight Facade API.

For a library using the facade:

  • If end users already have Telemere, then they’ll get Telemere signals out of the library. (And full filtering capabilities, etc.).
  • If end users don’t have Telemere, then the library can instead log using something like tools.logging.
General comments / status

Telemere may seem a bit of an odd animal at first since it looks like a logging library that’s hesitating to call itself a logging library. As it took shape, I struggled with how to describe it.

What I’d say today: Telemere’s basically meant to be a one-stop API for all the most common observability needs. These include traditional (string-oriented) logging, structured logging (arb nested Clojure data), events, tracing, and basic performance monitoring.

What I realised thinking about this problem space over the years - is that all of the above share fundamental ideas and needs:

  • We want to capture info in our systems at some point
  • We want to do it conditionally
  • We want to do something useful with that info

I suspected that a single API would do - but I wasn’t sure until I tried. When I did try, what I ended up with was actually a single macro (signal!) that handles all of the above through a handful of options.

I’m honestly very happy with the result - I find it elegant, easy to use and to understand, and deeply flexible. And I’m proud of the particular combination of ease-of-use and power - since these goals are often in conflict.

I’ll note that Telemere’s approach is possible only in a Lisp. And certain aspects of its implementation (esp. re: interop) are possible only in Clojure. So the value proposition here is unique.

At the risk of being overly blunt: observability matters, and in my opinion Telemere offers a code-side observability story that’s competitive with anything else I’m aware of in any language.

Part of my motivation in pursuing this particular project has been to try to use Clojure’s unique strengths to offer a unique and compelling advantage to Clojure projects/businesses/teams. Clojure enables Telemere, Telemere helps enable inexpensive and effective observability, observability helps enable more robust and debuggable systems. And robust debuggable systems can help enable successful projects.

So the idea (hope) is to be both a practical tool, and a sort of reference example of one of the kinds of tangible, real-world advantages made possible by Clojure.

Upcoming work

As always please do help vote on what you’d like to see me working on!

Telemere

My aim is to release v1 RC1 in September, then v1 final before the end of 2024.

The big stuff is all done, what remains is to give folks the opportunity to kick tyres and report issues or request changes before locking down the API.

Please also vote on which signal handlers would be most useful.

After that, my hope will be for Telemere to basically be stable - and to redirect future efforts toward education and promotion. Telemere enables a lot of powerful but non-obvious stuff, which I’ll need to do more work to explain.

Tempel

Tempel is a new data security framework for Clojure.

I’d like to release v1 final before the end of 2024. Still have some last features to think through and design (multi-factor authentication, etc.).

Tufte

Tufte offers simple performance monitoring for Clojure/Script.

Once Telemere v1 RC1 is out, I’ll be ready to prepare Tufte v3 - which’ll include a move to the exact same signal architecture powering Telemere.

Tufte and Telemere will then share identical terminology, capabilities, and API for filtering, handlers, etc.

The two already work well together, but interop will be even smoother after v3. The aim is to offer Telemere and Tufte as partner (complementary) libraries to enable unique next-gen observability capabilities for Clojure and ClojureScript applications.