Liking cljdoc? Tell your friends :D


Clojars changelog License Slack channel

clj-otel provides a small idiomatic Clojure API for adding telemetry to your libraries and applications using OpenTelemetry, an emerging standard for telemetry in cloud-native software, enabling effective observability.

Distributed trace displayed in Honeycomb
Figure 1. A distributed trace displayed in Honeycomb
Microservice dependencies displayed in ServiceNow Cloud Observability
Figure 2. Exploring microservice dependencies with ServiceNow Cloud Observability


clj-otel is tested with Clojure 1.11.1 and is based on the reference OpenTelemetry for Java implementation, which supports Java 8 and higher.


clj-otel is highly configurable and may be used in many ways. This quickstart briefly outlines getting started in a local environment. Find more in-depth information on clj-otel in the documentation and examples.

  • To add manual instrumentation to your library or application at design time

    • Add project dependency

      {;; ...
       :deps {com.github.steffan-westcott/clj-otel-api {:mvn/version "0.2.6"}}}
    • To add traces telemetry, use Clojure functions such as steffan-westcott.clj-otel.api.trace.span/with-span! to create spans with attributes

      (defn validate-profile [profile]
        (span/with-span! ["Validating profile" {:system/profile-id (:id profile)}]
          (validate profile)))
    • To add metrics telemetry, use Clojure functions in steffan-westcott.clj-otel.api.metrics.instrument to create instruments, then add or record measurements with attributes

      (defonce set-password-failure-count
        (instrument/instrument {:name "app.set-password-failure-count"
                                :instrument-type :counter}))
      (instrument/add! set-password-failure-count {:value 1
                                                   :attributes {:reason :too-short}})
  • To export telemetry data (from both manual and automatic instrumentation) from an application at runtime

    • Download the latest OpenTelemetry instrumentation JAR opentelemetry-javaagent.jar from the OpenTelemetry instrumentation agent releases page.

    • Add the following JVM options to your application, assuming export of traces telemetry only to an OTLP compliant backend such as Jaeger

  • To receive exported telemetry data

    • Prepare a telemetry backend such as Jaeger

      docker run --rm                     \
                 -p 16686:16686           \
                 -p 4318:4318             \
                 jaegertracing/all-in-one \
  • To explore application behaviour described by the received telemetry data

For demonstration configurations that export traces and metrics telemetry, see the examples.


  • Tutorial : A walk-through of instrumenting a small Clojure program and viewing its telemetry.

  • Guides : Common task recipes for adding telemetry to your Clojure libraries and applications, then configuring and running applications with telemetry.

  • API & Reference : API documentation for all clj-otel modules.

  • Concepts : A primer on observability, OpenTelemetry and what this project clj-otel enables for Clojure libraries and applications.


Find complete example applications in the examples directory. The examples aim to show:

  • Adding automatic and manual instrumentation to applications

  • Configuring and running applications that export telemetry data

  • Viewing telemetry data in backends

Project status

  • clj-otel is a young, alpha grade project with limited use in a production setting. Breaking API changes may still be made, but there should be few, if any.

  • For manual instrumentation:

    • Coverage of the Traces API is complete.

      • Trace semantics conventions support for recording exceptions is complete.

      • Trace semantics support for HTTP spans in applications run without the OpenTelemetry instrumentation agent is limited.

      • Support for wrapping asynchronous Clojure code in spans is complete. The API is minimal and low-level, supporting any async library that works with callbacks. Perhaps with community feedback, this will be expanded to add more specialised support for popular async libraries. Code for creating spans around core.async channels can be found in the examples, specifically the <with-span-binding macro.

    • Coverage of the Metrics API is complete.

      • Metrics HTTP semantics support for applications run without the OpenTelemetry instrumentation agent is very limited.

    • There is currently no coverage of the Logs API.

  • For the programmatic configuration of the OpenTelemetry SDK:

    • Coverage of Traces TracerProvider is complete.

    • Coverage of Metrics MeterProvider is in progress. Most configuration options are supported, but some public details of the OpenTelemetry Java SDK are not yet stable.

    • There is currently no coverage of Logging LoggerProvider.


Contributing & contact

The most needed contribution is experience reports of clj-otel use in production systems. I am keen to hear of usages of clj-otel and any problems and successes. clj-otel is a very young project, so now is an ideal time to provide feedback on the API design as improvements can be made freely.

I will be happy to consider pull requests for minor changes, but I may not accept more significant changes while I make a start on some items in the TODO list.

For questions or feedback on clj-otel, contact me on the #clj-otel channel in Clojurians Slack, user steffan.



To develop clj-otel, you should first install the following tools:


  • Get information on available build scripts with this command:

    clojure -A:deps -T:build help/doc
  • Before making any pull requests, please ensure the source code has been linted and formatted with these commands:

    clojure -T:build lint
    clojure -T:build fmt


I want to thank:

  • You (yes, you) for having the curiosity to look into this project. Thank you.

  • My friends Golnaz and Nimmo, for pointing me in the direction of observability and OpenTelemetry. Without them, I wouldn’t have had the idea to do this project.

  • The OpenTelemetry community and all makers of telemetry backends for making the effective observability of systems a tangible reality. Cloud-native software is so complex now, we need all the help we can get to understand how well it is (or is not) working.

  • The Diátaxis Documentation Framework, for a simple way to structure technical documentation.


Copyright © 2021-2024 Steffan Westcott
Distributed under the Apache License v2.0

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close