Giter Site home page Giter Site logo

sayid's Introduction

Sayid logo


CircleCI Clojars Project cljdoc badge

Sayid (siy EED) is an omniscient debugger and profiler for Clojure. It extracts secrets from code at run-time.

Sayid works by intercepting and recording the inputs and outputs of functions. It can even record function calls that occur inside of functions. The user can select which functions to trace. Functions can be selected individually or by namespace. The recorded data can be displayed, queried and profiled.

Sayid currently has three components:

  • sayid.core and its supporting namespaces
  • nREPL middleware
  • A CIDER plugin

The sayid.core namespace is designed to be used directly via a REPL and does not require Emacs or CIDER. BUT the CIDER integration offers a far better experience, so it is the current focus of this page and my development efforts.

We're looking for more maintainers for the project. If you're interested in helping out please ping @bbatsov.

Installation & Requirements

Requirements

Basic usage requires Clojure 1.7 and the optional nREPL middleware requires nREPL 0.4+.

nREPL-powered editor plugins are encouraged to make use of the bundled middleware that provides a very flexible Sayid API.

Leiningen

Add this to the dependencies in your project.clj or lein profiles.clj:

[com.billpiel/sayid "0.1.0"]

To use the bundled nREPL middleware, you'll want to include Sayid as a plug-in. Here's an example of a bare-bones profiles.clj that works for me:

{:user {:plugins [[com.billpiel/sayid "0.1.0"]]}}

Clojure CLI - deps.edn

Add a the Sayid dependency to your :deps key. Depending on your desired setup, you may want to add it to an optional profile, or your tools.deps config directory (often $HOME/.clojure).

{:deps
  {com.billpiel/sayid {:mvn/version "0.1.0"}}}

Emacs Integration

CIDER setup also requires that the Emacs package sayid is installed. It's available on MELPA and MELPA Stable. Put this code in init.el, or somewhere, to load keybindings for clojure-mode buffers.

