or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

context-management.mdengine-management.mdexecution-monitoring.mdindex.mdio-abstractions.mdproxy-system.mdsecurity-configuration.mdsource-management.mdvalue-operations.md

execution-monitoring.mddocs/

0

# Execution Monitoring

1

2

Execution monitoring provides advanced capabilities for observing, profiling, and debugging polyglot execution environments. It enables detailed execution events, performance metrics, and instrumentation across all supported languages with minimal performance overhead.

3

4

## Capabilities

5

6

### Execution Listener

7

8

Monitor execution events across polyglot contexts.

9

10

```java { .api }

11

public final class ExecutionListener implements AutoCloseable {

12

public static ExecutionListener.Builder newBuilder();

13

public ExecutionListener attach(Engine engine);

14

public void close();

15

}

16

17

public static final class ExecutionListener.Builder {

18

public ExecutionListener.Builder onEnter(Consumer<ExecutionEvent> callback);

19

public ExecutionListener.Builder onReturn(Consumer<ExecutionEvent> callback);

20

public ExecutionListener.Builder expressions(boolean enabled);

21

public ExecutionListener.Builder statements(boolean enabled);

22

public ExecutionListener.Builder roots(boolean enabled);

23

public ExecutionListener.Builder sourceFilter(Predicate<Source> filter);

24

public ExecutionListener.Builder rootNameFilter(Predicate<String> filter);

25

public ExecutionListener build();

26

}

27

```

28

29

**Usage:**

30

31

```java

32

// Basic execution monitoring

33

ExecutionListener listener = ExecutionListener.newBuilder()

34

.onEnter(event -> {

35

System.out.println("Entering: " + event.getLocation());

36

})

37

.onReturn(event -> {

38

System.out.println("Returning: " + event.getReturnValue());

39

})

40

.statements(true)

41

.expressions(true)

42

.build();

43

44

try (Engine engine = Engine.create()) {

45

ExecutionListener attached = listener.attach(engine);

46

47

try (Context context = Context.newBuilder("js").engine(engine).build()) {

48

// All execution in this context will be monitored

49

context.eval("js", "function add(a, b) { return a + b; } add(2, 3);");

50

}

51

52

attached.close();

53

}

54

```

55

56

### Execution Events

57

58

Access detailed information about execution events.

59

60

```java { .api }

61

public final class ExecutionEvent {

62

public SourceSection getLocation();

63

public Value getReturnValue();

64

public RuntimeException getException();

65

public List<Value> getInputValues();

66

public boolean hasReturnValue();

67

public boolean hasException();

68

}

69

```

70

71

**Usage:**

72

73

```java

74

ExecutionListener listener = ExecutionListener.newBuilder()

75

.onEnter(event -> {

76

SourceSection location = event.getLocation();

77

System.out.println("Executing at " + location.getSource().getName() +

78

":" + location.getStartLine());

79

80

// Access input values (function parameters, etc.)

81

List<Value> inputs = event.getInputValues();

82

System.out.println("Input values: " + inputs);

83

})

84

.onReturn(event -> {

85

if (event.hasReturnValue()) {

86

Value returnValue = event.getReturnValue();

87

System.out.println("Returned: " + returnValue);

88

}

89

90

if (event.hasException()) {

91

RuntimeException exception = event.getException();

92

System.out.println("Exception: " + exception.getMessage());

93

}

94

})

95

.statements(true)

96

.build();

97

```

98

99

### Filtered Monitoring

100

101

Monitor specific sources or functions only.

102

103

```java

104

// Monitor only specific sources

105

ExecutionListener sourceFiltered = ExecutionListener.newBuilder()

106

.sourceFilter(source -> source.getName().endsWith(".js"))

107

.onEnter(event -> System.out.println("JS execution: " + event.getLocation()))

108

.statements(true)

109

.build();

110

111

// Monitor only specific function names

112

ExecutionListener functionFiltered = ExecutionListener.newBuilder()

113

.rootNameFilter(name -> name.equals("criticalFunction"))

114

.onEnter(event -> System.out.println("Critical function called"))

115

.roots(true)

116

.build();

117

118

// Monitor expressions only (no statements)

119

ExecutionListener expressionOnly = ExecutionListener.newBuilder()

120

.expressions(true)

121

.statements(false)

122

.onReturn(event -> {

123

if (event.hasReturnValue()) {

124

System.out.println("Expression result: " + event.getReturnValue());

125

}

126

})

127

.build();

128

```

129

130

## Advanced Monitoring Patterns

131

132

### Performance Profiling

133

134

Create custom profilers using execution monitoring:

135

136

