Skip to content

add sample observer interface to improve observability with NewLocalReaderTrack - #970

Draft
haffi96 wants to merge 1 commit into
livekit:mainfrom
haffi96:observer-metrics
Draft

add sample observer interface to improve observability with NewLocalReaderTrack#970
haffi96 wants to merge 1 commit into
livekit:mainfrom
haffi96:observer-metrics

Conversation

@haffi96

@haffi96 haffi96 commented Aug 20, 2026

Copy link
Copy Markdown

This PR adds an optional, telemetry framework agnostic observer for the LocalTrack sample write loop.

Applications using NewLocalReaderTrack currently cannot observe the complete lifecycle of an encoded sample because reading, writing, and pacing happen inside the private writeWorker. The new observer exposes those lifecycle boundaries without requiring applications to duplicate the SDK’s reader, packetization, and pacing behavior.

Motivation

Applications publishing media from streaming sources often need to measure:

  • Samples read from the source
  • Sample sizes and source frame rate
  • Successful and failed WriteSample calls
  • Time between reading and writing a sample
  • Time spent inside WriteSample
  • Whether publishing is falling behind the intended media schedule
  • Samples skipped because a track is muted or disabled

Wrapping the source io.Reader is insufficient because reads do not correspond reliably to encoded frames. Implementing a custom SampleProvider exposes completed samples, but it cannot observe the subsequent WriteSample result or SDK pacing state.

The SDK’s writeWorker is the only location that has authoritative access to all three stages:

SampleProvider.NextSample
    → LocalTrack.WriteSample
    → frame pacing

Without a hook at this boundary, applications must reimplement significant portions of ReaderSampleProvider and the local-track write loop.

Design

The change deliberately does not introduce an OpenTelemetry or metrics dependency. Instead, it exposes a general-purpose synchronous observer which applications can connect to any telemetry implementation.

New SampleObserver interface

type SampleObserver interface {
    OnSampleRead(sample media.Sample, readCompletedAt time.Time)
    OnSampleWriteComplete(sample media.Sample, result SampleWriteResult)
    OnSamplePacingLag(sample media.Sample, lag time.Duration)
}

New SampleWriteResult

type SampleWriteResult struct {
    ReadCompletedAt  time.Time
    WriteStartedAt   time.Time
    WriteCompletedAt time.Time
    Err              error
    Skipped          bool
}

This provides enough information to calculate read-to-write latency and write duration without prescribing any particular telemetry system.

@haffi96 haffi96 changed the title add sample observer interface add sample observer interface to improve observability with NewLocalReaderTrack Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant