Skip to content

trace #

Description

trace records manual spans using the monotonic clock. Create a tracer with new_tracer(), open a span with tracer.span(name), and call span.end() when the operation finishes. The same span instance ignores repeated end() calls; copies have independent completion state and should not both be ended. A span records the thread where it started, even if ended elsewhere.

report() returns per-name counts and total, average, and maximum durations in nanoseconds, sorted by total duration. to_chrome_trace() exports completed spans as Chrome trace-event JSON for Perfetto or Chrome tracing, with microsecond timestamps and durations. event_count() counts completed spans. reset() clears recorded events and aggregates; spans that remain open can still record when ended.

The tracer synchronizes its shared aggregates and event log. A span instance itself must be ended by one caller at a time. The log retains every completed event until reset and does not perform sampling or allocation tracking.

fn new_tracer #

fn new_tracer() &Tracer

new_tracer creates an empty Tracer.

struct Span #

struct Span {
mut:
	tracer &Tracer = unsafe { nil }
	name   string
	start  u64
	tid    u64
	ended  bool
}

Span is one open measurement. End each instance exactly once; repeating end on the same instance is a safe no-op. Copies have independent completion state. Spans are values, so nesting is the caller's structure and needs no thread-local stack: concurrent spans from any threads aggregate by name under the tracer mutex.

fn (Span) end #

fn (mut s Span) end()

end closes the measurement, attributing the elapsed time to its name.

struct SpanReport #

struct SpanReport {
pub:
	name   string
	count  u64
	total  u64
	avg_ns f64
	max_ns u64
}

SpanReport is one row of Tracer.report, sorted by total time descending.

struct SpanStats #

struct SpanStats {
mut:
	count    u64
	total_ns u64
	max_ns   u64
}

SpanStats aggregates one span name: how often it ran and how long it took, in nanoseconds of the monotonic clock.

struct Tracer #

@[heap]
struct Tracer {
mut:
	mutex  &sync.Mutex
	stats  map[string]SpanStats
	events []TraceEvent
}

Tracer collects explicitly instrumented spans (Tracy-zones style) across threads: name aggregates plus a Chrome-trace event log viewable in Perfetto or chrome://tracing. It answers "where is my server spending time" at function granularity. Kernel-level sampling is deliberately out of scope here (it needs a signal/sampler design of its own).

fn (Tracer) span #

fn (mut t Tracer) span(name string) Span

span opens a measurement with the monotonic clock.

fn (Tracer) report #

fn (t &Tracer) report() []SpanReport

report returns per-name aggregates sorted by total time descending.

fn (Tracer) event_count #

fn (t &Tracer) event_count() int

event_count returns the number of recorded trace events.

fn (Tracer) reset #

fn (mut t Tracer) reset()

reset drops all aggregates and events.

fn (Tracer) to_chrome_trace #

fn (t &Tracer) to_chrome_trace() string

to_chrome_trace renders the event log in Chrome trace-event JSON: {"traceEvents": [{"name":...,"ph":"X","ts":us,"dur":us,"tid":..}, ...]}.