Skip to content

Commit

Permalink
[new] Improve uid control, switch to nano-style by default
Browse files Browse the repository at this point in the history
1. Added `*uid-fn*` to globally control uid style

2. Now distinguish between root and child uids
   Root uids generally need to be longer.

3. Added to utils: `nano-uid-fn` and `hex-uid-fn`
   These use new highly optimized implementations
   when on JVM Clojure, and are highly flexible.
  • Loading branch information
ptaoussanis committed Aug 19, 2024
1 parent 1cef195 commit 5ab2736
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 36 deletions.
4 changes: 2 additions & 2 deletions resources/signal-docstrings/signal-content.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Default signal keys:
`:inst` -------- Platform instant [1] when signal was created
`:level` ------- Signal level ∈ #{<int> :trace :debug :info :warn :error :fatal :report ...}
`:kind` -------- Signal ?kind ∈ #{nil :event :error :log :trace :spy :slf4j :tools-logging <app-val> ...}
`:id` ---------- ?id of signal (common to all signals created at callsite, contrast with `:uid`)
`:uid` --------- ?id of signal instance (unique to each signal created at callsite, contrast with `:id`)
`:id` ---------- ?id of signal (common to all signals created at callsite, contrast with `:uid`)
`:uid` --------- ?id of signal instance (unique to each signal created at callsite when tracing, contrast with `:id`)

`:msg` --------- Arb app-level message ?str given to signal creator
`:data` -------- Arb app-level data ?val (usu. a map) given to signal creator
Expand Down
29 changes: 29 additions & 0 deletions src/taoensso/telemere.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,35 @@
(impl/defhelp help:signal-content :signal-content)
(impl/defhelp help:environmental-config :environmental-config))

;;;;

(def ^:dynamic *uid-fn*
"Experimental, subject to change.
(fn [root?]) used to generate signal `:uid` values when tracing.
These are basically unique signal instance identifiers.
`root?` argument is true iff signal is a top-level trace (i.e. form
being traced is unnested = has no parent form).
Root uids typically have ~128 bits of entropy to ensure uniqueness.
Child uids are typically used only with respect to a parent/root,
and so can often make do with ~64 bits of entropy or less.
Smaller uids are generally cheaper to generate, and use less space
when serializing/transmitting/storing/etc.
By default generates nano-style uids like
\"r76-B8LoIPs5lBG1_Uhdy\" (root) and \"tMEYoZH0K-\" (non-root).
For plain fixed-length UUIDs use: (fn [_root?] (utils/uuid))
For plain fixed-length UUID strings use: (fn [_root?] (utils/uuid-str))
See also `utils/nano-uid-fn`, `utils/hex-id-fn`, etc."

(utils/nano-uid-fn {:secure? false}))

(comment (enc/qb 1e6 (enc/uuid) (*uid-fn* true) (*uid-fn* false))) ; [168.83 79.02 62.95]

