StatsSink

class StatsSink(val maxLevel: TraceLevel = TraceLevel.Coroutine) : TraceSink(source)

A TraceSink that aggregates events into per-dispatcher DispatcherMetrics: counters, running and peak concurrency, queue-delay and run-time histograms, failures and distinct threads.

No locks and no extra dependencies. Per-label state lives in an immutable map held in an atomic reference and grown by compare-and-set (labels are few); inside each state every value is an atomic counter, a lock-free LatencyHistogram, a compare-and-set maximum, or an immutable set replaced by compare-and-set. emit is cheap, never blocks and ignores unknown event subtypes. Counters are exact under concurrency; a metrics read is not a single atomic cut across fields.

Thread tracking only grows for events that carry ThreadInfo and stops at 4096 distinct ids.

Example:

val stats = StatsSink()
val dispatchers = DefaultDispatcherProvider.traced(stats)
// ... run work ...
stats.metrics().forEach { println(it) }
stats.metrics("io")?.signals()?.forEach(::println)

Not automatically bounded in time: counters are cumulative until reset. Pair it with PoolSampler to observe evolution, or read metrics and signals.

Requires opting in to ExperimentalStructuredCoroutines.

Parameters

maxLevel

highest TraceLevel this sink accepts. Use TraceLevel.Coroutine (the default) to also count distinct threads.

See also

Constructors

Link copied to clipboard
constructor(maxLevel: TraceLevel = TraceLevel.Coroutine)

Properties

Link copied to clipboard

Functions

Link copied to clipboard
open override fun emit(event: TraceEvent)

Receives one event. See the contract in the type documentation.

Link copied to clipboard
open override fun isEnabled(level: TraceLevel): Boolean

Whether this sink wants events of level. Defaults to true for every level.

Link copied to clipboard

Returns the metrics of every observed dispatcher label, sorted by label. Empty when nothing was observed.

Returns the metrics of label, or null when no event with that label was observed.

Link copied to clipboard
fun reset()

Forgets everything observed so far. Not atomic with concurrent emit calls: events emitted while it runs may be lost or survive it, like RingBufferSink.clear.