I was trying to turn telemere signals into maps that were suitable for display with :portal.viewer/log and ran in to several problems:
- The
:result key is required, even the the predicate spec doesn't list it, if you do not pass it the viewer breaks.
- The
:time predicate is inst?, which java.time.Instant passes. But if you pass a java.time.Instant as :time, the viewer breaks.
By "breaks" I mean the viewer falls back to the inspector viewer, I never actually saw any error messages.
Here is a working config I landed on:
(require '[taoensso.telemere :as taoensso.telemere])
(defn telemere->tap
([{:keys [msg_ level inst] :as signal}]
(tap>
(with-meta
(->
;; remove a bunch of nil values
(into {} (remove #(nil? (val %))) signal)
;; add result which the portal viewer will use to display the log message
(assoc :result [level msg_])
;; viewer doesn't support java.time.Instant
(assoc :time (java.util.Date/from inst))
(dissoc :inst)
;; telemere provides ns as a string, but viewer wants a symbol
(update :ns symbol)
;; add in runtime to get a nice logo
(assoc :runtime ((requiring-resolve 'portal.console/runtime))))
{:portal.viewer/default :portal.viewer/log
:portal.viewer/for
{:form :portal.viewer/pprint
:time :portal.viewer/relative-time}})))
([]
(tap> [:signal "telemere handler has shut down"])))
(defn add-telemere-tap-handler! []
(taoensso.telemere/remove-handler! :tap-handler)
(taoensso.telemere/add-handler! :tap-handler telemere->tap
{:min-level :debug}))
(do
(add-telemere-tap-handler!)
(taoensso.telemere/log! {:level :error :data {:err "Exception"}} "Error oh noes!")
(taoensso.telemere/log! {:level :info :data {:interesting :fact}} "Did you know that..")
(taoensso.telemere/log! {:level :debug :data {:data [42]}} "datadatatatadatatatata"))
Screenshots


I was trying to turn telemere signals into maps that were suitable for display with
:portal.viewer/logand ran in to several problems::resultkey is required, even the the predicate spec doesn't list it, if you do not pass it the viewer breaks.:timepredicate isinst?, which java.time.Instant passes. But if you pass ajava.time.Instantas:time, the viewer breaks.By "breaks" I mean the viewer falls back to the inspector viewer, I never actually saw any error messages.
Here is a working config I landed on:
Screenshots