telemere
Structured logging and telemetry for Clojure/Script with tracing and performance monitoring
What this skill does
# Telemere
Structured logging and telemetry library for Clojure and ClojureScript. Next-generation successor to Timbre with unified API for logging, tracing, and performance monitoring.
## Overview
Telemere provides a unified approach to application observability, handling traditional logging, structured telemetry, distributed tracing, and performance monitoring through a single consistent API.
**Key Features:**
- Structured data throughout pipeline (no string parsing)
- Compile-time signal elision (zero runtime cost for disabled signals)
- Runtime filtering (namespace, level, ID, rate limiting, sampling)
- Async and sync handler dispatch
- OpenTelemetry, SLF4J, and tools.logging interoperability
- Zero-configuration defaults
- ClojureScript support
**Artifact:** `com.taoensso/telemere`
**Latest Version:** 1.1.0
**License:** EPL-1.0
**Repository:** https://github.com/taoensso/telemere
## Installation
Add to `deps.edn`:
```clojure
{:deps {com.taoensso/telemere {:mvn/version "1.1.0"}}}
```
Or Leiningen `project.clj`:
```clojure
[com.taoensso/telemere "1.1.0"]
```
Import in namespace:
```clojure
(ns my-app
(:require [taoensso.telemere :as t]))
```
## Core Concepts
### Signals
Signals are structured telemetry events represented as Clojure maps with standardized attributes. They preserve data types throughout the logging pipeline rather than converting to strings.
Signal attributes include: namespace, level, ID, timestamp, thread info, line number, form data, return values, custom data maps.
### Default Configuration
Out-of-the-box settings:
- Minimum level: `:info`
- Handler: Console output to `*out*` or browser console
- Automatic interop with SLF4J, tools.logging when present
### Filtering Philosophy
Two-stage filtering:
1. **Call-time** (compile + runtime): Determines if signal is created
2. **Handler-time** (runtime): Determines which handlers process signal
Effective filtering reduces noise and improves performance.
## API Reference
### Signal Creation
#### log!
Traditional and structured logging.
```clojure
;; Basic logging with level
(t/log! :info "Processing started")
(t/log! :warn "High memory usage")
(t/log! :error "Database connection failed")
;; With message arguments
(t/log! :info ["User logged in:" {:user-id 123}])
;; Structured data
(t/log! {:level :info
:data {:user-id 123 :action "login"}})
;; With ID for filtering
(t/log! {:id :user-action
:level :info
:data {:user-id 123}})
```
**Levels (priority order):**
`:trace` < `:debug` < `:info` < `:warn` < `:error` < `:fatal` < `:report`
**Options:**
- `:level` - Signal level (keyword)
- `:id` - Signal ID for filtering (keyword)
- `:data` - Structured data map
- `:msg` - Message string or vector
- `:error` - Exception/error object
- `:ctx` - Context map
- `:sample-rate` - Signal sampling (0.0-1.0)
- `:rate-limit` - Rate limiting spec
- `:run` - Form to evaluate and include result
#### event!
ID and level-based event logging.
```clojure
;; Simple event
(t/event! :user-signup)
(t/event! :payment-processed)
;; With level
(t/event! :cache-miss :warn)
;; With data
(t/event! :user-signup
{:data {:user-id 123 :email "[email protected]"}})
;; With level and data
(t/event! :slow-query :warn
{:data {:duration-ms 1200 :query "SELECT ..."}})
```
Events are filtered by ID, making them ideal for metrics and tracking specific occurrences.
#### trace!
Tracks form execution with nested flow tracking.
```clojure
;; Basic tracing
(t/trace! :fetch-user
(fetch-user-from-db user-id))
;; Returns form result while logging execution
(def user
(t/trace! :fetch-user
(fetch-user-from-db 123)))
;; With data
(t/trace! {:id :process-order
:data {:order-id 456}}
(process-order 456))
;; Nested tracing shows parent-child relationships
(t/trace! :outer
(do
(t/trace! :inner-1 (step-1))
(t/trace! :inner-2 (step-2))))
```
Trace signals include execution time and return value. Nested traces maintain parent-child relationships.
#### spy!
Execution tracing with return value capture.
```clojure
;; Spy on expression
(t/spy! :debug
(+ 1 2 3))
;;=> 6 (also logs the expression and result)
;; Spy in pipeline
(->> data
(map inc)
(t/spy! :debug) ; See intermediate value
(filter even?))
;; With custom ID
(t/spy! {:id :computation :level :trace}
(* 42 (expensive-calc)))
```
Spy always returns the form result, making it useful in pipelines.
#### error!
Error logging with exception handling.
```clojure
;; Log error
(t/error! (ex-info "Failed" {:reason :timeout}))
;; With ID
(t/error! :db-error
(ex-info "Connection lost" {:host "db.example.com"}))
;; With additional data
(t/error! {:id :api-error
:data {:endpoint "/users" :status 500}}
(ex-info "API failed" {}))
```
Returns the error object.
#### catch->error!
Catch and log exceptions.
```clojure
;; Basic error catching
(t/catch->error!
(risky-operation))
;; With ID
(t/catch->error! :db-operation
(db-query))
;; With data
(t/catch->error! {:id :api-call
:data {:endpoint "/users"}}
(http-request "/users"))
;; Returns nil on error, result on success
(if-let [result (t/catch->error! (fetch-data))]
(process result)
(handle-error))
```
Catches exceptions, logs them, and returns nil. Returns form result if no exception.
#### signal!
Low-level signal creation with full control.
```clojure
;; Full signal specification
(t/signal!
{:kind :log
:level :info
:id :custom-event
:ns (str *ns*)
:data {:key "value"}
:msg "Custom message"
:run (do-something)})
```
Most use cases are better served by higher-level functions.
### Configuration
#### set-min-level!
Set global or namespace-specific minimum level.
```clojure
;; Global minimum level
(t/set-min-level! :warn)
;; Namespace-specific
(t/set-min-level! 'my.app.core :debug)
(t/set-min-level! 'my.app.* :info)
;; Per-namespace map
(t/set-min-level!
[['my.app.* :info]
['my.app.db :debug]
['noisy.library.* :error]])
```
Signals below minimum level are filtered at call-time.
#### set-ns-filter!
Configure namespace filtering.
```clojure
;; Allow only specific namespaces
(t/set-ns-filter! {:allow #{"my.app.*"}})
;; Disallow specific namespaces
(t/set-ns-filter! {:disallow #{"noisy.library.*"}})
;; Combined
(t/set-ns-filter!
{:allow #{"my.app.*"}
:disallow #{"my.app.test.*"}})
```
Namespace patterns support wildcards (`*`).
#### with-min-level
Temporarily override minimum level.
```clojure
;; Enable debug logging for block
(t/with-min-level :debug
(t/log! :debug "Debug info") ; Logged
(process-data))
;; Nested overrides
(t/with-min-level :warn
(t/with-min-level :trace ; Inner level applies
(t/log! :trace "Trace info")))
```
Scope is thread-local and dynamic.
#### with-signal
Capture last signal for testing.
```clojure
;; Capture signal map
(def sig
(t/with-signal
(t/log! {:level :info :data {:x 1}})))
(:level sig) ;;=> :info
(:data sig) ;;=> {:x 1}
;; Test signal creation
(let [sig (t/with-signal
(t/event! :test-event {:data {:y 2}}))]
(assert (= :test-event (:id sig)))
(assert (= {:y 2} (:data sig))))
```
Returns signal map instead of nil.
#### with-signals
Capture all signals from form.
```clojure
;; Capture multiple signals
(def sigs
(t/with-signals
(t/log! :info "First")
(t/log! :warn "Second")
(t/event! :third)))
(count sigs) ;;=> 3
(map :level sigs) ;;=> (:info :warn :info)
```
Returns vector of signal maps.
### Handlers
Handlers process signals and route them to destinations (console, files, databases, analytics).
#### add-handler!
Register signal handler.
```clojure
;; Console handler (built-in)
(t/add-handler! :my-console
(t/handler:console))
;; Custom handler function
(t/add-handler! :custom
(fn [signal]
(println "Custom:" (:msg signal))))
;; With filtering
(t/add-handler! :error-only
(t/handler:console)
{:min-level :error})
;; With async dRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.