Use microseconds for forwarding stats. (#3943)

Latency is always 0, but jitter is high.
Not sure how that happens as latency is the welford mean and jitter is
welford standard deviation. Feels like some mis-labeling.

Anyhow, switching to microseconds units to get better resolution.
This commit is contained in:
Raja Subramanian
2025-09-23 02:28:19 +05:30
committed by GitHub
parent 856e0871bc
commit 6a41fae548
2 changed files with 10 additions and 17 deletions
+8 -16
View File
@@ -1,14 +1,12 @@
package sfu
import (
"fmt"
"sync"
"time"
"go.uber.org/atomic"
"github.com/livekit/livekit-server/pkg/telemetry/prometheus"
"github.com/livekit/protocol/logger"
"github.com/livekit/protocol/utils"
)
@@ -46,25 +44,19 @@ func (s *ForwardStats) Update(arrival, left int64) {
s.latency.Update(time.Duration(arrival), float64(transit))
}
func (s *ForwardStats) GetStats() (latency, jitter time.Duration) {
func (s *ForwardStats) GetStats() (time.Duration, time.Duration) {
s.lock.Lock()
w := s.latency.Summarize()
s.lock.Unlock()
latency, jitter = time.Duration(w.Mean()), time.Duration(w.StdDev())
// TODO: remove this check after debugging unexpected jitter issue
if jitter > 10*time.Second {
logger.Infow("unexpected forward jitter",
"jitter", jitter,
"stats", fmt.Sprintf("count %.2f, mean %.2f, stdDev %.2f", w.Count(), w.Mean(), w.StdDev()),
)
}
return
return time.Duration(w.Mean()), time.Duration(w.StdDev())
}
func (s *ForwardStats) GetLastStats(duration time.Duration) (latency, jitter time.Duration) {
func (s *ForwardStats) GetLastStats(duration time.Duration) (time.Duration, time.Duration) {
s.lock.Lock()
defer s.lock.Unlock()
w := s.latency.SummarizeLast(duration)
s.lock.Unlock()
return time.Duration(w.Mean()), time.Duration(w.StdDev())
}
@@ -82,8 +74,8 @@ func (s *ForwardStats) report(reportInterval time.Duration) {
case <-ticker.C:
latency, jitter := s.GetLastStats(reportInterval)
latencySlow, jitterSlow := s.GetStats()
prometheus.RecordForwardJitter(uint32(jitter/time.Millisecond), uint32(jitterSlow/time.Millisecond))
prometheus.RecordForwardLatency(uint32(latency/time.Millisecond), uint32(latencySlow/time.Millisecond))
prometheus.RecordForwardJitter(uint32(jitter.Microseconds()), uint32(jitterSlow.Microseconds()))
prometheus.RecordForwardLatency(uint32(latency.Microseconds()), uint32(latencySlow.Microseconds()))
}
}
}
+2 -1
View File
@@ -29,6 +29,7 @@ import (
"github.com/livekit/protocol/livekit"
"github.com/livekit/protocol/logger"
"github.com/livekit/protocol/utils"
"github.com/livekit/protocol/utils/mono"
"github.com/livekit/livekit-server/pkg/sfu/audio"
"github.com/livekit/livekit-server/pkg/sfu/buffer"
@@ -826,7 +827,7 @@ func (w *WebRTCReceiver) forwardRTP(layer int32, buff *buffer.Buffer) {
// track delay/jitter
if writeCount > 0 && w.forwardStats != nil {
w.forwardStats.Update(pkt.Arrival, time.Now().UnixNano())
w.forwardStats.Update(pkt.Arrival, mono.UnixNano())
}
// track video layers