```java

137

public class SimpleProfiler {

138

private final Map<String, Long> executionTimes = new ConcurrentHashMap<>();

139

private final Map<String, AtomicLong> callCounts = new ConcurrentHashMap<>();

140

private final ThreadLocal<Long> enterTime = new ThreadLocal<>();

141

142

public ExecutionListener createListener() {

143

return ExecutionListener.newBuilder()

144

.onEnter(event -> {

145

enterTime.set(System.nanoTime());

146

})

147

.onReturn(event -> {

148

long duration = System.nanoTime() - enterTime.get();

149

String location = getLocationKey(event.getLocation());

150

151

executionTimes.merge(location, duration, Long::sum);

152

callCounts.computeIfAbsent(location, k -> new AtomicLong(0)).incrementAndGet();

153

})

154

.statements(true)

155

.roots(true)

156

.build();

157

}

158

159

public void printProfile() {

160

System.out.println("Execution Profile:");

161

executionTimes.entrySet().stream()

162

.sorted(Map.Entry.<String, Long>comparingByValue().reversed())

163

.forEach(entry -> {

164

String location = entry.getKey();

165

long totalTime = entry.getValue();

166

long callCount = callCounts.get(location).get();

167

long avgTime = totalTime / callCount;

168

169

System.out.printf("%s: %d calls, %d ns total, %d ns avg%n",

170

location, callCount, totalTime, avgTime);

171

});

172

}

173

174

private String getLocationKey(SourceSection location) {

175

return location.getSource().getName() + ":" + location.getStartLine();

176

}

177

}

178

179

// Usage

180

SimpleProfiler profiler = new SimpleProfiler();

181

ExecutionListener listener = profiler.createListener();

182

183

try (Engine engine = Engine.create()) {

184

ExecutionListener attached = listener.attach(engine);

185

186

try (Context context = Context.newBuilder("js").engine(engine).build()) {

187

context.eval("js", "function fib(n) { return n < 2 ? n : fib(n-1) + fib(n-2); } fib(10);");

188

}

189

190

profiler.printProfile();

191

attached.close();

192

}

193

```

194

195

### Code Coverage Analysis

196

197

Track code coverage across polyglot execution:

198

199

```java

200

public class CoverageAnalyzer {

201

private final Set<String> executedLines = ConcurrentHashMap.newKeySet();

202

private final Map<String, Set<Integer>> sourceLines = new ConcurrentHashMap<>();

203

204

public ExecutionListener createListener() {

205

return ExecutionListener.newBuilder()

206

.onEnter(event -> {

207

SourceSection location = event.getLocation();

208

String sourceName = location.getSource().getName();

209

int lineNumber = location.getStartLine();

210

211

executedLines.add(sourceName + ":" + lineNumber);

212

213

// Track all lines in this source

214

sourceLines.computeIfAbsent(sourceName, k -> ConcurrentHashMap.newKeySet())

215

.add(lineNumber);

216

})

217

.statements(true)

218

.build();

219

}

220

221

public void printCoverage() {

222

System.out.println("Code Coverage Report:");

223

sourceLines.forEach((sourceName, lines) -> {

224

long totalLines = lines.size();

225

long executedCount = lines.stream()

226

.map(line -> sourceName + ":" + line)

227

.mapToLong(key -> executedLines.contains(key) ? 1 : 0)

228

.sum();

229

230

double coverage = (double) executedCount / totalLines * 100;

231

System.out.printf("%s: %.1f%% (%d/%d lines)%n",

232

sourceName, coverage, executedCount, totalLines);

233

});

234

}

235

}

236

```

237

238

### Exception Tracking

239

240

Monitor and analyze exceptions across polyglot execution:

241

242

```java

243

public class ExceptionTracker {

244

private final List<ExceptionInfo> exceptions = new CopyOnWriteArrayList<>();

245

246

public ExecutionListener createListener() {

247

return ExecutionListener.newBuilder()

248

.onReturn(event -> {

249

if (event.hasException()) {

250

RuntimeException exception = event.getException();

251

SourceSection location = event.getLocation();

252

253

exceptions.add(new ExceptionInfo(

254

exception.getClass().getSimpleName(),

255

exception.getMessage(),

256

location.getSource().getName(),

257

location.getStartLine(),

258

System.currentTimeMillis()

259

));

260

}

261

})

262

.statements(true)

263

.expressions(true)

264

.build();

265

}

266

267

public void printExceptionSummary() {

268

Map<String, Long> exceptionCounts = exceptions.stream()

269

.collect(Collectors.groupingBy(

270

ExceptionInfo::getType,

271

Collectors.counting()

272

));

273

274

System.out.println("Exception Summary:");

275

exceptionCounts.entrySet().stream()

276

.sorted(Map.Entry.<String, Long>comparingByValue().reversed())

277

.forEach(entry -> {

278

System.out.printf("%s: %d occurrences%n", entry.getKey(), entry.getValue());

279

});

280

}

281

282

private static class ExceptionInfo {

283

private final String type;

284

private final String message;

285

private final String source;

286

private final int line;

287

private final long timestamp;

288

289

// Constructor and getters...

290

}

291

}

292

```

293

294

### Real-time Monitoring

295

296

Create real-time monitoring dashboards:

297

298

