Tracing functions when the arguments are big maps

2019-05-13 22:26发布

问题:

When I trace a function, if one of the arguments is a nested map with a lot of elements, the trace is filled with clutter. Here's a typical example:

TRACE t36705: (get-value {:nodeclass :simple, :nodeid :simple25, :dock {:constan
t-dock {:name :constant-dock, :value 22, :dockclass {:name :constant-dock, :link
-policy {:lp-committed? #object[fargish.links$fn__5756 0x407956a5 "fargish.links
$fn__5756@407956a5"], :lp-reciprocate-no-commitment #object[clojure.core$constan
tly$fn__4614 0x69497a36 "clojure.core$constantly$fn__4614@69497a36"], :lp-recipr
ocate-commitment #object[clojure.core$constantly$fn__4614 0x30ee413a "clojure.co
re$constantly$fn__4614@30ee413a"], :lp-can-boost-to #object[fargish.links$fn__57
58 0x5df17e60 "fargish.links$fn__5758@5df17e60"], :lp-official-partners #object[
fargish.links$fn__5760 0x3df2f4ab "fargish.links$fn__5760@3df2f4ab"], :lp-normal
ize-after-add #object[clojure.core$constantly$fn__4614 0x386cc1c4 "clojure.core$
constantly$fn__4614@386cc1c4"], :lp-reduce-to-uncommitted #object[fargish.links$
fn__5765 0x7bd4f212 "fargish.links$fn__5765@7bd4f212"], :lp-committed-to #object
[fargish.links$fn__5767 0x5c3cc103 "fargish.links$fn__5767@5c3cc103"], :lp-boost
 #object[fargish.links$fn__5771 0x423e35f0 "fargish.links$fn__5771@423e35f0"]}, 
:maker #object[fargish.spec_test$eval36501$__GT_Dock_constant_dock__36515 0x19cc
229b "fargish.spec_test$eval36501$__GT_Dock_constant_dock__36515@19cc229b"]}}, :
function-dock {:name :function-dock, :value #fargish.spec.Vfunc{:args (constant-
dock), :f #object[fargish.spec_test$fn__36544 0x135647d3 "fargish.spec_test$fn__
36544@135647d3"]}, :dockclass {:name :function-dock, :link-policy {:lp-committed
? #object[fargish.links$fn__5756 0x407956a5 "fargish.links$fn__5756@407956a5"], 
:lp-reciprocate-no-commitment #object[clojure.core$constantly$fn__4614 0x69497a3
6 "clojure.core$constantly$fn__4614@69497a36"], :lp-reciprocate-commitment #obje
ct[clojure.core$constantly$fn__4614 0x30ee413a "clojure.core$constantly$fn__4614
@30ee413a"], :lp-can-boost-to #object[fargish.links$fn__5758 0x5df17e60 "fargish
.links$fn__5758@5df17e60"], :lp-official-partners #object[fargish.links$fn__5760
 0x3df2f4ab "fargish.links$fn__5760@3df2f4ab"], :lp-normalize-after-add #object[
clojure.core$constantly$fn__4614 0x386cc1c4 "clojure.core$constantly$fn__4614@38
6cc1c4"], :lp-reduce-to-uncommitted #object[fargish.links$fn__5765 0x7bd4f212 "f
argish.links$fn__5765@7bd4f212"], :lp-committed-to #object[fargish.links$fn__576
7 0x5c3cc103 "fargish.links$fn__5767@5c3cc103"], :lp-boost #object[fargish.links
$fn__5771 0x423e35f0 "fargish.links$fn__5771@423e35f0"]}, :maker #object[fargish
.spec_test$eval36523$__GT_Dock_function_dock__36537 0x34584446 "fargish.spec_tes
t$eval36523$__GT_Dock_function_dock__36537@34584446"]}}}} constant-dock)
TRACE t36705: => nil

What's a technique for setting things up so these traces print out without so much clutter? I don't expect traces to be super-easy to read, but there has to be a better way than this.

回答1:

Unfortunately, clojure.tools.trace doesn't allow customizing the output of trace logs. I wasn't sure if you could modify your source code between runs or you needed a mechanism to plugin into a running system where you cannot modify function implementation.

From your comment it seems you can modify a function you want to trace. Based on your requirement to log only a subset of function's arguments content I would switch to ordinary logging (either with println or with some logging framework) and add explicit logging expressions to log only relevant data.

For example:

(defn some-function
  [a b]
  (println "some-function" {:a (select-keys a [:x :y]) :b (select-keys b [:x :z])})
  (comment your function body))

It's not that easy as changing defn to deftrace but can be customized any way you want.