Skip to content

Commit

Permalink
[mod] [#356] Call pr-str on non-string arguments
Browse files Browse the repository at this point in the history
Change (both Clj and Cljs):

  For print-style logging commands (`debug`, `info`, etc.):

    By default, `pr-str` (rather than `str`) is now called on all non-string
    arguments when generating `:msg_` and `:output_` vals in Timbre's log data
    map.

    I.e. will affect generated output.

  For format-style logging commands (`debugf`, `infof`, etc.):

    No change since format-style logging commands presume that a format
    pattern will explicitly specify the desired formatting, so arguments
    are not automatically formatted.

    I.e. should not affect generated output.

Motivation:

  My hope is that this change should be positive or neutral for the vast
  majority of users. There are several known cases where `pr-str` produces
  better output (e.g. for JS objects in Cljs), and currently no known
  cases where `pr-str` produces worse output (though please ping me if you
  know of something!).

To customise this behaviour (message generation), see the `default-output-fn`
docstring.
  • Loading branch information
ptaoussanis committed Oct 23, 2022
1 parent 8d1b3a6 commit 597c7a0
Showing 1 changed file with 41 additions and 27 deletions.
68 changes: 41 additions & 27 deletions src/taoensso/timbre.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -565,21 +565,6 @@

;;;; Utils

(defn- str-join [xs]
(enc/str-join " "
(map
(fn [x]
(let [x (enc/nil->str x)] ; Undefined, nil -> "nil"
(cond
(record? x) (pr-str x)
;; (enc/lazy-seq? x) (pr-str x) ; Dubious?
:else x))))
xs))

(comment
(defrecord MyRec [x])
(str-join ["foo" (MyRec. "foo")]))

#?(:clj
(enc/defonce ^:private get-agent
(enc/fmemoize (fn [appender-id] (agent nil :error-mode :continue)))))
Expand Down Expand Up @@ -1101,21 +1086,50 @@
(str enc/system-newline
(ef data)))))))))

(defn- default-arg->str-fn [x]
(enc/cond
(nil? x) "nil"
(string? x) x
:else
#?(:clj (with-out-str (pr x))
:cljs (pr-str x))))

(defn- legacy-arg->str-fn [x]
(enc/cond
(nil? x) "nil"
(record? x) (pr-str x)
:else x))

(defn- str-join
([ xs] (str-join default-arg->str-fn xs))
([arg->str-fn xs] (enc/str-join " " (map arg->str-fn) xs)))

(comment
(defrecord MyRec [x])
(str-join ["foo" (MyRec. "foo")]))

(defn default-output-msg-fn
"(fn [data]) -> string, used by `default-output-fn` to generate output
for `:vargs` value (vector of raw logging arguments) in log data."
[{:keys [msg-type ?msg-fmt vargs] :as data}]
(case msg-type
nil ""
:p (str-join vargs)
:f
(if (string? ?msg-fmt)
(enc/format* ?msg-fmt vargs)
(throw
(ex-info "Timbre format-style logging call without a format pattern string"
{:?msg-fmt ?msg-fmt :type (type ?msg-fmt) :vargs vargs})))))

(comment (default-output-msg-fn {:msg-type :p :vargs ["a" "b"]}))
[{:keys [msg-type ?msg-fmt vargs output-opts] :as data}]
(let [{:keys [arg->str-fn] ; Undocumented
:or {arg->str-fn default-arg->str-fn}}
output-opts]

(case msg-type
nil ""
:p (str-join arg->str-fn vargs)
:f
(if (string? ?msg-fmt)
(enc/format* ?msg-fmt vargs) ; Don't use arg->str-fn, would prevent custom formatting
(throw
(ex-info "Timbre format-style logging call without a format pattern string"
{:?msg-fmt ?msg-fmt :type (type ?msg-fmt) :vargs vargs}))))))

(comment
(default-output-msg-fn
{:msg-type :p :vargs ["a" "b"]
:output-opts {:arg->str-fn (fn [_] "x")}}))

#?(:clj
(def ^:private default-stacktrace-fonts
Expand Down

0 comments on commit 597c7a0

Please sign in to comment.