elide run --insights=<VALUE> in a Java or Kotlin project attaches an instrumentation agent to the program’s JVM.
The value is either a JavaScript Insight script or a Java class:
| Value | Runs | Repeatable |
|---|---|---|
trace.js | A JavaScript script that calls insight.on | Yes |
class:app.Trace | A class on the program’s classpath with public static void insightmain(String, JvmInsight) | No; cannot be mixed with scripts |
--insights applies to project runs (elide run with a jvm.main) and single-file Java or Kotlin runs (elide run Main.java).
The examples trace this program:
// elide.pkl
amends "elide:project.pkl"
name = "insight-demo"
jvm {
main = "app.Main"
}// src/main/java/app/Main.java
package app;
public class Main {
static int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
System.out.println(add(1, 2));
}
}Scripts
// trace.js
insight.on("enter", (ctx, frame) => {
console.log("enter " + ctx.name + " a=" + frame.a + " b=" + frame.b);
}, { roots: true, rootNameFilter: "Lapp/Main;\\.add.*" });
insight.on("return", (ctx, frame) => {
console.log("return " + ctx.name);
}, { roots: true, rootNameFilter: "Lapp/Main;\\.add.*" });elide run --insights=trace.jsenter Lapp/Main;.add(II)I a=1 b=2
return Lapp/Main;.add(II)I
3The first run downloads the JavaScript engine for the agent (about 67 MB of JARs) into the Maven cache. JVM warnings and agent log lines go to stderr.
| Script API | On a JVM program |
|---|---|
| Events | enter and return; no source |
rootNameFilter | Required; without it the handler never runs. A regular expression that must match the whole method name, L<class path>;. |
roots, statements | Match method entries, or each statement; no expressions |
sourceFilter | Not supported |
ctx.name | The method name in the form above |
ctx.line | Source line for statements; -1 for roots |
frame | Arguments and locals by name (frame.a) |
ctx.returnValue | Not available |
Handlers see only the program’s own classes: a broad filter such as .* skips JDK classes and the insight engine itself.
Classes
A class on the program’s classpath receives the agent’s API and registers handlers with onMethod. The API is in the
bundled org.apidesign.jvm:jvm-insight:0.2, which a project declares as compileOnly:
dependencies {
maven {
compileOnly { "org.apidesign.jvm:jvm-insight:0.2" }
}
}// src/main/java/app/Trace.java
package app;
import org.apidesign.jvm.insight.JvmInsight;
public class Trace {
public static void insightmain(String args, JvmInsight insight) {
insight.onMethod((method, builder) -> {
if (method.clazz().name().equals("app.Main") && method.name().equals("add")) {
builder.when(JvmInsight.When.ENTER).roots(true)
.call((at, frame) -> System.out.println("enter " + at.method().name() + " " + frame));
}
});
}
}elide run --insights=class:app.Traceenter add {a=1, b=2}
3JvmInsight API | Use |
|---|---|
onMethod((method, builder) -> …) | Called for each method as its class loads; method.clazz().name(), method.name(), method.descriptor() identify it |
builder. | When the handler runs |
builder.roots(true), builder. | Method entry, or each statement |
builder. | The handler; at.method(), at.line(), and frame as a Map of arguments and locals |
Class handlers need no download.