;;;; Signal creators
;; - event! [id ] [id opts/level] ; id + ?level => allowed? ; Sole signal with descending main arg!
;; - log! [msg ] [opts/level msg] ; msg + ?level => allowed?
Expand Down
40 changes: 10 additions & 30 deletions src/taoensso/telemere/impl.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
#?(:clj
(enc/declare-remote ; For macro expansions
^:dynamic taoensso.telemere/*ctx*
^:dynamic taoensso.telemere/*middleware*))
^:dynamic taoensso.telemere/*middleware*
^:dynamic taoensso.telemere/*uid-fn*))

;;;; Utils

Expand Down Expand Up @@ -62,27 +63,6 @@

(comment (enc/get-env {:as :edn, :return :explain} :taoensso.telemere/rt-filters<.platform><.edn>))

;;;; Unique IDs (UIDs)

(enc/def* nanoid-readable (enc/rand-id-fn {:chars :nanoid-readable, :len 23}))

#?(:clj
(defn- parse-uid-form [uid-form]
(when uid-form
(case uid-form
:auto/uuid `(enc/uuid)
:auto/uuid-str `(enc/uuid-str)
:auto/nanoid `(enc/nanoid)
:auto/nanoid-readable `(nanoid-readable)
uid-form))))

(comment
(enc/qb 1e6 ; [161.36 184.69 274.53 468.67]
(enc/uuid)
(enc/uuid-str)
(enc/nanoid)
(nanoid-readable)))

;;;; Messages

(deftype MsgSkip [])
Expand Down Expand Up @@ -519,15 +499,14 @@
{:msg "Expected constant (compile-time) `:trace?` boolean"
:context `signal!}))

parent-form (get opts :parent (when trace? `taoensso.telemere.impl/*trace-parent*))
root-form (get opts :root (when trace? `(or taoensso.telemere.impl/*trace-root*
{:id ~'__id, :uid ~'__uid, :inst ~'__inst})))
parent-form (get opts :parent (when trace? `taoensso.telemere.impl/*trace-parent*))
root-form (get opts :root (when trace? `taoensso.telemere.impl/*trace-root*))

inst-form (get opts :inst :auto)
inst-form (if (= inst-form :auto) `(enc/now-inst*) inst-form)
inst-form (get opts :inst :auto)
uid-form (get opts :uid (when trace? :auto))

uid-form (get opts :uid (when trace? :auto/uuid))
uid-form (parse-uid-form uid-form)
inst-form (if (not= inst-form :auto) inst-form `(enc/now-inst*))
uid-form (if (not= uid-form :auto) uid-form `(taoensso.telemere/*uid-fn* (if ~'__root0 false true)))

thread-form (if clj? `(enc/thread-info) nil)

Expand Down Expand Up @@ -621,13 +600,14 @@
~run-form
(let [;;; Allow to throw at call
~'__inst ~inst-form
~'__root0 ~root-form
~'__level ~level-form
~'__kind ~kind-form
~'__id ~id-form
~'__uid ~uid-form
~'__ns ~ns-form
~'__thread ~thread-form
~'__root ~root-form
~'__root (or ~'__root0 (when ~trace? {:id ~'__id, :uid ~'__uid, :inst ~'__inst}))

~'__run-result ; Non-throwing (traps)
~(when run-form
Expand Down
87 changes: 83 additions & 4 deletions src/taoensso/telemere/utils.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,91 @@
(format-id (str *ns*) ::id1)
(format-id nil ::id1))

;;;; Public misc
;;;; Unique IDs (UIDs)

(defn nano-uid-fn
"Experimental, subject to change.
Returns a (fn nano-uid [root?]) that returns a random nano-style uid string like:
\"r76-B8LoIPs5lBG1_Uhdy\" - 126 bit (21 char) root uid
\"tMEYoZH0K-\" - 60 bit (10 char) non-root (child) uid"
{:tag #?(:clj 'String :cljs 'string)}
([] (nano-uid-fn nil))
([{:keys [secure? root-len child-len]
:or
{root-len 21
child-len 10}}]

(let [root-len (long root-len)
child-len (long child-len)]

#?(:cljs (fn nano-uid [root?] (if root? (enc/nanoid secure? root-len) (enc/nanoid secure? child-len)))
:clj
(if secure?
(fn nano-uid-secure [root?]
(let [srng (.get com.taoensso.encore.Ids/SRNG_STRONG)]
(if root?
(com.taoensso.encore.Ids/genNanoId srng root-len)
(com.taoensso.encore.Ids/genNanoId srng child-len))))

(fn nano-uid-insecure [root?]
(if root?
(com.taoensso.encore.Ids/genNanoId root-len)
(com.taoensso.encore.Ids/genNanoId child-len))))))))

(comment ((nano-uid-fn) true))

(defn hex-uid-fn
"Experimental, subject to change.
Returns a (fn hex-uid [root?]) that returns a random hex-style uid string like:
\"05039666eb9dc3206475f44ab9f3d843\" - 128 bit (32 char) root uid
\"721fcef639a51513\" - 64 bit (16 char) non-root (child) uid"
{:tag #?(:clj 'String :cljs 'string)}
([] (hex-uid-fn nil))
([{:keys [secure? root-len child-len]
:or
{root-len 32
child-len 16}}]

(let [root-len (long root-len)
child-len (long child-len)]

#?(:cljs
(let [rand-bytes-fn
(if secure?
(partial enc/rand-bytes true)
(partial enc/rand-bytes false))

hex-uid-root (enc/rand-id-fn {:chars :hex-lowercase, :len root-len, :rand-bytes-fn rand-bytes-fn})
hex-uid-child (enc/rand-id-fn {:chars :hex-lowercase, :len child-len, :rand-bytes-fn rand-bytes-fn})]

(fn hex-uid [root?] (if root? (hex-uid-root) (hex-uid-child))))

:clj
(if secure?
(fn hex-uid-secure [root?]
(let [srng (.get com.taoensso.encore.Ids/SRNG_STRONG)]
(if root?
(com.taoensso.encore.Ids/genHexId srng root-len)
(com.taoensso.encore.Ids/genHexId srng child-len))))

(fn hex-uid-insecure [root?]
(if root?
(com.taoensso.encore.Ids/genHexId root-len)
(com.taoensso.encore.Ids/genHexId child-len))))))))

(comment ((hex-uid-fn) true))
(comment
;; [170.47 180.18 53.87 60.68]
(let [nano-uid-fn (nano-uid-fn), hex-uid-fn (hex-uid-fn)]
(enc/qb 1e6 (enc/uuid) (enc/uuid-str) (nano-uid true) (hex-uid true))))

;;;; Misc

(enc/defaliases
enc/newline enc/pr-edn #?(:cljs enc/pr-json)
#?@(:clj [enc/thread-info enc/thread-id enc/thread-name
enc/host-info enc/host-ip enc/hostname]))
enc/newline enc/pr-edn #?(:clj enc/uuid) enc/uuid-str
#?@(:cljs [enc/pr-json])
#?@(:clj [enc/thread-info enc/thread-id enc/thread-name
enc/host-info enc/host-ip enc/hostname]))

#?(:cljs
(defn js-console-logger
Expand Down

0 comments on commit 5ab2736

Please sign in to comment.