(eval-after-load 'clojure-mode
  '(sayid-setup-package))

If you use CIDER's jack-in commands, then Sayid automatically adds the Maven dependency when starting a REPL. This means you don't need to manually add the dependency to your project.clj or deps.edn file.

If you don't use CIDER's jack-in commands, you'll need to add a dependency manually. Here's an example of a bare-bones profiles.clj that works for me:

{:user {:plugins [[cider/cider-nrepl "0.25.3"]
                  [com.billpiel/sayid "0.1.0"]]
        :dependencies [[nrepl/nrepl "0.7.0"]]}}

Usually you'll want to use the latest versions of cider-nrepl and nREPL here.

Other Editors

A 3rd-party vim plugin also exists. See this and this.

Using Sayid

Note: This assumes you're using the official CIDER plugin..

Documentation is a little light at the moment. There are lists of keybindings. Helpfully, they are easily accessible from within emacs. Below are the contents of the various help buffers, as well as instructions on how to pop them up in time of need.

Generated docs are also available for the core namespace here.

In a clojure-mode buffer, press C-c s h (sayid-show-help) to pop up the help buffer.

C-c s ! -- Disable traces, eval current buffer, enable traces, clear the workspace log
C-c s e -- Enables traces, evals the expression at point, disables traces, displays results with terse view
C-c s f -- Queries the active workspace for entries that most closely match the context of the cursor position
C-c s n -- Applies an inner trace to the function at point, replays workspace, displays results
C-c s r -- Replays workspace, queries results by context of cursor
C-c s w -- Shows workspace, using the current view
C-c s t y -- Prompts for a dir, recursively traces all ns's in that dir and subdirs
C-c s t p -- Prompts for a pattern (* = wildcare), and applies a trace to all *loaded* ns's whose name matches the patten
C-c s t b -- Trace the ns in the current buffer
C-c s t e -- Enable the *existing* (if any) trace of the function at point
C-c s t E -- Enable all traces
C-c s t d -- Disable the *existing* (if any) trace of the function at point
C-c s t D -- Disable all traces
C-c s t n -- Apply an inner trace to the symbol at point
C-c s t o -- Apply an outer trace to the symbol at point
C-c s t r -- Remove existing trace from the symbol at point
C-c s t K -- Remove all traces
C-c s c -- Clear the workspace trace log
C-c s x -- Blow away workspace -- traces and logs
C-c s s -- Popup buffer showing what it currently traced
C-c s S -- Popup buffer showing what it currently traced in buffer's ns
C-c s V s -- Set the view
C-c s h -- show this help

In the *sayid* buffer, press h to pop up the help buffer.

ENTER -- pop to function
d -- def value to $s/*
f -- query for calls to function
F -- query for calls to function with modifier
i -- show only this instance
I -- query for this instance with modifier
w -- show full workspace trace
n -- jump to next call node
N -- apply inner trace and reply workspace
p -- jump to prev call node
P -- pretty print value
C -- clear workspace trace log
v -- toggle view
V -- set view (see register-view)
l, backspace -- previous buffer state
L, S-backspace -- forward buffer state
g -- generate instance expression and put in kill ring
h -- help

In the *sayid-traced* buffer, press h to pop up the help buffer.

enter -- Drill into ns at point
e -- Enable trace
d -- Disable trace
E -- Enable ALL traces
D -- Disable ALL traces
i -- Apply inner trace to func at point
o -- Apply outer trace to func at point
r -- Remove trace from fun at point
l, backspace -- go back to trace overview (if in ns view)

In the *sayid-pprint* buffer, press h to pop up the help buffer.

ENTER -- show path in mini-buffer
i -- jump into child node
o -- jump out to parent node
n -- jump to next sibling node
p -- jump to previous sibling node

Demos

Conj 2016 Presentation

I presented Sayid at the Clojure Conj conference in Austin in 2016.

Becoming Omniscient with Sayid - Bill Piel

Demo #1 - Video

A demo video I recorded after the very first alpha release. You can find the contrived example project here.

Sayid v0.0.1 - Demo #1

Demo #1 - Walkthrough

This is a written walkthrough of the same steps illustrated in the demo video above, but with Sayid v0.0.8. You can find the contrived example project here.

Below is the code to the test namespace. You can see that we have a vending machine that dispenses tacos for 85 cents. We execute the test1 function, which inserts 41 cents worth of change and presses the taco button.

(ns contrived-example.core-test
  (:require [clojure.test :refer :all]
            [contrived-example.core :as ce]))


(def test-vending-machine {:inventory {:a1 {:name :taco
                                            :price 0.85
                                            :qty 10}}
                           :coins-inserted []
                           :coins-returned []
                           :dispensed nil
                           :err-msg nil})

(defn test1 []
  (-> test-vending-machine
      (ce/insert-coin :quarter) ;; 25
      (ce/insert-coin :dime)    ;; 35
      (ce/insert-coin :nickel)  ;; 40
      (ce/insert-coin :penny)   ;; 41 cents
      (ce/press-button :a1)))   ;; taco costs 85 cents

(test1)

Let's press some keys to get Sayid going.

eval the namespace C-c C-k (probably) (cider-load-buffer)

trace the project namespaces [C-c s t p]{.kbd} (sayid-trace-ns-by-pattern) then contrived-example.*

This should pop up. It shows how many functions have been traced in which namespaces. Execute test1!

Traced namespaces:
  5 / 5  contrived-example.core
  1 / 1  contrived-example.core-test
  8 / 8  contrived-example.inner-workings


Traced functions:

You can't tell yet, but something magical happened. Press C-c s w (sayid-get-workspace) to get an overview of what has been captured in the Sayid workspace. This monster should appear:

v contrived-example.core-test/test1  :13446
|v contrived-example.core/insert-coin  :13447
|^
|v contrived-example.core/insert-coin  :13448
|^
|v contrived-example.core/insert-coin  :13449
|^
|v contrived-example.core/insert-coin  :13450
|^
|v contrived-example.core/press-button  :13451
||v contrived-example.inner-workings/valid-selection  :13452
|||v contrived-example.inner-workings/get-selection  :13453
|||^
|||v contrived-example.inner-workings/calc-coin-value  :13454
|||^
||| contrived-example.inner-workings/valid-selection  :13452
||^
||v contrived-example.inner-workings/process-transaction  :13455
|||v contrived-example.inner-workings/get-selection  :13456
|||^
|||v contrived-example.inner-workings/calc-change-to-return  :13457
||||v contrived-example.inner-workings/calc-coin-value  :13458
||||^
||||v contrived-example.inner-workings/round-to-pennies  :13459
||||^
||||v contrived-example.inner-workings/calc-change-to-return*  :13460
|||||v contrived-example.inner-workings/calc-coin-value  :13461
|||||^
|||||v contrived-example.inner-workings/calc-change-to-return*  :13462
||||||v contrived-example.inner-workings/calc-coin-value  :13463
||||||^
||||||v contrived-example.inner-workings/calc-change-to-return*  :13464
|||||||v contrived-example.inner-workings/calc-coin-value  :13465
|||||||^
|||||||v contrived-example.inner-workings/calc-change-to-return*  :13466
||||||||v contrived-example.inner-workings/calc-coin-value  :13467
||||||||^
|||||||| contrived-example.inner-workings/calc-change-to-return*  :13466
|||||||^
|||||||v contrived-example.inner-workings/calc-change-to-return*  :13468
||||||||v contrived-example.inner-workings/calc-coin-value  :13469
||||||||^
|||||||| contrived-example.inner-workings/calc-change-to-return*  :13468
|||||||^
|||||||v contrived-example.inner-workings/calc-change-to-return*  :13470
||||||||v contrived-example.inner-workings/calc-coin-value  :13471
||||||||^
|||||||| contrived-example.inner-workings/calc-change-to-return*  :13470
|||||||^
||||||| contrived-example.inner-workings/calc-change-to-return*  :13464
||||||^
|||||| contrived-example.inner-workings/calc-change-to-return*  :13462
|||||^
||||| contrived-example.inner-workings/calc-change-to-return*  :13460
||||^
|||| contrived-example.inner-workings/calc-change-to-return  :13457
|||^
||| contrived-example.inner-workings/process-transaction  :13455
||^
|| contrived-example.core/press-button  :13451
|^
| contrived-example.core-test/test1  :13446
^

What's the meaning of this? These are all the function calls that were made in the traced namespaced when we execute test1.

Let's explore. Get your cursor to the first line of the output and press i (sayid-query-id).

 v contrived-example.core-test/test1  :13446
 | returned =>  {:inventory {:a1 {:name :taco :price 0.85 :qty 9}}
 |               :coins-inserted []
 |               :coins-returned [:quarter :quarter :nickel]
 |               :dispensed {:name :taco :price 0.85 :qty 10}
 |               :err-msg nil}
 ^

This shows us the details of that instance of test1 being called. We can see that a hash map was returned. Despite us inserting only 41 cents for an 85 cent taco, we see that a taco was dispensed, plus change! That's a BUG.

Hit backspace (sayid-buf-back). We're back at the overview. Scan the list of functions that are called. Let's assume some programmer's intuition and decide that valid-selection is the first place of interest. Get your cursor to that line and press these keys to view the instance and all of its descendants. I d ENTER (sayid-query-id-w-mode`)

 ||v contrived-example.inner-workings/valid-selection  :13452
 ||| machine => {:inventory {:a1 {:name :taco :price 0.85 :qty 10}}
 |||             :coins-inserted [:quarter :dime :nickel :penny]
 |||             :coins-returned []
 |||             :dispensed nil
 |||             :err-msg nil}
 ||| button => :a1
 ||| returns =>  true
 |||v contrived-example.inner-workings/get-selection  :13453
 |||| machine => {:inventory {:a1 {:name :taco :price 0.85 :qty 10}}
 ||||             :coins-inserted [:quarter :dime :nickel :penny]
 ||||             :coins-returned []
 ||||             :dispensed nil
 ||||             :err-msg nil}
 |||| button => :a1
 |||| returned =>  {:name :taco :price 0.85 :qty 10}
 |||^
 |||v contrived-example.inner-workings/calc-coin-value  :13454
 |||| coins => [:quarter :dime :nickel :penny]
 |||| returned =>  1.4
 |||^
 ||| contrived-example.inner-workings/valid-selection  :13452
 ||| machine => {:inventory {:a1 {:name :taco :price 0.85 :qty 10}}
 |||             :coins-inserted [:quarter :dime :nickel :penny]
 |||             :coins-returned []
 |||             :dispensed nil
 |||             :err-msg nil}
 ||| button => :a1
 ||| returned =>  true
 ||^

We can see that valid-selection makes calls to get-selection and calc-coin-value. Looking at the return values, we might notice a problem: calc-coin-value receives [:quarter :dime :nickel :penny] but returns $1.40 as the value. Let's dig deeper. Press n (sayid-buffer-nav-to-next) a couple times to get the cursor to the call to calc-coin-value. Now press N (sayid-buf-replay-with-inner-trace) and hold onto your hat.

 ||||v (->> coins (keep coin-values) (apply +)) => (apply + (keep coin-values coins))  contrived-example.inner-workings/calc-coin-value  :13491
 ||||| returns =>  1.4
 |||||v (apply + (keep coin-values coins))  contrived-example.inner-workings/calc-coin-value  :13492
 |||||| #function[clojure.core/+]
 |||||| (0.25 0.1 0.05 1)
 |||||| returns =>  1.4
 ||||||v (keep coin-values coins)  contrived-example.inner-workings/calc-coin-value  :13493
 ||||||| {:quarter 0.25 :dime 0.1 :nickel 0.05 :penny 1}
 ||||||| [:quarter :dime :nickel :penny]
 ||||||| returned =>  (0.25 0.1 0.05 1)
 ||||||^
 |||||| (apply + (keep coin-values coins))  contrived-example.inner-workings/calc-coin-value  :13492
 |||||| #function[clojure.core/+]
 |||||| (0.25 0.1 0.05 1)
 |||||| returned =>  1.4
 |||||^
 ||||| (->> coins (keep coin-values) (apply +)) => (apply + (keep coin-values coins))  contrived-example.inner-workings/calc-coin-value  :13491
 ||||| returned =>  1.4
 ||||^
...truncated...

(jump to the top of the buffer)

What did we do? We applied an inner trace to the function calc-coin-value and then replayed the call to test1 that we had captured originally.

An INNER trace? YES! We can see the inputs and output values of each expression in the function. Look at it. Where do things go wrong? It's when we pass a hash map to keep that defines a penny as being worth a dollar. Bug located! Press n a couple times to get your cursor to that call. Press RET to jump to that line of code.

 (ns contrived-example.inner-workings)

 (def coin-values
   {:quarter 0.25
    :dime 0.10
    :nickel 0.05
    :penny 1})

 (defn- calc-coin-value
   [coins]
   (->> coins
        (keep coin-values)
        (apply +)))

...truncated...

We now find ourselves at the troublesome call to keep causing our bug. The hash map, coin-values, is just above. Change the value of a penny from 1 to 0.01. Let's eval our corrected code the Sayid way -- press C-c s ! (sayid-load-enable-clear). This will remove the traces, eval the buffer, then re-apply the traces. It also clears the workspace log. This is all helpful. Navigate back to core-test and run test1 again. Repeating steps above, you can verify the output is now correct: no taco.

 v contrived-example.core-test/test1  :13579
 | returned =>  {:inventory {:a1 {:name :taco :price 0.85 :qty 10}}
 |               :coins-inserted [:quarter :dime :nickel :penny]
 |               :coins-returned []
 |               :dispensed nil
 |               :err-msg true}
 ^

Great work!

License

Distributed under the Apache 2.0 License. See LICENSE for details.

sayid's People

Contributors

andreacrotti avatar bbatsov avatar benedekfazekas avatar bpiel avatar briaoeuidhtns avatar danielcompton avatar futuro avatar jekelly-adobe avatar jhacksworth avatar markgdawson avatar syohex avatar yonatane avatar zheh12 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sayid's Issues

Update install instructions for new versions of CIDER

The install instructions say to add a dependency on [cider/cider-nrepl "0.19.0"] and [nrepl/nrepl "0.5.3"]. New versions of CIDER automatically add the cider-nrepl dependency, and I'm guessing also add unreal as an implicit dependency. Are either/both of these still necessary to install Sayid?

Pressing g in the *sayid* windows results in wrong-type-argument

Exactly where should I have the focus on when doing the 'g' command? Now I get an error.

This is the call stack:

Debugger entered--Lisp error: (wrong-type-argument stringp (now-as-str))

string-match("\`-+\'" (now-as-str))
menu-bar-update-yank-menu((now-as-str) nil)
kill-new((now-as-str))
sayid-gen-instance-expr()
funcall-interactively(sayid-gen-instance-expr)
call-interactively(sayid-gen-instance-expr nil nil)
command-execute(sayid-gen-instance-expr)

Sayid Viability for CLJS?

It appears that sayid does not currently support CLJS. Is there any technical reason for this? If not, I may be interested in helping make CLJS happen.

Multiple errors on multiple functions (invalid arity)

Sorry, I don't even know how make a meaningful title to help you but anyway...

I'm integrating Sayid on Atom using my plugin "clojure-plus", but I'm having a lot of errors on a lot of functions. For instance, in "inner trace":

(sayid/ws-add-inner-trace-fn! f) ; This "f" is a full qualified symbol
=> NullPointerException

(sayid/ws-inner-trace-apply 'some/function [10 20])
=> ArityException Wrong number of args (2) passed to: inner-trace2/inner-tracer  clojure.lang.AFn.throwArity (AFn.java:429)

(sayid/ws-inner-trace-apply-print 'some/function [10 20])
=> ArityException Wrong number of args (2) passed to: inner-trace2/inner-tracer  clojure.lang.AFn.throwArity (AFn.java:429)

(sayid/ws-replay-id! :30174)
ArityException Wrong number of args (1) passed to: core/ws-query  clojure.lang.AFn.throwArity (AFn.java:429)

(sayid/ws-query-inner-trace-replay [:id id])
NullPointerException   clojure.lang.Compiler.maybeResolveIn (Compiler.java:7174)

What's going on? Are these functions really not meant to be used? If so, how can I do an inner trace?

'q' should close buffer

pressing 'q' in a sayid window should close it. i think this is command with many command/report like windows.

*sayid* buffer shows text without color or functionality

Tutorial worked fine for me, but now Sayid is failing to work on my own project. The workspace text is not colored and none of the keyboard shortcuts work. For example, pressing i fails to inspect node, it just types the letter i.

I'm assuming there must be some difference in setup between my project and the tutorial, but my stabs in the dark failed. I added the following line to my project.clj:

:repl-options {:nrepl-middleware [com.billpiel.sayid.nrepl-middleware/wrap-sayid]}

My project is called assembler. I created with lein new app assembler.

Here is the my entire project.clj file:

(defproject assembler "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]]
  :main ^:skip-aot assembler.core
  :target-path "target/%s"
  :repl-options {:nrepl-middleware [com.billpiel.sayid.nrepl-middleware/wrap-sayid]}
  :profiles {:uberjar {:aot :all}})

And here is my ~/.lein/profiles.clj

{:repl {:plugins [[cider/cider-nrepl "RELEASE"]
                  [refactor-nrepl "RELEASE"]]
        :dependencies [[alembic "RELEASE"]
                       [org.clojure/tools.nrepl "RELEASE"]
                       [com.cemerick/pomegranate "RELEASE"]
                       [zprint "RELEASE"]]
        :global-vars {*print-length* 1000}}
 :user {:plugins [[cider/cider-nrepl "RELEASE"]
                  [com.billpiel/sayid "RELEASE"]]
        :dependencies [[org.clojure/tools.nrepl "RELEASE"]]}}

I'm running Emacs Version 25.1 (9.0) with Spacemacs Release 0.200.9.

The error in the mini-buffer reads: Wrong type argument: listp, /././.

Here's a screenshot too: http://img.webappzero.com/kjgV

Automatic dependency injection no longer works for non-Lein projects

I've documented this in PR #67 also, but the short of it is that Cider no longer uses the cider-jack-in-lein-plugins var for non-lein projects, and but Sayid hasn't been updated to match the new behavior.

I'm creating this issue after the PR in the event that other folks hit this same issue, and can see that there's movement on fixing it.

Also, thanks for making/maintaining such a great plugin!

Error when trying to start inner-trace

When I try to perform an inner-trace on a function (sayid-inner-trace-fn) I get the following error on the REPL

https://gist.github.com/DonyorM/dbe0f39bcaec5f156fbb607fc297093b

When trying to run the function I get the following errors on the repl before the function result is outputted:

(AFn.java:18)
    java.util.concurrent.FutureTask.run (FutureTask.java:266)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
    java.lang.Thread.run (Thread.java:745)

The trace is not registered in the workplace.

I am testing this with the newest spacemacs, using cider 0.15.0snapshot and sayid 0.0.11

Any chance for a Vim plugin?

This project looks perfect for answering the "Why is my data this shape?" question. Any plans for Vim users, or making the project easily consumable by other plugin writers?

Thanks.

Rerunning same function multiple times

So I'm trying to get sayid to run trace a function multiple times. I trace the function and then run it with cider-load-buffer. The first time I do this, it works great, I can open the workspace and view all of my returns. However, once I try to run it again, nothing happens. Pressing C in the sayid buffer does not seem to affect anything.

Is this a bug? Or am I doing something wrong?

Exception when using with Spec

Just thought i'd give Sayid a whirl as it really looks promising, I to want to stop 'sprinkling'.

Configured everything and got this little monster:

kixi.datastore.schema-creator/schema-validator schema_creator.clj: 18
clojure.spec/valid? spec.clj: 744
clojure.spec/map-spec-impl/reify/conform* spec.clj: 782
clojure.spec/conform spec.clj: 150
clojure.spec/or-spec-impl/reify/conform* spec.clj: 1041
clojure.spec/or-spec-impl/fn spec.clj: 1006
clojure.spec/map-spec-impl/reify/conform* spec.clj: 782
clojure.spec/conform spec.clj: 150
clojure.spec/regex-spec-impl/reify/conform* spec.clj: 1633
clojure.spec/re-conform spec.clj: 1589
clojure.spec/deriv spec.clj: 1463 (repeats 3 times)
clojure.spec/deriv spec.clj: 1456
clojure.spec/dt spec.clj: 727
clojure.spec/dt spec.clj: 731
clojure.spec/conform spec.clj: 150
clojure.spec/multi-spec-impl/reify/conform* spec.clj: 900
clojure.spec/multi-spec-impl/predx spec.clj: 886
java.lang.ClassCastException: com.billpiel.sayid.trace$shallow_tracer$tracing_wrapper__22432 cannot be cast to clojure.lang.MultiFn`

Looks like spec doesn't like some of the fn wrapping that's going on. Hopefully will get the chance to dig into this a bit tomorrow, but thought I'd see if this was a common problem.

Submit package to MELPA

Plz place package to MELPA repo.

I work on layer for spacemacs and it a little bit hacky to use packages from non-melpa and non-gnu repos.

Wrong type argument error

When I tried running this in Spacemacs I got the following error when using the C-c s t p command:

(wrong-type-argument char-or-string-p nil)
  write-resp-val-to-buf(nil #<buffer *sayid-traced*>)
  sayid-setup-buf(nil t nil)
  sayid-req-insert-meta-ansi(("op" "sayid-show-traced" "ns" nil))
  sayid-show-traced()
  sayid-trace-ns-by-pattern()
  call-interactively(sayid-trace-ns-by-pattern nil nil)
  command-execute(sayid-trace-ns-by-pattern)

I was using the newest development version (develop branch) with the default clojure layer. Sayid was added as an additional package using a melpa recipe from github:

(sayid :location (recipe :fetcher github :repo bpiel/sayid :files ("src/el/*.el")))

How should I fix this?

Documentation request

Hi,

I'm definitely appreciating Sayid now that I'm spending more time with it! Unfortunately, a lot of the documentation shows only key chords. For example, from the overview: "Press C-c s w to get an overview of what has been captured in the Sayid workspace". For those of us using different bindings (eg evil-mode users, spacemacs users) that doesn't really tell us anything. It would be really helpful if when you give a key chord, you could also include the name of the function. A lot of emacs packages do it parenthetically, which IMHO works well, ie "Press C-c s w (sayid-workspace-overview) to get an overview of what has been captured in the Sayid workspace".

Thanks much! With or without this change, Sayid is awesome :)

Invitation to join clojure-emacs or nREPL org

Hey there!

sayid seems like a cool project that can certainly benefit from getting more love from the Clojure and Emacs hackers out there. Not sure what your plans for the project are, but if you'd like to get some help - consider yourself invited to join either https://github.com/clojure-emacs or https://github.com/nrepl and transfer the project there.

I think that grouping related projects together increases the chances for their long-term success.

Error on define sayid-set-clj-mode-keys

File mode specification error: (error Autoloading failed to define function sayid-set-clj-mode-keys)

I use spacemacs. It worked yesterday, but now it doesn't : (
Also, it breaks all cider keybinding provided by spacemacs.

Investigate buildout into production-scalable tooling

Filing this ticket as a set of TODO items largely for myself, but hopefully also as a conversation-starter.

  • How expensive is it to have instrumentation check whether tracing is enabled and, finding that it isn't, not trace an invocation? (That is to say: Is the overhead low enough to have instrumentation be present in production, but only called on a representative sample or when another condition is met)?
  • How expensive is it to collect traces, but them throw them away? (If we can trace a call, but only serialize and export those traces if an error condition is detected, this would be a powerful tool for detailed error reporting).
  • How expensive is it to collect (or report) only profiling results, but not arguments and return values?
  • Is exporting sysdig trace events rather than accumulating state in-memory a workable approach?

Undo buffer limit exceeded

I have been doing an inner trace on a recursive function, and thus generating a very large workspace buffer. I've been getting this error basically whenever I did something.

Warning (undo): Buffer `*sayid*' undo info was 21192348 bytes long.
The undo info was discarded because it exceeded `undo-outer-limit'.

This is normal if you executed a command that made a huge change
to the buffer.  In that case, to prevent similar problems in the
future, set `undo-outer-limit' to a value that is large enough to
cover the maximum size of normal changes you expect a single
command to make, but not so large that it might exceed the
maximum memory allotted to Emacs.

If you did not execute any such command, the situation is
probably due to a bug and you should report it.

You can disable the popping up of this buffer by adding the entry
(undo discard-info) to the user option `warning-suppress-types',
which is defined in the `warnings' library.

I don't know if sayid needs the undo buffer, so if it doesn't, we could consider removing it to avoid the issue. Otherwise, users need to set their limit higher.

Symbol's value as a variable is void: sayid-ring

I have sayid installed both on the emacs and clojure side. Curerntly, sayid-version displays 0.0.17 both for clj and el. This is the content of my ~/.lein/profiles.clj:

{:user {:plugins [[cider/cider-nrepl "0.18.0"]
                  [com.billpiel/sayid "0.0.17"]]
        :dependencies [[org.clojure/tools.nrepl "0.2.12"]]}}

I tried setting up a very minimal example:

(ns sayid-test.core
  (:gen-class))

(defn foo [x]
  (max 1 2 3 (+ x (* x 3))))

After evaling this buffer with cider-eval-buffer, I run sayid-trace-ns-in-file and get the expected message:

Traced namespaces:
  1 / 1  sayid-test.core


Traced functions:

After this, I open a REPL and eval (foo 5), which should make sayid trace the run of the function. And then, when I run sayid-get-workspace, I find myself with an empty buffer, and the error message: Symbol's value as a variable is void: sayid-ring

Any idea what could be wrong?

Nothing appearing in Sayid Workspace

So I have a function I'm trying to trace. I can add a trace (I have done this with sayid-trace-ns-in-file, sayid-trace-fn-enable, and sayid-inner-trace-fn) but when I run the buffer with cider-load-buffer nothing appears in the sayid workspace. Here is the namespace:

(ns four-clojure.scratch
  (:require [four-clojure.core :as c]))

(def trans-test #{[8 4] [9 3] [4 2] [27 9]})

(defn transitive [s]
  (let [val-map (apply hash-map (flatten (vec s)))
        find-relations (fn find-relations [key]
                         (let [result (get val-map key)]
                           (if result
                             (lazy-seq (cons result (find-relations result))))))]
    (reduce (fn [coll item]
              (map (fn [x]
                     [item x]) (find-relations item)))
            #{} (keys val-map))))

(transitive trans-test)

I get a result in the minibuffer, so I know the code runs. The traces all appear in the trace buffer. No errors occur as far as I can see.

I have this setup in spacemacs, so that could be part of the issue. But before I dive into the mess, I'd like to make sure it really is just my setup.

Looks like sayid was released but not published to clojars or any other repository

I'm getting this classpath exception

error in process sentinel: nrepl-server-sentinel: Could not start nREPL server: Error building classpath. Could not find artifact com.billpiel:sayid:jar:0.0.18 in central (https://repo1.maven.org/maven2/)

error in process sentinel: Could not start nREPL server: Error building classpath. Could not find artifact com.billpiel:sayid:jar:0.0.18 in central (https://repo1.maven.org/maven2/)

Pressing "g" cannot locate source file.

Not sure what is broken, here. When I press in "g" during looking into function's trace it fails at the moment of finding proper file:

  • Emacs version 25.1.1
  • latest sayid from master branch

Here https://github.com/bpiel/sayid/blob/master/src/el/sayid.el#L777 I've got exception:
File not found: antonov/api/availability.clj

I tried to trace it in emacs (sayid-find-existing-file file) => ("clojure" "/private/var/folders/ty/q1nfz8qn24x_8p27fx7z14yr0000gp/T" "cider" "mranderson047")`

Looks wrong because project root is not existing here. Please help me trace and fix this exception.

p.s. Sayid probably can go thru existing opened file-buffers, and if filepath will match file requested - write expression there. Or even better solution open cider-scratch and writedown form there.
If you're fine with using cider-scratch I can implement it. thanks!

document nrepl interface

Add documentation for the nrepl interface to facilitate work on plugins/integrations by people other than myself.

Documentation on how to use this with a deps.edn project + CIDER

I'm looking at trying to use Sayid with a deps.edn project, but I'm not really sure how to translate the requirement of adding [com.billpiel/sayid "0.0.17"] to Leiningen's :plugins into a deps.edn project. It would be very useful if there was more documentation on this. If I figure it out, I'll make a PR.

Clean up the homepage

The homepage is full of markup that was generated using https://github.com/hniksic/emacs-htmlize. It's extremely hard to work with it, so we should clean up all the excessive markup and inline styles. I think most of the font-locking is non-essential anyways (and the cases where it's useful can be replaced with screenshots).

Wrong type argument

Currently try to work with sayid (still in spacemacs), but whenever I try to initiate a trace, I'm getting this error: sayid-write-resp-val-to-buf: Wrong type argument: listp, 19

Debugger entered--Lisp error: (wrong-type-argument listp 19)
  sayid-put-text-props(((0 19 (("start" 0) ("start-col" 0))) (19 39 (("start" 19) ("start-col" 0)))) #<buffer *sayid-traced*>)
  sayid-write-resp-val-to-buf(("Traced namespaces:\n\n\nTraced functions:\n" ((0 19 (("start" 0) ("start-col" 0))) (19 39 (("start" 19) ("start-col" 0))))) #<buffer *sayid-traced*>)
  sayid-setup-buf(("Traced namespaces:\n\n\nTraced functions:\n" ((0 19 (("start" 0) ("start-col" 0))) (19 39 (("start" 19) ("start-col" 0))))) t nil)
  sayid-req-insert-content(("op" "sayid-show-traced" "ns" nil))
  sayid-show-traced()
  sayid-remove-trace-fn()
  call-interactively(sayid-remove-trace-fn nil nil)
  command-execute(sayid-remove-trace-fn

In this case I was trying to remove a trace from this function:

(defn transitive [s]
    (let [val-map (apply hash-map (flatten (vec s)))
          find-relations (fn find-relations [key]
                           (let [result (get val-map key)]
                           (if result
                             (lazy-seq (cons result (find-relations result))))))]
      (reduce (fn [coll item]
                (map (fn [x]
                       [item x]) (find-relations item)))
              #{} (keys val-map))))

I get similar errors when enabling a trace or creating an inner trace. Creating an inner trace does cause the trace to appear on the sayid-traced buffer. Just enabling a trace does not making it appear in the traced buffer. In either case, the results do not appear in the sayid workspace when I run the method.

sayid-buf-replay-with-inner-trace not found

I'm not finding the sayid-buf-replay-with-inner-trace function in my M-x listing in emacs. I'm trying to create new bindings for sayid in Emacs, but it seems that function doesn't exist.

I am running the develop branch of Spacemacs in emacs 24.
I added sayid with the following package code:

(sayid :location (recipe :fetcher github
                             :repo bpiel/sayid
                             :files ("src/el/*.el")))

support *.cljc files

Did the C-c s t p. Instrumented my code, which is just one *.cljc file. Ran it and then did the C-c s w bit and it showed the trace report. Went into the report and hit enter on first line/column, the v. Got error: "File not found: omn1/core2.cljc".

My source tree looks like:

 src
 |-- clj
 `-- cljc
     `-- omn1
         `-- core2.cljc

My guess is you dont look in src/cljc dir for files?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.