Dev debug info (#50)

This commit is contained in:
David Colburn
2021-07-13 14:05:25 -05:00
committed by GitHub
parent 0cf6efdae9
commit 5fdb6361cd
8 changed files with 184 additions and 3 deletions

2
go.mod
View File

@@ -43,4 +43,4 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)
replace github.com/pion/ion-sfu => github.com/livekit/ion-sfu v1.20.0
replace github.com/pion/ion-sfu => github.com/livekit/ion-sfu v1.20.2

4
go.sum
View File

@@ -231,8 +231,8 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/lithammer/shortuuid/v3 v3.0.6 h1:pr15YQyvhiSX/qPxncFtqk+v4xLEpOZObbsY/mKrcvA=
github.com/lithammer/shortuuid/v3 v3.0.6/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
github.com/livekit/ion-sfu v1.20.0 h1:mLNunMgRF6+Bz+5/JrVgxQKE6umuN3vkkQu8IcVquYA=
github.com/livekit/ion-sfu v1.20.0/go.mod h1:Wx6b4qGUjvSo1kGl+/fHl0ZF48g2IJOjzUFg0yCo9qY=
github.com/livekit/ion-sfu v1.20.2 h1:fIvKl2biQUbIdVPgWgGaMXo8e3s9E9ActCvD5lSlVJo=
github.com/livekit/ion-sfu v1.20.2/go.mod h1:Wx6b4qGUjvSo1kGl+/fHl0ZF48g2IJOjzUFg0yCo9qY=
github.com/livekit/protocol v0.5.6 h1:vMUjYvJH2TD/WIjrXtG6aQl5fFrIj0/ZgIctQqmmwro=
github.com/livekit/protocol v0.5.6/go.mod h1:wo3CGfYB7XMF8GoVJAfTARrYSP/ombi+sbLl6AYdKP0=
github.com/lucsky/cuid v1.0.2 h1:z4XlExeoderxoPj2/dxKOyPxe9RCOu7yNq9/XWxIUMQ=

View File

@@ -373,3 +373,32 @@ func (t *MediaTrack) sendDownTrackBindingReports(sub types.Participant) {
}
}()
}
func (t *MediaTrack) DebugInfo() map[string]interface{} {
info := map[string]interface{}{
"ID": t.ID(),
"SSRC": t.ssrc,
"Kind": t.kind.String(),
"PubMuted": t.muted.Get(),
}
subscribedTrackInfo := make([]map[string]interface{}, 0)
t.lock.RLock()
for _, track := range t.subscribedTracks {
dt := track.dt.DebugInfo()
dt["PubMuted"] = track.pubMuted.Get()
dt["SubMuted"] = track.subMuted.Get()
subscribedTrackInfo = append(subscribedTrackInfo, dt)
}
t.lock.RUnlock()
info["DownTracks"] = subscribedTrackInfo
if t.receiver != nil {
receiverInfo := t.receiver.DebugInfo()
for k, v := range receiverInfo {
info[k] = v
}
}
return info
}

View File

@@ -964,3 +964,52 @@ func (p *ParticipantImpl) rtcpSendWorker() {
}
}
}
func (p *ParticipantImpl) DebugInfo() map[string]interface{} {
info := map[string]interface{}{
"ID": p.id,
"State": p.State().String(),
}
publishedTrackInfo := make(map[string]interface{})
subscribedTrackInfo := make(map[string]interface{})
pendingTrackInfo := make(map[string]interface{})
p.lock.RLock()
for trackID, track := range p.publishedTracks {
if mt, ok := track.(*MediaTrack); ok {
publishedTrackInfo[trackID] = mt.DebugInfo()
} else {
publishedTrackInfo[trackID] = map[string]interface{}{
"ID": track.ID(),
"Kind": track.Kind().String(),
"PubMuted": track.IsMuted(),
}
}
}
for pubID, tracks := range p.subscribedTracks {
trackInfo := make([]map[string]interface{}, 0, len(tracks))
for _, track := range tracks {
dt := track.DownTrack().DebugInfo()
dt["SubMuted"] = track.IsMuted()
trackInfo = append(trackInfo, dt)
}
subscribedTrackInfo[pubID] = trackInfo
}
for clientID, track := range p.pendingTracks {
pendingTrackInfo[clientID] = map[string]interface{}{
"Sid": track.Sid,
"Type": track.Type.String(),
"Simulcast": track.Simulcast,
}
}
p.lock.RUnlock()
info["PublishedTracks"] = publishedTrackInfo
info["SubscribedTracks"] = subscribedTrackInfo
info["PendingTracks"] = pendingTrackInfo
return info
}

View File

@@ -580,3 +580,20 @@ func (r *Room) audioUpdateWorker() {
time.Sleep(time.Duration(r.audioConfig.UpdateInterval) * time.Millisecond)
}
}
func (r *Room) DebugInfo() map[string]interface{} {
info := map[string]interface{}{
"Name": r.Room.Name,
"Sid": r.Room.Sid,
"CreatedAt": r.Room.CreationTime,
}
participants := r.GetParticipants()
participantInfo := make(map[string]interface{})
for _, p := range participants {
participantInfo[p.Identity()] = p.DebugInfo()
}
info["Participants"] = participantInfo
return info
}

