mirror of
https://github.com/taoensso/telemere.git
synced 2026-02-05 11:53:12 +00:00
[mod] Fix AOT support, don't alias conditional vars
This commit is contained in:
parent
3fe58d35c1
commit
9ccb815dd9
12 changed files with 186 additions and 153 deletions
|
|
@ -29,10 +29,12 @@
|
||||||
[[org.clojure/clojure "1.11.2"]
|
[[org.clojure/clojure "1.11.2"]
|
||||||
[com.github.clj-easy/graal-build-time "1.0.5"]]}
|
[com.github.clj-easy/graal-build-time "1.0.5"]]}
|
||||||
|
|
||||||
|
:test {:aot [taoensso.telemere-tests]}
|
||||||
:dev
|
:dev
|
||||||
{:jvm-opts
|
{:jvm-opts
|
||||||
["-server"
|
["-server"
|
||||||
"-Dtaoensso.elide-deprecated=true"
|
"-Dtaoensso.elide-deprecated=true"
|
||||||
|
"-Dtaoensso.telemere.auto-handlers=false"
|
||||||
"-Dclojure.tools.logging-to-telemere?=true"]
|
"-Dclojure.tools.logging-to-telemere?=true"]
|
||||||
|
|
||||||
:global-vars
|
:global-vars
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
(ns ^:no-doc taoensso.telemere.slf4j
|
(ns taoensso.telemere.slf4j
|
||||||
"Private ns, implementation detail.
|
"Intake support for SLF4J -> Telemere.
|
||||||
Intake support: SLF4J -> Telemere.
|
Telemere will attempt to load this ns automatically when possible.
|
||||||
|
|
||||||
To use Telemere as your SLF4J backend/provider, just include the
|
To use Telemere as your SLF4J backend/provider, just include the
|
||||||
`com.taoensso/slf4j-telemere` dependency on your classpath.
|
`com.taoensso/slf4j-telemere` dependency on your classpath.
|
||||||
|
|
@ -18,7 +18,11 @@
|
||||||
|
|
||||||
(:require
|
(:require
|
||||||
[taoensso.encore :as enc :refer [have have?]]
|
[taoensso.encore :as enc :refer [have have?]]
|
||||||
[taoensso.telemere.impl :as impl]))
|
[taoensso.telemere.impl :as impl])
|
||||||
|
|
||||||
|
(:import
|
||||||
|
[org.slf4j Logger]
|
||||||
|
[com.taoensso.telemere.slf4j TelemereLogger]))
|
||||||
|
|
||||||
;;;; Utils
|
;;;; Utils
|
||||||
|
|
||||||
|
|
@ -40,10 +44,10 @@
|
||||||
|
|
||||||
(comment (enc/qb 1e6 (sig-level org.slf4j.event.Level/INFO))) ; 36.47
|
(comment (enc/qb 1e6 (sig-level org.slf4j.event.Level/INFO))) ; 36.47
|
||||||
|
|
||||||
(defn get-marker "Private util for tests, etc."
|
(defn- get-marker "Private util for tests, etc."
|
||||||
^org.slf4j.Marker [n] (org.slf4j.MarkerFactory/getMarker n))
|
^org.slf4j.Marker [n] (org.slf4j.MarkerFactory/getMarker n))
|
||||||
|
|
||||||
(defn est-marker!
|
(defn- est-marker!
|
||||||
"Private util for tests, etc.
|
"Private util for tests, etc.
|
||||||
Globally establishes (compound) `org.slf4j.Marker` with name `n` and mutates it
|
Globally establishes (compound) `org.slf4j.Marker` with name `n` and mutates it
|
||||||
(all occurences!) to have exactly the given references. Returns the (compound) marker."
|
(all occurences!) to have exactly the given references. Returns the (compound) marker."
|
||||||
|
|
@ -55,7 +59,7 @@
|
||||||
|
|
||||||
(comment [(est-marker! "a1" "a2") (get-marker "a1") (= (get-marker "a1") (get-marker "a1"))])
|
(comment [(est-marker! "a1" "a2") (get-marker "a1") (= (get-marker "a1") (get-marker "a1"))])
|
||||||
|
|
||||||
(def marker-names
|
(def ^:private marker-names
|
||||||
"Returns #{<MarkerName>}. Cached => assumes markers NOT modified after creation."
|
"Returns #{<MarkerName>}. Cached => assumes markers NOT modified after creation."
|
||||||
;; We use `BasicMarkerFactory` so:
|
;; We use `BasicMarkerFactory` so:
|
||||||
;; 1. Our markers are just labels (no other content besides their name).
|
;; 1. Our markers are just labels (no other content besides their name).
|
||||||
|
|
@ -95,7 +99,7 @@
|
||||||
|
|
||||||
;;;; Intake fns (called by `TelemereLogger`)
|
;;;; Intake fns (called by `TelemereLogger`)
|
||||||
|
|
||||||
(defn allowed?
|
(defn- allowed?
|
||||||
"Private, don't use.
|
"Private, don't use.
|
||||||
Called by `com.taoensso.telemere.slf4j.TelemereLogger`."
|
Called by `com.taoensso.telemere.slf4j.TelemereLogger`."
|
||||||
[^org.slf4j.event.Level level]
|
[^org.slf4j.event.Level level]
|
||||||
|
|
@ -134,7 +138,7 @@
|
||||||
:slf4j/kvs kvs)})
|
:slf4j/kvs kvs)})
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defn log!
|
(defn- log!
|
||||||
"Private, don't use.
|
"Private, don't use.
|
||||||
Called by `com.taoensso.telemere.slf4j.TelemereLogger`."
|
Called by `com.taoensso.telemere.slf4j.TelemereLogger`."
|
||||||
|
|
||||||
|
|
@ -172,15 +176,27 @@
|
||||||
(org.slf4j.MDC/getCopyOfContextMap)
|
(org.slf4j.MDC/getCopyOfContextMap)
|
||||||
(org.slf4j.MDC/clear)))
|
(org.slf4j.MDC/clear)))
|
||||||
|
|
||||||
(impl/add-intake-check! :slf4j
|
;;;;
|
||||||
(fn []
|
|
||||||
(let [^org.slf4j.Logger sl
|
|
||||||
(org.slf4j.LoggerFactory/getLogger "IntakeTestTelemereLogger")
|
|
||||||
sending? (instance? com.taoensso.telemere.slf4j.TelemereLogger sl)
|
|
||||||
receiving?
|
|
||||||
(and sending?
|
|
||||||
(impl/test-intake! "SLF4J -> Telemere" #(.info sl %)))]
|
|
||||||
|
|
||||||
{:present? true
|
(defn check-intake
|
||||||
:sending->telemere? sending?
|
"Returns {:keys [present? sending->telemere? telemere-receiving?]}."
|
||||||
:telemere-receiving? receiving?})))
|
[]
|
||||||
|
(let [^org.slf4j.Logger sl
|
||||||
|
(org.slf4j.LoggerFactory/getLogger "IntakeTestTelemereLogger")
|
||||||
|
sending? (instance? com.taoensso.telemere.slf4j.TelemereLogger sl)
|
||||||
|
receiving?
|
||||||
|
(and sending?
|
||||||
|
(impl/test-intake! "SLF4J -> Telemere" #(.info sl %)))]
|
||||||
|
|
||||||
|
{:present? true
|
||||||
|
:sending->telemere? sending?
|
||||||
|
:telemere-receiving? receiving?}))
|
||||||
|
|
||||||
|
(impl/add-intake-check! :slf4j check-intake)
|
||||||
|
|
||||||
|
(impl/on-init
|
||||||
|
(impl/signal!
|
||||||
|
{:kind :event
|
||||||
|
:level :info
|
||||||
|
:id :taoensso.telemere/slf4j->telemere!
|
||||||
|
:msg "Enabling intake: SLF4J -> Telemere"}))
|
||||||
|
|
|
||||||
|
|
@ -372,25 +372,6 @@
|
||||||
streams/streams->telemere!
|
streams/streams->telemere!
|
||||||
streams/streams->reset!))
|
streams/streams->reset!))
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(enc/compile-when
|
|
||||||
(do (require '[taoensso.telemere.tools-logging :as ttl]) true)
|
|
||||||
(enc/defalias ttl/tools-logging->telemere!) ; Incl. `get-env` docs
|
|
||||||
(when (enc/get-env {:as :bool} :clojure.tools.logging-to-telemere?)
|
|
||||||
(ttl/tools-logging->telemere!))))
|
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(enc/compile-when
|
|
||||||
(and org.slf4j.Logger com.taoensso.telemere.slf4j.TelemereLogger)
|
|
||||||
|
|
||||||
(impl/signal!
|
|
||||||
{:kind :event
|
|
||||||
:level :info
|
|
||||||
:id :taoensso.telemere/slf4j->telemere!
|
|
||||||
:msg "Enabling intake: SLF4J -> Telemere"})
|
|
||||||
|
|
||||||
(require '[taoensso.telemere.slf4j :as slf4j])))
|
|
||||||
|
|
||||||
(comment (check-intakes))
|
(comment (check-intakes))
|
||||||
|
|
||||||
;;;; Handlers
|
;;;; Handlers
|
||||||
|
|
@ -400,20 +381,6 @@
|
||||||
#?(:cljs handlers:console/handler:console-raw)
|
#?(:cljs handlers:console/handler:console-raw)
|
||||||
#?(:clj handlers:file/handler:file))
|
#?(:clj handlers:file/handler:file))
|
||||||
|
|
||||||
#?(:clj
|
|
||||||
(enc/compile-when
|
|
||||||
(do (require '[taoensso.telemere.handlers.open-telemetry :as handlers:open-tel]) true)
|
|
||||||
(enc/defalias handlers:open-tel/handler:open-telemetry-logger)))
|
|
||||||
|
|
||||||
(defonce ^:no-doc __add-default-handlers
|
|
||||||
(do
|
|
||||||
(add-handler! :default/console (handler:console))
|
|
||||||
#?(:clj
|
|
||||||
(enc/compile-when handler:open-telemetry-logger
|
|
||||||
(when-let [handler (enc/catching (handler:open-telemetry-logger))]
|
|
||||||
(add-handler! :default/open-telemetry-logger handler))))
|
|
||||||
nil))
|
|
||||||
|
|
||||||
;;;; Flow benchmarks
|
;;;; Flow benchmarks
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
|
|
@ -447,6 +414,16 @@
|
||||||
|
|
||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
|
(impl/on-init
|
||||||
|
(when impl/auto-handlers?
|
||||||
|
(add-handler! :default/console (handler:console)))
|
||||||
|
|
||||||
|
#?(:clj (enc/catching (require '[taoensso.telemere.tools-logging])))
|
||||||
|
#?(:clj (enc/catching (require '[taoensso.telemere.slf4j])))
|
||||||
|
#?(:clj (enc/catching (require '[taoensso.telemere.handlers.open-telemetry]))))
|
||||||
|
|
||||||
|
;;;;
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(with-handler :hid1 (handlers/console-handler) {} (log! "Message"))
|
(with-handler :hid1 (handlers/console-handler) {} (log! "Message"))
|
||||||
|
|
||||||
|
|
@ -461,5 +438,3 @@
|
||||||
(do (let [hf (handlers/file-handler)] (hf sig) (hf)))
|
(do (let [hf (handlers/file-handler)] (hf sig) (hf)))
|
||||||
(do (let [hf (handlers/console-handler)] (hf sig) (hf)))
|
(do (let [hf (handlers/console-handler)] (hf sig) (hf)))
|
||||||
#?(:cljs (let [hf (handlers/raw-console-handler)] (hf sig) (hf)))))
|
#?(:cljs (let [hf (handlers/raw-console-handler)] (hf sig) (hf)))))
|
||||||
|
|
||||||
;;;;
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
(ns ^:no-doc taoensso.telemere.handlers.open-telemetry
|
(ns taoensso.telemere.handlers.open-telemetry
|
||||||
"Private ns, implementation detail.
|
"Core OpenTelemetry handler and utils.
|
||||||
Core OpenTelemetry handlers.
|
Telemere will attempt to load this ns automatically when possible.
|
||||||
|
|
||||||
Needs `OpenTelemetry Java`,
|
Needs `OpenTelemetry Java`,
|
||||||
Ref. <https://github.com/open-telemetry/opentelemetry-java>."
|
Ref. <https://github.com/open-telemetry/opentelemetry-java>."
|
||||||
|
|
@ -8,7 +8,9 @@
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[taoensso.encore :as enc :refer [have have?]]
|
[taoensso.encore :as enc :refer [have have?]]
|
||||||
[taoensso.telemere.utils :as utils])
|
[taoensso.telemere.utils :as utils]
|
||||||
|
[taoensso.telemere.impl :as impl]
|
||||||
|
[taoensso.telemere :as tel])
|
||||||
|
|
||||||
(:import
|
(:import
|
||||||
[io.opentelemetry.api.logs LoggerProvider Severity]
|
[io.opentelemetry.api.logs LoggerProvider Severity]
|
||||||
|
|
@ -21,7 +23,7 @@
|
||||||
|
|
||||||
;;;; Implementation
|
;;;; Implementation
|
||||||
|
|
||||||
(defn level->severity
|
(defn- level->severity
|
||||||
^Severity [level]
|
^Severity [level]
|
||||||
(case level
|
(case level
|
||||||
:trace Severity/TRACE
|
:trace Severity/TRACE
|
||||||
|
|
@ -33,7 +35,7 @@
|
||||||
:report Severity/INFO4
|
:report Severity/INFO4
|
||||||
Severity/UNDEFINED_SEVERITY_NUMBER))
|
Severity/UNDEFINED_SEVERITY_NUMBER))
|
||||||
|
|
||||||
(def ^String attr-name
|
(def ^:private ^String attr-name
|
||||||
"Returns cached OpenTelemetry-style name: `:foo/bar-baz` -> \"foo_bar_baz\", etc.
|
"Returns cached OpenTelemetry-style name: `:foo/bar-baz` -> \"foo_bar_baz\", etc.
|
||||||
Ref. <https://opentelemetry.io/docs/specs/semconv/general/attribute-naming/>."
|
Ref. <https://opentelemetry.io/docs/specs/semconv/general/attribute-naming/>."
|
||||||
(enc/fmemoize
|
(enc/fmemoize
|
||||||
|
|
@ -49,7 +51,7 @@
|
||||||
(comment (enc/qb 1e6 (attr-name :x1.x2/x3-x4 :Foo/Bar-BAZ))) ; 63.6
|
(comment (enc/qb 1e6 (attr-name :x1.x2/x3-x4 :Foo/Bar-BAZ))) ; 63.6
|
||||||
|
|
||||||
;; AttributeTypes: String, Long, Double, Boolean, and arrays
|
;; AttributeTypes: String, Long, Double, Boolean, and arrays
|
||||||
(defprotocol IAttr+ (attr+ [_aval akey builder]))
|
(defprotocol IAttr+ (^:private attr+ [_aval akey builder]))
|
||||||
(extend-protocol IAttr+
|
(extend-protocol IAttr+
|
||||||
nil (attr+ [v k ^AttributesBuilder b] (.put b (attr-name k) "nil")) ; Like pr-edn*
|
nil (attr+ [v k ^AttributesBuilder b] (.put b (attr-name k) "nil")) ; Like pr-edn*
|
||||||
Boolean (attr+ [v k ^AttributesBuilder b] (.put b (attr-name k) v))
|
Boolean (attr+ [v k ^AttributesBuilder b] (.put b (attr-name k) v))
|
||||||
|
|
@ -78,7 +80,7 @@
|
||||||
|
|
||||||
Object (attr+ [v k ^AttributesBuilder b] (.put b (attr-name k) (enc/pr-edn* v))))
|
Object (attr+ [v k ^AttributesBuilder b] (.put b (attr-name k) (enc/pr-edn* v))))
|
||||||
|
|
||||||
(defn as-attrs
|
(defn- as-attrs
|
||||||
"Returns `io.opentelemetry.api.common.Attributes` for given map."
|
"Returns `io.opentelemetry.api.common.Attributes` for given map."
|
||||||
^Attributes [m]
|
^Attributes [m]
|
||||||
(if (empty? m)
|
(if (empty? m)
|
||||||
|
|
@ -89,7 +91,7 @@
|
||||||
|
|
||||||
(comment (str (as-attrs {:s "s", :kw :foo/bar, :long 5, :double 5.0, :longs [5 5 5] :nil nil})))
|
(comment (str (as-attrs {:s "s", :kw :foo/bar, :long 5, :double 5.0, :longs [5 5 5] :nil nil})))
|
||||||
|
|
||||||
(defn merge-prefix-map
|
(defn- merge-prefix-map
|
||||||
"Merges prefixed `from` into `to`."
|
"Merges prefixed `from` into `to`."
|
||||||
[to prefix from]
|
[to prefix from]
|
||||||
(enc/cond
|
(enc/cond
|
||||||
|
|
@ -103,7 +105,7 @@
|
||||||
|
|
||||||
(comment (merge-prefix-map {} "data" {:a/b1 "v1" :a/b2 "v2" :nil nil}))
|
(comment (merge-prefix-map {} "data" {:a/b1 "v1" :a/b2 "v2" :nil nil}))
|
||||||
|
|
||||||
(defn signal->attrs-map
|
(defn- signal->attrs-map
|
||||||
"Returns attributes map for given signal,
|
"Returns attributes map for given signal,
|
||||||
Ref. <https://opentelemetry.io/docs/specs/otel/logs/data-model/>."
|
Ref. <https://opentelemetry.io/docs/specs/otel/logs/data-model/>."
|
||||||
[attrs-key signal]
|
[attrs-key signal]
|
||||||
|
|
@ -181,7 +183,7 @@
|
||||||
|
|
||||||
;;;; Handler
|
;;;; Handler
|
||||||
|
|
||||||
(defn ^:public handler:open-telemetry-logger
|
(defn handler:open-telemetry-logger
|
||||||
"Experimental, subject to change!! Feedback very welcome!
|
"Experimental, subject to change!! Feedback very welcome!
|
||||||
|
|
||||||
Returns a (fn handler [signal]) that:
|
Returns a (fn handler [signal]) that:
|
||||||
|
|
@ -216,3 +218,10 @@
|
||||||
(.setSeverity severity)
|
(.setSeverity severity)
|
||||||
(.setBody msg)
|
(.setBody msg)
|
||||||
(.setAllAttributes attrs)))))))))
|
(.setAllAttributes attrs)))))))))
|
||||||
|
|
||||||
|
;;;;
|
||||||
|
|
||||||
|
(impl/on-init
|
||||||
|
(when impl/auto-handlers?
|
||||||
|
(when-let [handler (enc/catching (handler:open-telemetry-logger))]
|
||||||
|
(tel/add-handler! :default/open-telemetry-logger handler))))
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,18 @@
|
||||||
|
|
||||||
;;;; Utils
|
;;;; Utils
|
||||||
|
|
||||||
|
(def auto-handlers? (enc/get-env {:as :bool, :default true} :taoensso.telemere/auto-handlers))
|
||||||
|
|
||||||
#?(:clj (defmacro threaded [& body] `(let [t# (Thread. (fn [] ~@body))] (.start t#) t#)))
|
#?(:clj (defmacro threaded [& body] `(let [t# (Thread. (fn [] ~@body))] (.start t#) t#)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defmacro on-init [& body]
|
||||||
|
(let [sym (with-meta '__on-init {:private true})
|
||||||
|
compiling? (if (:ns &env) false `*compile-files*)]
|
||||||
|
`(defonce ~sym (when-not ~compiling? ~@body nil)))))
|
||||||
|
|
||||||
|
(comment (macroexpand-1 '(on-init (println "foo"))))
|
||||||
|
|
||||||
;;;; Config
|
;;;; Config
|
||||||
|
|
||||||
#?(:clj
|
#?(:clj
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,26 @@
|
||||||
(ns ^:no-doc taoensso.telemere.streams
|
(ns taoensso.telemere.streams
|
||||||
"Private ns, implementation detail.
|
"Intake support for standard stream/s -> Telemere."
|
||||||
Intake support: standard stream/s -> Telemere."
|
|
||||||
(:refer-clojure :exclude [binding])
|
(:refer-clojure :exclude [binding])
|
||||||
(:require
|
(:require
|
||||||
[taoensso.encore :as enc :refer [binding have have?]]
|
[taoensso.encore :as enc :refer [binding have have?]]
|
||||||
[taoensso.telemere.impl :as impl]))
|
[taoensso.telemere.impl :as impl]))
|
||||||
|
|
||||||
(enc/defonce orig-*out* "Original `*out*` on ns load" *out*)
|
(enc/defonce ^:private orig-*out* "Original `*out*` on ns load" *out*)
|
||||||
(enc/defonce orig-*err* "Original `*err*` on ns load" *err*)
|
(enc/defonce ^:private orig-*err* "Original `*err*` on ns load" *err*)
|
||||||
(enc/defonce ^:dynamic prev-*out* "Previous `*out*` (prior to any Telemere binds)" nil)
|
(enc/defonce ^:no-doc ^:dynamic prev-*out* "Previous `*out*` (prior to any Telemere binds)" nil)
|
||||||
(enc/defonce ^:dynamic prev-*err* "Previous `*err*` (prior to any Telemere binds)" nil)
|
(enc/defonce ^:no-doc ^:dynamic prev-*err* "Previous `*err*` (prior to any Telemere binds)" nil)
|
||||||
|
|
||||||
(def ^:private ^:const default-out-opts {:kind :system/out, :level :info})
|
(def ^:private ^:const default-out-opts {:kind :system/out, :level :info})
|
||||||
(def ^:private ^:const default-err-opts {:kind :system/err, :level :error})
|
(def ^:private ^:const default-err-opts {:kind :system/err, :level :error})
|
||||||
|
|
||||||
(defn osw ^java.io.OutputStreamWriter [x] (java.io.OutputStreamWriter. x))
|
(defn ^:no-doc osw
|
||||||
|
"Private, don't use."
|
||||||
|
^java.io.OutputStreamWriter [x]
|
||||||
|
(java.io.OutputStreamWriter. x))
|
||||||
|
|
||||||
(defn telemere-print-stream
|
(defn ^:no-doc telemere-print-stream
|
||||||
"Returns a `java.io.PrintStream` that will flush to Telemere signals with given opts."
|
"Private, don't use.
|
||||||
|
Returns a `java.io.PrintStream` that will flush to Telemere signals with given opts."
|
||||||
^java.io.PrintStream [{:as sig-opts :keys [kind level id]}]
|
^java.io.PrintStream [{:as sig-opts :keys [kind level id]}]
|
||||||
(let [baos
|
(let [baos
|
||||||
(proxy [java.io.ByteArrayOutputStream] []
|
(proxy [java.io.ByteArrayOutputStream] []
|
||||||
|
|
@ -42,6 +45,8 @@
|
||||||
(java.io.PrintStream. baos true ; Auto flush
|
(java.io.PrintStream. baos true ; Auto flush
|
||||||
java.nio.charset.StandardCharsets/UTF_8)))
|
java.nio.charset.StandardCharsets/UTF_8)))
|
||||||
|
|
||||||
|
;;;;
|
||||||
|
|
||||||
(defmacro ^:public with-out->telemere
|
(defmacro ^:public with-out->telemere
|
||||||
"Executes form with `*out*` bound to flush to Telemere signals with given opts."
|
"Executes form with `*out*` bound to flush to Telemere signals with given opts."
|
||||||
([ form] `(with-out->telemere nil ~form))
|
([ form] `(with-out->telemere nil ~form))
|
||||||
|
|
@ -143,14 +148,21 @@
|
||||||
(streams->telemere! {})
|
(streams->telemere! {})
|
||||||
(streams->reset!))
|
(streams->reset!))
|
||||||
|
|
||||||
(impl/add-intake-check! :system/out
|
;;;;
|
||||||
(fn []
|
|
||||||
(let [sending? (boolean @orig-out_)
|
|
||||||
receiving? (and sending? (impl/test-intake! "`System/out` -> Telemere" #(.println System/out %)))]
|
|
||||||
{:sending->telemere? sending?, :telemere-receiving? receiving?})))
|
|
||||||
|
|
||||||
(impl/add-intake-check! :system/err
|
(defn check-out-intake
|
||||||
(fn []
|
"Returns {:keys [sending->telemere? telemere-receiving?]}."
|
||||||
(let [sending? (boolean @orig-err_)
|
[]
|
||||||
receiving? (and sending? (impl/test-intake! "`System/err` -> Telemere" #(.println System/err %)))]
|
(let [sending? (boolean @orig-out_)
|
||||||
{:sending->telemere? sending?, :telemere-receiving? receiving?})))
|
receiving? (and sending? (impl/test-intake! "`System/out` -> Telemere" #(.println System/out %)))]
|
||||||
|
{:sending->telemere? sending?, :telemere-receiving? receiving?}))
|
||||||
|
|
||||||
|
(defn check-err-intake
|
||||||
|
"Returns {:keys [sending->telemere? telemere-receiving?]}."
|
||||||
|
[]
|
||||||
|
(let [sending? (boolean @orig-err_)
|
||||||
|
receiving? (and sending? (impl/test-intake! "`System/err` -> Telemere" #(.println System/err %)))]
|
||||||
|
{:sending->telemere? sending?, :telemere-receiving? receiving?}))
|
||||||
|
|
||||||
|
(impl/add-intake-check! :system/out check-out-intake)
|
||||||
|
(impl/add-intake-check! :system/err check-err-intake)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
(ns ^:no-doc taoensso.telemere.tools-logging
|
(ns taoensso.telemere.tools-logging
|
||||||
"Private ns, implementation detail.
|
"Intake support for `clojure.tools.logging` -> Telemere.
|
||||||
Intake support: `clojure.tools.logging` -> Telemere."
|
Telemere will attempt to load this ns automatically when possible."
|
||||||
(:require
|
(:require
|
||||||
[taoensso.encore :as enc :refer [have have?]]
|
[taoensso.encore :as enc :refer [have have?]]
|
||||||
[taoensso.telemere.impl :as impl]
|
[taoensso.telemere.impl :as impl]
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
(name [_ ] "taoensso.telemere")
|
(name [_ ] "taoensso.telemere")
|
||||||
(get-logger [_ logger-ns] (TelemereLogger. (str logger-ns))))
|
(get-logger [_ logger-ns] (TelemereLogger. (str logger-ns))))
|
||||||
|
|
||||||
(defn ^:public tools-logging->telemere!
|
(defn tools-logging->telemere!
|
||||||
"Configures `clojure.tools.logging` to use Telemere as its logging implementation.
|
"Configures `clojure.tools.logging` to use Telemere as its logging implementation.
|
||||||
|
|
||||||
Called automatically if the following is true:
|
Called automatically if the following is true:
|
||||||
|
|
@ -53,19 +53,30 @@
|
||||||
(alter-var-root #'clojure.tools.logging/*logger-factory*
|
(alter-var-root #'clojure.tools.logging/*logger-factory*
|
||||||
(fn [_] (TelemereLoggerFactory.))))
|
(fn [_] (TelemereLoggerFactory.))))
|
||||||
|
|
||||||
(defn tools-logging-factory [] (TelemereLoggerFactory.))
|
(defn tools-logging->telemere?
|
||||||
(defn tools-logging->telemere? []
|
"Returns true iff `clojure.tools.logging` is configured to use Telemere
|
||||||
|
as its logging implementation."
|
||||||
|
[]
|
||||||
(when-let [lf clojure.tools.logging/*logger-factory*]
|
(when-let [lf clojure.tools.logging/*logger-factory*]
|
||||||
(instance? TelemereLoggerFactory lf)))
|
(instance? TelemereLoggerFactory lf)))
|
||||||
|
|
||||||
(impl/add-intake-check! :tools-logging
|
;;;;
|
||||||
(fn []
|
|
||||||
(let [sending? (tools-logging->telemere?)
|
|
||||||
receiving?
|
|
||||||
(and sending?
|
|
||||||
(impl/test-intake! "`clojure.tools.logging` -> Telemere"
|
|
||||||
#(clojure.tools.logging/info %)))]
|
|
||||||
|
|
||||||
{:present? true
|
(defn check-intake
|
||||||
:sending->telemere? sending?
|
"Returns {:keys [present? sending->telemere? telemere-receiving?]}."
|
||||||
:telemere-receiving? receiving?})))
|
[]
|
||||||
|
(let [sending? (tools-logging->telemere?)
|
||||||
|
receiving?
|
||||||
|
(and sending?
|
||||||
|
(impl/test-intake! "`clojure.tools.logging` -> Telemere"
|
||||||
|
#(clojure.tools.logging/info %)))]
|
||||||
|
|
||||||
|
{:present? true
|
||||||
|
:sending->telemere? sending?
|
||||||
|
:telemere-receiving? receiving?}))
|
||||||
|
|
||||||
|
(impl/add-intake-check! :tools-logging check-intake)
|
||||||
|
|
||||||
|
(impl/on-init
|
||||||
|
(when (enc/get-env {:as :bool} :clojure.tools.logging-to-telemere?)
|
||||||
|
(tools-logging->telemere!)))
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@
|
||||||
:refer [signal! with-signal with-signals]
|
:refer [signal! with-signal with-signals]
|
||||||
:rename {signal! sig!, with-signal with-sig, with-signals with-sigs}]
|
:rename {signal! sig!, with-signal with-sig, with-signals with-sigs}]
|
||||||
|
|
||||||
[taoensso.telemere.utils :as utils]
|
[taoensso.telemere.utils :as utils]
|
||||||
[taoensso.telemere.timbre :as timbre]
|
[taoensso.telemere.timbre :as timbre]
|
||||||
#?(:clj [taoensso.telemere.slf4j :as slf4j])
|
#_[taoensso.telemere.tools-logging :as tools-logging]
|
||||||
#?(:clj [clojure.tools.logging :as ctl])
|
#_[taoensso.telemere.streams :as streams]
|
||||||
|
#?(:clj [taoensso.telemere.slf4j :as slf4j])
|
||||||
|
#?(:clj [clojure.tools.logging :as ctl])
|
||||||
|
|
||||||
#?(:default [taoensso.telemere.handlers.console :as handlers:console])
|
#?(:default [taoensso.telemere.handlers.console :as handlers:console])
|
||||||
#?(:clj [taoensso.telemere.handlers.file :as handlers:file])
|
#?(:clj [taoensso.telemere.handlers.file :as handlers:file])
|
||||||
|
|
@ -577,9 +579,9 @@
|
||||||
(is (sm? (with-sig (-> (.atInfo sl) (.addKeyValue "k1" "v1") (.addKeyValue "k2" "v2") (.log))) {:data {:slf4j/kvs {"k1" "v1", "k2" "v2"}}}) "Fluent API: kvs")
|
(is (sm? (with-sig (-> (.atInfo sl) (.addKeyValue "k1" "v1") (.addKeyValue "k2" "v2") (.log))) {:data {:slf4j/kvs {"k1" "v1", "k2" "v2"}}}) "Fluent API: kvs")
|
||||||
|
|
||||||
(testing "Markers"
|
(testing "Markers"
|
||||||
(let [m1 (slf4j/est-marker! "M1")
|
(let [m1 (#'slf4j/est-marker! "M1")
|
||||||
m2 (slf4j/est-marker! "M2")
|
m2 (#'slf4j/est-marker! "M2")
|
||||||
cm (slf4j/est-marker! "Compound" "M1" "M2")]
|
cm (#'slf4j/est-marker! "Compound" "M1" "M2")]
|
||||||
|
|
||||||
[(is (sm? (with-sig (.info sl cm "Hello")) {:data #:slf4j{:marker-names #{"Compound" "M1" "M2"}}}) "Legacy API: markers")
|
[(is (sm? (with-sig (.info sl cm "Hello")) {:data #:slf4j{:marker-names #{"Compound" "M1" "M2"}}}) "Legacy API: markers")
|
||||||
(is (sm? (with-sig (-> (.atInfo sl) (.addMarker m1) (.addMarker cm) (.log))) {:data #:slf4j{:marker-names #{"Compound" "M1" "M2"}}}) "Fluent API: markers")]))
|
(is (sm? (with-sig (-> (.atInfo sl) (.addMarker m1) (.addMarker cm) (.log))) {:data #:slf4j{:marker-names #{"Compound" "M1" "M2"}}}) "Fluent API: markers")]))
|
||||||
|
|
@ -813,26 +815,26 @@
|
||||||
#?(:clj
|
#?(:clj
|
||||||
(deftest _open-telemetry
|
(deftest _open-telemetry
|
||||||
[(testing "attr-name"
|
[(testing "attr-name"
|
||||||
[(is (= (handlers:otel/attr-name :foo) "foo"))
|
[(is (= (#'handlers:otel/attr-name :foo) "foo"))
|
||||||
(is (= (handlers:otel/attr-name :foo-bar-baz) "foo_bar_baz"))
|
(is (= (#'handlers:otel/attr-name :foo-bar-baz) "foo_bar_baz"))
|
||||||
(is (= (handlers:otel/attr-name :foo/bar-baz) "foo.bar_baz"))
|
(is (= (#'handlers:otel/attr-name :foo/bar-baz) "foo.bar_baz"))
|
||||||
(is (= (handlers:otel/attr-name :Foo/Bar-BAZ) "foo.bar_baz"))
|
(is (= (#'handlers:otel/attr-name :Foo/Bar-BAZ) "foo.bar_baz"))
|
||||||
(is (= (handlers:otel/attr-name "Foo Bar-Baz") "foo_bar_baz"))
|
(is (= (#'handlers:otel/attr-name "Foo Bar-Baz") "foo_bar_baz"))
|
||||||
(is (= (handlers:otel/attr-name :x1.x2/x3-x4 :foo/bar-baz)
|
(is (= (#'handlers:otel/attr-name :x1.x2/x3-x4 :foo/bar-baz)
|
||||||
"x1.x2.x3_x4.foo.bar_baz"))])
|
"x1.x2.x3_x4.foo.bar_baz"))])
|
||||||
|
|
||||||
(testing "merge-prefix-map"
|
(testing "merge-prefix-map"
|
||||||
[(is (= (handlers:otel/merge-prefix-map nil "pf" nil) nil))
|
[(is (= (#'handlers:otel/merge-prefix-map nil "pf" nil) nil))
|
||||||
(is (= (handlers:otel/merge-prefix-map nil "pf" {}) nil))
|
(is (= (#'handlers:otel/merge-prefix-map nil "pf" {}) nil))
|
||||||
(is (= (handlers:otel/merge-prefix-map {"a" "A"} "pf" {:a :A}) {"a" "A", "pf.a" :A}))
|
(is (= (#'handlers:otel/merge-prefix-map {"a" "A"} "pf" {:a :A}) {"a" "A", "pf.a" :A}))
|
||||||
(is (= (handlers:otel/merge-prefix-map {} "pf"
|
(is (= (#'handlers:otel/merge-prefix-map {} "pf"
|
||||||
{:a/b1 "v1" :a/b2 "v2" :nil nil, :map {:k1 "v1"}})
|
{:a/b1 "v1" :a/b2 "v2" :nil nil, :map {:k1 "v1"}})
|
||||||
|
|
||||||
{"pf.a.b1" "v1", "pf.a.b2" "v2", "pf.nil" nil, "pf.map" {:k1 "v1"}}))])
|
{"pf.a.b1" "v1", "pf.a.b2" "v2", "pf.nil" nil, "pf.map" {:k1 "v1"}}))])
|
||||||
|
|
||||||
(testing "as-attrs"
|
(testing "as-attrs"
|
||||||
(is (= (str
|
(is (= (str
|
||||||
(handlers:otel/as-attrs
|
(#'handlers:otel/as-attrs
|
||||||
{:string "s", :keyword :foo/bar, :long 5, :double 5.0, :nil nil,
|
{:string "s", :keyword :foo/bar, :long 5, :double 5.0, :nil nil,
|
||||||
:longs [5 5.0 5.0],
|
:longs [5 5.0 5.0],
|
||||||
:doubles [5.0 5 5],
|
:doubles [5.0 5 5],
|
||||||
|
|
@ -844,7 +846,7 @@
|
||||||
"{bools=[true, false, false], double=5.0, doubles=[5.0, 5.0, 5.0], keyword=\":foo/bar\", long=5, longs=[5, 5, 5], map=[[:k1 \"v1\"]], mixed=[5, \"5\", nil], nil=\"nil\", string=\"s\", strings=[\"a\", \"b\", \"c\"]}")))
|
"{bools=[true, false, false], double=5.0, doubles=[5.0, 5.0, 5.0], keyword=\":foo/bar\", long=5, longs=[5, 5, 5], map=[[:k1 \"v1\"]], mixed=[5, \"5\", nil], nil=\"nil\", string=\"s\", strings=[\"a\", \"b\", \"c\"]}")))
|
||||||
|
|
||||||
(testing "signal->attrs-map"
|
(testing "signal->attrs-map"
|
||||||
(let [attrs-map handlers:otel/signal->attrs-map]
|
(let [attrs-map #'handlers:otel/signal->attrs-map]
|
||||||
[(is (= (attrs-map nil { }) {"error" false}))
|
[(is (= (attrs-map nil { }) {"error" false}))
|
||||||
(is (= (attrs-map :attrs {:attrs {:a1 :A1}}) {"error" false, :a1 :A1}))
|
(is (= (attrs-map :attrs {:attrs {:a1 :A1}}) {"error" false, :a1 :A1}))
|
||||||
(is
|
(is
|
||||||
|
|
|
||||||
|
|
@ -95,21 +95,21 @@ See section [3-Config](./3-Config) for customization.
|
||||||
|
|
||||||
> Signal handlers process created signals to *do something with them* (analyse them, write them to console/file/queue/db, etc.)
|
> Signal handlers process created signals to *do something with them* (analyse them, write them to console/file/queue/db, etc.)
|
||||||
|
|
||||||
| Platform | Condition | Handler |
|
| Platform | Condition | Handler |
|
||||||
| -------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Clj | Always | [Console handler](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) that prints signals to `*out*` or `*err*`. |
|
| Clj | Always | [Console handler](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) that prints signals to `*out*` or `*err*`. |
|
||||||
| Cljs | Always | [Console handler](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) that prints signals to the **browser console**. |
|
| Cljs | Always | [Console handler](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) that prints signals to the **browser console**. |
|
||||||
| Clj | [OpenTelemetry API](https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-api) present | [OpenTelemetry handler](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:open-telemetry-logger) that emits signals as log records to a configured [`LoggerProvider`](https://opentelemetry.io/docs/specs/otel/logs/sdk/#loggerprovider). |
|
| Clj | [OpenTelemetry API](https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-api) present | [OpenTelemetry handler](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:open-telemetry-logger) that emits signals as log records to a configured [`LoggerProvider`](https://opentelemetry.io/docs/specs/otel/logs/sdk/#loggerprovider). |
|
||||||
|
|
||||||
**Default signal intakes**:
|
**Default signal intakes**:
|
||||||
|
|
||||||
> Telemere can create signals from relevant **external API calls**, etc.
|
> Telemere can create signals from relevant **external API calls**, etc.
|
||||||
|
|
||||||
| Platform | Condition | Signals from |
|
| Platform | Condition | Signals from |
|
||||||
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
|
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||||
| Clj | [SLF4J API](https://mvnrepository.com/artifact/org.slf4j/slf4j-api) and [Telemere SLF4J backend](https://clojars.org/com.taoensso/slf4j-telemere) present | [SLF4J](https://www.slf4j.org/) logging calls. |
|
| Clj | [SLF4J API](https://mvnrepository.com/artifact/org.slf4j/slf4j-api) and [Telemere SLF4J backend](https://clojars.org/com.taoensso/slf4j-telemere) present | [SLF4J](https://www.slf4j.org/) logging calls. |
|
||||||
| Clj | [clojure.tools.logging](https://mvnrepository.com/artifact/org.clojure/tools.logging) present and [`tools-logging->telemere!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#tools-logging-%3Etelemere!) called | [clojure.tools.logging](https://github.com/clojure/tools.logging) logging calls. |
|
| Clj | [clojure.tools.logging](https://mvnrepository.com/artifact/org.clojure/tools.logging) present and [`tools-logging->telemere!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.tools-logging#tools-logging-%3Etelemere!) called | [clojure.tools.logging](https://github.com/clojure/tools.logging) logging calls. |
|
||||||
| Clj | [`streams->telemere!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#streams-%3Etelemere!) called | Output to `System/out` and `System/err` streams. |
|
| Clj | [`streams->telemere!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#streams-%3Etelemere!) called | Output to `System/out` and `System/err` streams. |
|
||||||
|
|
||||||
Run [`check-intakes`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#check-intakes) to help verify/debug:
|
Run [`check-intakes`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#check-intakes) to help verify/debug:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@ This flow is described by [`help:signal-flow`](https://cljdoc.org/d/com.taoensso
|
||||||
|
|
||||||
For more info see:
|
For more info see:
|
||||||
|
|
||||||
| Var | Help with |
|
| Var | Help with |
|
||||||
| :-- | :-- |
|
| :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------- |
|
||||||
| [`help:signal-creators`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-creators) | List of signal creators
|
| [`help:signal-creators`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-creators) | List of signal creators |
|
||||||
| [`help:signal-options`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-options) | Options for signal creators
|
| [`help:signal-options`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-options) | Options for signal creators |
|
||||||
| [`help:signal-content`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-content) | Signal map content
|
| [`help:signal-content`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-content) | Signal map content |
|
||||||
| [`help:signal-flow`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-flow) | Ordered flow from signal creation to handling
|
| [`help:signal-flow`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-flow) | Ordered flow from signal creation to handling |
|
||||||
| [`help:signal-filters`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-filters) | API for configuring signal filters
|
| [`help:signal-filters`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-filters) | API for configuring signal filters |
|
||||||
| [`help:signal-handlers`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-handlers) | API for configuring signal handlers
|
| [`help:signal-handlers`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-handlers) | API for configuring signal handlers |
|
||||||
| [`help:signal-formatters`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-formatters) | Signal formatters for use by handlers
|
| [`help:signal-formatters`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#help:signal-formatters) | Signal formatters for use by handlers |
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,7 @@ See section [4-Handlers](./4-Handlers).
|
||||||
To do this:
|
To do this:
|
||||||
|
|
||||||
1. Ensure that you have the `clojure.tools.logging` dependency, and
|
1. Ensure that you have the `clojure.tools.logging` dependency, and
|
||||||
2. Call [`tools-logging->telemere!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#tools-logging-%3Etelemere!), or set the relevant system config as described in its docstring.
|
2. Call [`tools-logging->telemere!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.tools-logging#tools-logging-%3Etelemere!), or set the relevant system config as described in its docstring.
|
||||||
|
|
||||||
Note that the `tools-logging->telemere!` var will be present **only if** the `clojure.tools.logging` dependency is present.
|
|
||||||
|
|
||||||
Verify successful intake with [`check-intakes`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#check-intakes):
|
Verify successful intake with [`check-intakes`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#check-intakes):
|
||||||
|
|
||||||
|
|
@ -90,9 +88,7 @@ Telemere can send signals as [`LogRecords`](https://opentelemetry.io/docs/specs/
|
||||||
To do this:
|
To do this:
|
||||||
|
|
||||||
1. Ensure that you have the [OpenTelemetry Java](https://github.com/open-telemetry/opentelemetry-java) dependency.
|
1. Ensure that you have the [OpenTelemetry Java](https://github.com/open-telemetry/opentelemetry-java) dependency.
|
||||||
2. Use [`handler:open-telemetry-logger`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:open-telemetry-logger) to create an appropriately configured handler, and register it with [`add-handler!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#add-handler!).
|
2. Use [`handler:open-telemetry-logger`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.open-telemetry#handler:open-telemetry-logger) to create an appropriately configured handler, and register it with [`add-handler!`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#add-handler!).
|
||||||
|
|
||||||
Note that the `handler:open-telemetry-logger` var will be present **only if** the OpenTelemetry Java dependency is present.
|
|
||||||
|
|
||||||
## Tufte
|
## Tufte
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ Signal handlers process created signals to *do something with them* (analyse the
|
||||||
|
|
||||||
The following handlers are included out-the-box:
|
The following handlers are included out-the-box:
|
||||||
|
|
||||||
| Name | Platform | Writes signals to | Writes signals as |
|
| Name | Platform | Writes signals to | Writes signals as |
|
||||||
| :---------------------------------------------------------------------------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------- |
|
| :------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------- |
|
||||||
| [`handler:console`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) | Clj | `*out*` or `*err*` | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
| [`handler:console`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) | Clj | `*out*` or `*err*` | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
||||||
| [`handler:console`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) | Cljs | Browser console | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
| [`handler:console`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console) | Cljs | Browser console | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
||||||
| [`handler:console-raw`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console-raw) | Cljs | Browser console | Raw data (for [cljs-devtools](https://github.com/binaryage/cljs-devtools), etc.) |
|
| [`handler:console-raw`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:console-raw) | Cljs | Browser console | Raw data (for [cljs-devtools](https://github.com/binaryage/cljs-devtools), etc.) |
|
||||||
| [`handler:file`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:file) | Clj | File/s on disk | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
| [`handler:file`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:file) | Clj | File/s on disk | String ([edn](https://github.com/edn-format/edn), JSON, formatted, etc.) |
|
||||||
| [`handler:open-telemetry-logger`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere#handler:open-telemetry-logger) | Clj | [OpenTelemetry](https://opentelemetry.io/) [Java client](https://github.com/open-telemetry/opentelemetry-java) | [LogRecord](https://opentelemetry.io/docs/specs/otel/logs/data-model/) |
|
| [`handler:open-telemetry-logger`](https://cljdoc.org/d/com.taoensso/telemere/CURRENT/api/taoensso.telemere.open-telemetry#handler:open-telemetry-logger) | Clj | [OpenTelemetry](https://opentelemetry.io/) [Java client](https://github.com/open-telemetry/opentelemetry-java) | [LogRecord](https://opentelemetry.io/docs/specs/otel/logs/data-model/) |
|
||||||
|
|
||||||
- See relevant docstrings (links above) for more info.
|
- See relevant docstrings (links above) for more info.
|
||||||
- See section [8-Community](8-Community.md) for additional handlers.
|
- See section [8-Community](8-Community.md) for additional handlers.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue