Skip to main content

telemere

Structured logging and telemetry for Clojure/Script with tracing and performance monitoring

Informações da origem

Repositório
hugoduncan/library-skills
Última atividade na origem
15 de novembro de 2025 às 03:05
Idioma detectado do SKILL.md
inglês
Estrelas
3
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
3 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
telemere
description
Structured logging and telemetry for Clojure/Script with tracing and performance monitoring
# 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 "user@example.com"}}) ;; 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 dispatch (t/add-handler! :async-log (fn [signal] (log-to-db signal)) {:async {:buffer-size 1024 :n-threads 2}}) ;; With sampling (t/add-handler! :sampled (t/handler:console) {:sample-rate 0.1}) ; 10% of signals ``` **Handler Options:** - `:min-level` - Minimum signal level - `:ns-filter` - Namespace filter - `:id-filter` - ID filter - `:sample-rate` - Sampling rate (0.0-1.0) - `:rate-limit` - Rate limiting spec - `:async` - Async dispatch config - `:middleware` - Transform functions #### remove-handler! Remove handler by ID. ```clojure (t/remove-handler! :my-console) (t/remove-handler! :custom) ``` #### handler:console Built-in console handler with formatting. ```clojure ;; Default text format (t/handler:console) ;; JSON format (t/handler:console {:format :json}) ;; EDN format (t/handler:console {:format :edn}) ;; Custom format function (t/handler:console {:format (fn [signal] (pr-str (:data signal)))}) ``` #### handler:stream Output to Java OutputStream or Writer. ```clojure ;; File output (t/add-handler! :file (t/handler:stream (io/output-stream "app.log") {:format :json})) ;; With rotation (requires additional setup) (t/add-handler! :rotating-file (rotating-file-handler "logs/app.log")) ``` ### Filtering Utilities #### check-min-level Check if level passes minimum threshold. ```clojure (t/check-min-level :info) ;;=> true/false
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub