Fork me on GitHub
#clojure
<
2024-06-27
>
roklenarcic07:06:43

What other templating libraries than Selmer exist? Any with whitespace control?

p-himik07:06:47

You can try using https://phronmophobic.github.io/dewey/search.html. Apart from "template" that will produce quite a few non-matches, another good search term is "mustache".

oλv12:06:06

Is there a tool like htop for JVM/Clojure. I’d like something for inspecting running threads and exploring runtime object trees.

jpmonettas12:06:24

yes, for the JVM you have Java Mission Control, or VisualVM

oλv12:06:11

What do you recommend for inspecting live server processes?

jpmonettas12:06:10

I normally use VisualVM, I find it easier for most cases

jpmonettas12:06:16

if you need very deep monitoring of the inner workings of the JVM, I think the most powerful is JFR (Java Flight Recorder) + JMC (Java Mission Control)

jpmonettas12:06:11

if you are running a repl in a terminal, and just want a thread dump (stack of each thread) you can hit Ctrl+\ and it will dump the threads

vemv14:06:34

For the threads part, in yesterday's thread some options were described https://clojurians.slack.com/archives/C03S1KBA2/p1719422755625319

jumar17:06:28

I think it would help to start with the actual problem you are trying to solve. A running system is constantly changing so you can inspect its snapshot at best. Or you need to actually fire up a debugger and interrupt a thread in whatever it’s doing Also not sure what you mean by runtime object trees

jpmonettas17:06:31

I guess with runtime object trees he refers to a heap dump

oλv18:06:06

@U0739PUFQ whoottt!! never heard abt Ctrl+\ 🤯. I’m only using CIDER+nrepl, does it work there?

jpmonettas18:06:01

no, that only works on the terminal afaik. But you can do the same easily with VisualVM, or other tooling that already comes with the JVM like jstack

oλv18:06:56

By runtime object trees i mean each thread’s tree of reachable objects, i.e the objects which won’t get GCed.

jpmonettas18:06:57

if you don't want to install anything for some reason you can do jps to figure out the process id, and then run jstack PID

jpmonettas18:06:55

> By runtime object trees i mean each thread’s tree of reachable objects, i.e the objects which won’t get GCed. you can do a heap dump on the JVM also, but that will not be thread related. But you can see all objects in the heap and navigate the references

oλv18:06:49

My immediate use case, is that I was concerned that I started a process, i call it the ingester, in two threads. I would like to see the currently running threads to see if I there was a duplicate so I could shut it down.

jpmonettas18:06:32

jstack PID will list on the terminal all the threads running and their current methods stacks at the point you run the command, so you can figure out what threads are running, who is doing what, and also who is blocked waiting, etc

jpmonettas18:06:30

the nice thing about tools like VisualVM is that you have all this functionality from a UI, so you don't need to remember all the commands names and their args

oλv18:06:07

Oh, cool! I never knew about jstack. Seems very useful!

jpmonettas18:06:57

both VisualVM and JMC can also analyze Java Flight Recorder files, which is something that can be turned on the JVM to record a bunch of events even on production, since it doesn't almost affect perf

oλv18:06:58

Can I use visualvm with a server process?

jpmonettas18:06:13

yes, you can connect it to a remote process

jpmonettas18:06:44

but that process needs to be started with some special args, so it can connect to it

oλv18:06:00

That’s fine

jpmonettas18:06:22

> I never knew about jstack if you list your jdk bin folder there are a ton of useful commands like jstack

jpmonettas18:06:05

for example jcmd can send commands to a JVM, for doing a bunch of what VisualVM can do, like heap dump, run the GC, thread dumps, etc

👍 1
oλv18:06:23

Oh, that’s super neat

jpmonettas18:06:39

you can do jcmd PID and it will list all commands available

oλv18:06:51

Is it possible to augment stack traces with Clojure source code ala gdb+dwarf

jpmonettas18:06:35

not sure augmented in what way, for example, if I run jcmd 134400 Thread.print which does the same as jstack 134400 it will show like :

"main" #1 prio=5 os_prio=0 cpu=7525.64ms elapsed=24340.26s tid=0x00007fa288015df0 nid=0x20d09 waiting on condition  [0x00007fa28d9fc000]                                                                    
   java.lang.Thread.State: TIMED_WAITING (sleeping)                                                                                                                                                         
        at java.lang.Thread.sleep([email protected]/Native Method)                                                                                                                                          
        at nrepl.cmdline$dispatch_commands.invokeStatic(cmdline.clj:497)                                                                                                                                    
        at nrepl.cmdline$dispatch_commands.invoke(cmdline.clj:481)                                                                                                                                          
        at nrepl.cmdline$_main.invokeStatic(cmdline.clj:504)                                                                                                                                                
        at nrepl.cmdline$_main.doInvoke(cmdline.clj:499)                                                                                                                                                    
        at clojure.lang.RestFn.applyTo(RestFn.java:140)                                                                                                                                                     
        at clojure.lang.Var.applyTo(Var.java:707)                                                                                                                                                           
        at clojure.core$apply.invokeStatic(core.clj:667)                                                                                                                                                    
        at clojure.main$main_opt.invokeStatic(main.clj:523)                                                                                                                                                 
        at clojure.main$main_opt.invoke(main.clj:519)                                                                                                                                                       
        at clojure.main$main.invokeStatic(main.clj:674)                                                                                                                                                     
        at clojure.main$main.doInvoke(main.clj:626)                                                                                                                                                         
        at clojure.lang.RestFn.applyTo(RestFn.java:140)                                                                                                                                                     
        at clojure.lang.Var.applyTo(Var.java:707)                                                                                                                                                           
        at clojure.main.main(main.java:40)                                                                  
where you can see clojure and java files lines, and fns names

oλv18:06:04

Oh that’s very neat that it gives source lines

oλv18:06:18

Like I mean show the current line verbatim

jpmonettas18:06:47

that I don't think so, but maybe there are tools that can do that

jpmonettas18:06:54

VisualVM has a plugin system, maybe there is a plugin for a thread dump like that, no idea

oλv18:06:45

Anyways, thanks for the advice! These dynamic tools will come in very handy.

gratitude 1
oλv12:06:44

Or like lldb debugger, view of all threads, ability to look at running code and data.

jpmonettas12:06:18

for debugging there are a bunch of options, depending on what you need to debug, like : • stepping over java libraries I prefer IntelliJ debugger, if you have Cursive it can also step over Clojure code with some limitations • stepping over Clojure, if you already use Cider, it contains a simple debugger (same as VSCode) • I use http://www.flow-storm.org/ for Clojure debugging, which is time travel, ide independent (disclaimer I work on it) • many other debugging libraries (check the debugging section in https://www.clojure-toolbox.com/)

jpmonettas12:06:40

but happy to answer debugging questions about any approaches

oλv12:06:42

CIDER inspector is nice for data inspection, but I’d like a view over all my threads.