```java

299

public class RealTimeMonitor {

300

private final AtomicLong executionCount = new AtomicLong(0);

301

private final AtomicLong exceptionCount = new AtomicLong(0);

302

private final ConcurrentHashMap<String, AtomicLong> languageStats = new ConcurrentHashMap<>();

303

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

304

305

public ExecutionListener createListener() {

306

// Start periodic reporting

307

scheduler.scheduleAtFixedRate(this::printStats, 0, 5, TimeUnit.SECONDS);

308

309

return ExecutionListener.newBuilder()

310

.onEnter(event -> {

311

executionCount.incrementAndGet();

312

313

String language = event.getLocation().getSource().getLanguage();

314

languageStats.computeIfAbsent(language, k -> new AtomicLong(0))

315

.incrementAndGet();

316

})

317

.onReturn(event -> {

318

if (event.hasException()) {

319

exceptionCount.incrementAndGet();

320

}

321

})

322

.statements(true)

323

.build();

324

}

325

326

private void printStats() {

327

System.out.println("=== Real-time Stats ===");

328

System.out.println("Total executions: " + executionCount.get());

329

System.out.println("Total exceptions: " + exceptionCount.get());

330

System.out.println("By language:");

331

languageStats.forEach((lang, count) -> {

332

System.out.println(" " + lang + ": " + count.get());

333

});

334

System.out.println();

335

}

336

337

public void shutdown() {

338

scheduler.shutdown();

339

}

340

}

341

```

342

343

### Multi-Context Monitoring

344

345

Monitor execution across multiple contexts:

346

347

```java

348

public class MultiContextMonitor {

349

private final Map<Context, String> contextNames = new ConcurrentHashMap<>();

350

private final Map<String, AtomicLong> contextStats = new ConcurrentHashMap<>();

351

352

public void registerContext(Context context, String name) {

353

contextNames.put(context, name);

354

contextStats.put(name, new AtomicLong(0));

355

}

356

357

public ExecutionListener createListener() {

358

return ExecutionListener.newBuilder()

359

.onEnter(event -> {

360

Context currentContext = Context.getCurrent();

361

String contextName = contextNames.get(currentContext);

362

if (contextName != null) {

363

contextStats.get(contextName).incrementAndGet();

364

}

365

})

366

.statements(true)

367

.build();

368

}

369

370

public void printContextStats() {

371

System.out.println("Context Execution Stats:");

372

contextStats.forEach((name, count) -> {

373

System.out.println(name + ": " + count.get() + " statements");

374

});

375

}

376

}

377

```

378

379

## Integration with Development Tools

380

381

### IDE Integration

382

383

Export execution data for IDE consumption:

384

385

```java

386

public class IDEIntegration {

387

public void exportExecutionTrace(List<ExecutionEvent> events, Path outputFile) {

388

try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(outputFile))) {

389

writer.println("timestamp,source,line,event_type,value");

390

391

events.forEach(event -> {

392

SourceSection location = event.getLocation();

393

writer.printf("%d,%s,%d,%s,%s%n",

394

System.currentTimeMillis(),

395

location.getSource().getName(),

396

location.getStartLine(),

397

event.hasReturnValue() ? "return" : "enter",

398

event.hasReturnValue() ? event.getReturnValue().toString() : ""

399

);

400

});

401

} catch (IOException e) {

402

throw new RuntimeException("Failed to export execution trace", e);

403

}

404

}

405

}

406

```

407

408

### Performance Testing

409

410

Integrate with performance testing frameworks:

411

412

```java

413

public class PerformanceTestIntegration {

414

public void runPerformanceTest(String testName, Runnable test) {

415

ExecutionListener listener = ExecutionListener.newBuilder()

416

.onEnter(event -> recordMetric("execution.enter", 1))

417

.onReturn(event -> {

418

recordMetric("execution.return", 1);

419

if (event.hasException()) {

420

recordMetric("execution.exception", 1);

421

}

422

})

423

.statements(true)

424

.build();

425

426

try (Engine engine = Engine.create()) {

427

ExecutionListener attached = listener.attach(engine);

428

429

long startTime = System.nanoTime();

430

test.run();

431

long duration = System.nanoTime() - startTime;

432

433

recordMetric("test.duration", duration);

434

attached.close();

435

}

436

}

437

438

private void recordMetric(String name, long value) {

439

// Integration with metrics collection system

440

// MetricsRegistry.record(name, value);

441

}

442

}

443

```

444

445

## Performance Considerations

446

447

- **Selective Monitoring**: Only monitor what you need; excessive monitoring can impact performance

448

- **Filtering**: Use source and root name filters to reduce monitoring overhead

449

- **Async Processing**: Process monitoring data asynchronously to minimize execution impact

450

- **Memory Management**: Be careful with data collection in long-running applications

451

- **Sampling**: Consider sampling for high-frequency applications

452

453

## Thread Safety

454

455

All monitoring components are thread-safe and can be used across multiple contexts and threads simultaneously. However, be careful with shared data structures and consider using concurrent collections for custom monitoring implementations.