View File

@@ -78,6 +78,8 @@ type Participant interface {
RemoveSubscribedTrack(participantId string, st SubscribedTrack)
SubscriberPC() *webrtc.PeerConnection
UpdateAfterActive() bool
DebugInfo() map[string]interface{}
}
// PublishedTrack is the main interface representing a track published to the room

View File

@@ -89,6 +89,16 @@ type FakeParticipant struct {
connectedAtReturnsOnCall map[int]struct {
result1 time.Time
}
DebugInfoStub func() map[string]interface{}
debugInfoMutex sync.RWMutex
debugInfoArgsForCall []struct {
}
debugInfoReturns struct {
result1 map[string]interface{}
}
debugInfoReturnsOnCall map[int]struct {
result1 map[string]interface{}
}
GetAudioLevelStub func() (uint8, bool)
getAudioLevelMutex sync.RWMutex
getAudioLevelArgsForCall []struct {
@@ -788,6 +798,59 @@ func (fake *FakeParticipant) ConnectedAtReturnsOnCall(i int, result1 time.Time)
}{result1}
}
func (fake *FakeParticipant) DebugInfo() map[string]interface{} {
fake.debugInfoMutex.Lock()
ret, specificReturn := fake.debugInfoReturnsOnCall[len(fake.debugInfoArgsForCall)]
fake.debugInfoArgsForCall = append(fake.debugInfoArgsForCall, struct {
}{})
stub := fake.DebugInfoStub
fakeReturns := fake.debugInfoReturns
fake.recordInvocation("DebugInfo", []interface{}{})
fake.debugInfoMutex.Unlock()
if stub != nil {
return stub()
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeParticipant) DebugInfoCallCount() int {
fake.debugInfoMutex.RLock()
defer fake.debugInfoMutex.RUnlock()
return len(fake.debugInfoArgsForCall)
}
func (fake *FakeParticipant) DebugInfoCalls(stub func() map[string]interface{}) {
fake.debugInfoMutex.Lock()
defer fake.debugInfoMutex.Unlock()
fake.DebugInfoStub = stub
}
func (fake *FakeParticipant) DebugInfoReturns(result1 map[string]interface{}) {
fake.debugInfoMutex.Lock()
defer fake.debugInfoMutex.Unlock()
fake.DebugInfoStub = nil
fake.debugInfoReturns = struct {
result1 map[string]interface{}
}{result1}
}
func (fake *FakeParticipant) DebugInfoReturnsOnCall(i int, result1 map[string]interface{}) {
fake.debugInfoMutex.Lock()
defer fake.debugInfoMutex.Unlock()
fake.DebugInfoStub = nil
if fake.debugInfoReturnsOnCall == nil {
fake.debugInfoReturnsOnCall = make(map[int]struct {
result1 map[string]interface{}
})
}
fake.debugInfoReturnsOnCall[i] = struct {
result1 map[string]interface{}
}{result1}
}
func (fake *FakeParticipant) GetAudioLevel() (uint8, bool) {
fake.getAudioLevelMutex.Lock()
ret, specificReturn := fake.getAudioLevelReturnsOnCall[len(fake.getAudioLevelArgsForCall)]
@@ -2430,6 +2493,8 @@ func (fake *FakeParticipant) Invocations() map[string][][]interface{} {
defer fake.closeMutex.RUnlock()
fake.connectedAtMutex.RLock()
defer fake.connectedAtMutex.RUnlock()
fake.debugInfoMutex.RLock()
defer fake.debugInfoMutex.RUnlock()
fake.getAudioLevelMutex.RLock()
defer fake.getAudioLevelMutex.RUnlock()
fake.getPublishedTracksMutex.RLock()

View File

@@ -2,6 +2,7 @@ package service
import (
"context"
"encoding/json"
"errors"
"fmt"
"net"
@@ -73,6 +74,7 @@ func NewLivekitServer(conf *config.Config,
mux.HandleFunc("/", s.healthCheck)
if conf.Development {
mux.HandleFunc("/debug/goroutine", s.debugGoroutines)
mux.HandleFunc("/debug/rooms", s.debugInfo)
}
s.httpServer = &http.Server{
@@ -222,6 +224,23 @@ func (s *LivekitServer) debugGoroutines(w http.ResponseWriter, r *http.Request)
_ = pprof.Lookup("goroutine").WriteTo(w, 2)
}
func (s *LivekitServer) debugInfo(w http.ResponseWriter, r *http.Request) {
s.roomManager.lock.RLock()
info := make([]map[string]interface{}, 0, len(s.roomManager.rooms))
for _, room := range s.roomManager.rooms {
info = append(info, room.DebugInfo())
}
s.roomManager.lock.RUnlock()
b, err := json.Marshal(info)
if err != nil {
w.WriteHeader(400)
_, _ = w.Write([]byte(err.Error()))
} else {
_, _ = w.Write(b)
}
}
func (s *LivekitServer) healthCheck(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}