From a55bcc27f876f0ef924105d13801fbd7051a2cde Mon Sep 17 00:00:00 2001 From: Lukas Domagala Date: Sat, 20 Nov 2021 19:29:14 +0100 Subject: [PATCH] fixed flamegraph sorting and added exception tracing --- README.md | 12 ++++++++++-- dev/user.clj | 3 +++ dev/user.cljs | 7 +++++-- src/omni_trace/flamegraph.cljc | 3 ++- src/omni_trace/omni_trace.cljc | 21 +++++++++++++++++---- src/omni_trace/testing_ns.cljc | 1 + 6 files changed, 38 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 734e168..9a46b39 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # omni-trace Omnipotent/omniscient tracing core for debugging clojure(script) -very early alpha, api is still unstable +very early alpha, api is still unstable but its only for dev time so there shouldn't be any problems [![Clojars Project](https://img.shields.io/clojars/v/org.clojars.cyrik/omni-trace.svg)](https://clojars.org/org.clojars.cyrik/omni-trace) @@ -34,7 +34,8 @@ or just through github source: (e/insert-coin :dime) (e/insert-coin :nickel) (e/insert-coin :penny) - (e/press-button :a1)) + (e/press-button :a1) + (e/retrieve-change-returned)) ;look at traces for every function that was traced @o/workspace ;connect to portal @@ -48,6 +49,13 @@ or just through github source: ![Screenshot](docs/flamegraph.png) +## Features +- Works in clojure and clojurescript +- Instrument whole namespaces from the repl +- show the trace as a Flamegraph in Portal or anything else that understands Vega.js +- remembers the call that caused the exception and shows the arguments + + ## In the works - better trace output to the REPL - callbacks from Portal so you can rerun an updated function with the old params by clicking on it in the Flamegraph diff --git a/dev/user.clj b/dev/user.clj index fcf1315..3c368e4 100644 --- a/dev/user.clj +++ b/dev/user.clj @@ -31,6 +31,9 @@ o/instrumented-vars + (tap> ^{:portal.viewer/default :portal.viewer/hiccup} + [:div "custom thing here" [:portal.viewer/inspector {:complex :data-structure}]]) + (o/uninstrument-ns 'omni-trace.testing-ns) (macroexpand '(o/instrument-ns 'omni-trace.testing-ns)) diff --git a/dev/user.cljs b/dev/user.cljs index 687c925..57ce49e 100644 --- a/dev/user.cljs +++ b/dev/user.cljs @@ -14,7 +14,8 @@ (e/insert-coin :dime) (e/insert-coin :nickel) (e/insert-coin :penny) - (e/press-button :a1)) + (e/press-button :a1) + (e/retrieve-change-returned)) ;look at traces for every function that was traced @o/workspace ;connect to portal @@ -22,9 +23,11 @@ (add-tap #'p/submit) ;send the trace to portal as a vegajs flamegraph (tap> (flame/flamegraph (flame/flamedata @o/workspace))) + (tap> ^{:portal.viewer/default :portal.viewer/hiccup} [:button {:onclick (str "alert('123')")} (str "alert('123')")]) + [:button {:onclick "alert('123')"} "Test it!"] ;remove tracing from a namesapce (o/uninstrument-ns 'omni-trace.testing-ns) - + (o/reset-workspace!) o/instrumented-vars (macroexpand '(o/uninstrument-ns 'omni-trace.testing-ns)) (alter-meta! (var omni-trace.testing-ns/insert-coin) assoc-in [:stuffs] "yeah123") diff --git a/src/omni_trace/flamegraph.cljc b/src/omni_trace/flamegraph.cljc index a9253d2..350fbc5 100644 --- a/src/omni_trace/flamegraph.cljc +++ b/src/omni_trace/flamegraph.cljc @@ -23,6 +23,7 @@ {:signal "{n: datum.name, a:datum.args, + t:datum.thrown, r: datum.return}"}} :update {:x {:field "a0"} @@ -47,7 +48,7 @@ :parentKey "parent"} {:type "partition" ;:field "size" - :sort {:field "value"} + :sort {:field "id"} :padding 2 :size [{:signal "width"} diff --git a/src/omni_trace/omni_trace.cljc b/src/omni_trace/omni_trace.cljc index e1554ac..5698360 100644 --- a/src/omni_trace/omni_trace.cljc +++ b/src/omni_trace/omni_trace.cljc @@ -14,16 +14,29 @@ #?(:clj (System/currentTimeMillis) :cljs (.now js/Date))) +(defn reset-workspace! [] + (reset! workspace {})) + +(defn log [workspace id trace] + (swap! workspace assoc id trace)) + (defn trace-fn-call [name f args opts] (let [parent (or *trace-log-parent* {:workspace (::workspace opts) :parent :root}) - call-id (keyword (gensym)) + call-id (keyword (gensym "")) before-time (now) this (assoc parent :parent call-id) res (binding [*trace-log-parent* this] - (apply f args))] - (swap! (:workspace parent) - #(assoc % call-id {:id call-id :name name :args args :start before-time :end (now) :parent (:parent parent) :return res})) + (try + (apply f args) + (catch #?(:clj Throwable :cljs :default) t + (log (:workspace parent) + call-id + {:id call-id :name name :args args :start before-time :end (now) :parent (:parent parent) :thrown (#?(:clj Throwable->map :cljs identity) t)}) + (throw t))))] + (log (:workspace parent) + call-id + {:id call-id :name name :args args :start before-time :end (now) :parent (:parent parent) :return res}) res)) (defn instrumented [sym v opts] diff --git a/src/omni_trace/testing_ns.cljc b/src/omni_trace/testing_ns.cljc index 2dea943..475e904 100644 --- a/src/omni_trace/testing_ns.cljc +++ b/src/omni_trace/testing_ns.cljc @@ -107,4 +107,5 @@ (defn retrieve-change-returned [machine] [(:change-returned machine) + (throw #?(:cljs (js/Error. "Oops") :clj (Exception. "Oops"))) (dissoc machine :change-returned)]) \ No newline at end of file