portal

Steven Lombardi 2023-07-20T18:11:16.374319Z

I find myself very often copy-pasting EDN from my console to Portal. But given that my EDN often has functions in it, the copy-paste routinely fails. I've worked around it by doing something like this manually:

(defn datafy-copied-edn
  [copied-edn-str]
  (clojure.edn/read-string {:readers {'function identity}} copied-edn-str))
And then tapping the result to Portal. But is there room for Portal to make some more assumptions so copy-paste can work out of the box?

Steven Lombardi 2023-08-18T18:23:57.956879Z

Sorry for letting this hang in limbo. Here are some details that will likely be useful.

Steven Lombardi 2023-08-18T18:28:18.624599Z

To reproduce the limitation (not necessarily a bug), log a data structure using a logging library of your choice. Be sure it has a function attached to it:

(log/info "Test: " {:key1 "val1" :key2 (constantly :val2)})
Then copy the data structure to the clipboard and paste it into portal. You'll get an error:
Invalid symbol: clojure.core/constantly/fn--5740.

Steven Lombardi 2023-08-18T18:30:05.365699Z

Steven Lombardi 2023-08-18T18:31:44.762589Z

It's worth noting that attempting to tap> the output causes an error too, so you can't use that as a workaround:

(tap> {:key1 "val1", :key2 #function[clojure.core/constantly/fn--5740]})
; Syntax error reading source at (REPL:9570:71).
; No reader function for tag function

Steven Lombardi 2023-08-18T18:33:41.411609Z

One sort of workaround I've identified is with a helper function like this, but it requires the data be a string which is not ergonomic at all, since you have manually tweak the data tediously (escaping quotes, etc) to get it to work.

(defn datafy-copied-edn
  [copied-edn-str]
  (clojure.edn/read-string {:readers {'function identity}} copied-edn-str))

Steven Lombardi 2023-08-18T18:36:27.286409Z

The alternative is to update all logging sites to make the data a string...

clj꞉cis.sm-customer-stream.roundtrip-test꞉> 
(str {:key1 "val1" :key2 (constantly :val2)})
"{:key1 \"val1\", :key2 #function[clojure.core/constantly/fn--5740]}"
clj꞉cis.sm-customer-stream.roundtrip-test꞉> 
(datafy-copied-edn *1)
{:key1 "val1", :key2 [clojure.core/constantly/fn--5740]}
...but that make retargeting logs to portal almost pointless because the data isn't rich and explorable anymore.

Steven Lombardi 2023-08-18T18:37:56.566019Z

So the question here is how to improve portal's ergonomics so that you can copy paste data from logs into portal to get a rich representation on-demand. We tend to have very large maps full of context/functions/other data so its very helpful to selectively move stuff to portal for more detailed inspection.

Steven Lombardi 2023-08-18T18:40:21.677009Z

The answer might be that we just need to filter out our functions from our context map before logging. But maybe it makes sense for portal to do that for you.

djblue 2023-08-18T18:51:22.433139Z

Ohh, this main issue here is that clojure accepts clojure.core/constantly/fn--5740 as a valid symbol while clojurescript doesn't.

djblue 2023-08-18T18:53:13.026809Z

Have you seen https://cljdoc.org/d/djblue/portal/0.46.0/doc/guides/logging/timbre? It shows how you can send your logs directly from timbre to portal which would side step this issue.

Steven Lombardi 2023-08-18T18:54:10.204759Z

Yeah I've already configured logs to go to portal when I need them to. The problem is when I'm looking at a log in our staging or prod environment and i want to send that data to portal.

👍 1
djblue 2023-08-18T18:56:24.412739Z

Yeah, I think the main reason why datafy-copied-edn works for you is that the edn is being read in via clojure instead of clojurescript

Steven Lombardi 2023-08-18T18:57:35.056779Z

And I'm guessing because Portal aims to have wide dialect support you're kind of stuck with the ClojureScript limitation right?

Steven Lombardi 2023-08-18T18:58:08.864209Z

Or is it because your EDN parsing lives in ClojureScript?

☝️ 1
djblue 2023-08-18T18:58:50.906099Z

Yeah, all of the paste parsing happens in cljs since it's more convenient

Steven Lombardi 2023-08-18T18:59:47.292539Z

Ah I'm following. So if it used Clojure's EDN parsing, paste would "just work"?

djblue 2023-08-18T19:05:02.252849Z

Yeah. I think some options to address this are: • Figure out how to get this edn parsable in cljs • Allow users to specify a command on paste

👍 1
djblue 2023-08-18T19:10:18.827879Z

I think https://github.com/clojure/tools.reader/blob/master/src/main/cljs/cljs/tools/reader/impl/commons.cljs#L97-L118 is the code responsible for parsing symbols 🤔

djblue 2023-08-19T22:18:42.310039Z

Okay, I think https://github.com/djblue/portal/commit/0b35b6aaf012b38141d5c303d935b1523117fb98 should do it

Steven Lombardi 2023-08-23T20:58:51.085639Z

Oh wow that looks like it'll do it. I'll try the new version out and let you know.

djblue 2023-08-23T21:25:07.822409Z

I haven't released this to clojars yet, but it should be available via the standalone version at https://djblue.github.io/portal/

djblue 2023-07-20T18:13:35.834649Z

Yeah, making things easier would be nice. Do you have an example of what the edn looks like?

djblue 2023-07-20T18:24:33.929239Z

https://github.com/djblue/portal/blob/master/src/portal/runtime/edn.cljc is the current logic portal uses to parse most edn

djblue 2023-08-18T05:48:29.087719Z

@lambeauxworks Following up on what type of edn strings caused issues for you 🙏