Selkie--Trace
NAME
Selkie::Trace - runtime span tracing (Chrome Trace JSON / slow-span JSONL)
SYNOPSIS
Selkie::Trace.init(mode => 'trace', trace-path => $path);
my $span = Selkie::Trace.enabled
?? Selkie::Trace.start('widget.render', cat => 'render',
args => %(rows => 4))
!! Nil;
# ... work ...
$span.finish(ok => True) with $span;
Selkie::Trace.shutdown; # drains + writes the JSON tailDESCRIPTION
Three modes: off (default ā .enabled is a state-var check and .start returns the type object), slow (synchronous JSONL of spans over their threshold ā cheap enough for day-to-day use), and trace (complete Chrome Trace capture ā every span, for deliberate profiling sessions only).
In trace mode, events are enqueued lock-free on a Channel and a dedicated writer thread owns all JSON serialization and file I/O, so span capture on hot paths costs an arg snapshot + a channel send, not a file write. shutdown/reset close the channel, join the writer, and only then append the JSON tail ā the file is complete and valid once shutdown returns. Producers racing shutdown lose their events (sends on the closed channel are swallowed), which is the intended "capture ends now" semantic.
Span discipline
Create spans after any cheap early-return guard, never before: a method whose common case is a no-op (an idempotent destroy, an already-loaded load) must not emit an event that records nothing ā per-frame no-op spans dominated a real capture at 27 events/frame before this rule.
sub drain-trace-writer
sub drain-trace-writer() returns NilClose the channel and join the writer so every queued event is on disk, leaving the handle ready for the JSON tail. Callers hold $lock. Idempotent.