mirror of
https://github.com/pion/ice.git
synced 2025-09-26 19:41:11 +08:00
184 lines
5.7 KiB
Go
184 lines
5.7 KiB
Go
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package ice
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// GetCandidatePairsStats returns a list of candidate pair stats.
|
|
func (a *Agent) GetCandidatePairsStats() []CandidatePairStats {
|
|
var res []CandidatePairStats
|
|
err := a.loop.Run(a.loop, func(_ context.Context) {
|
|
result := make([]CandidatePairStats, 0, len(a.checklist))
|
|
for _, cp := range a.checklist {
|
|
stat := CandidatePairStats{
|
|
Timestamp: time.Now(),
|
|
LocalCandidateID: cp.Local.ID(),
|
|
RemoteCandidateID: cp.Remote.ID(),
|
|
State: cp.state,
|
|
Nominated: cp.nominated,
|
|
PacketsSent: cp.PacketsSent(),
|
|
PacketsReceived: cp.PacketsReceived(),
|
|
BytesSent: cp.BytesSent(),
|
|
BytesReceived: cp.BytesReceived(),
|
|
LastPacketSentTimestamp: cp.LastPacketSentAt(),
|
|
LastPacketReceivedTimestamp: cp.LastPacketReceivedAt(),
|
|
FirstRequestTimestamp: cp.FirstRequestSentAt(),
|
|
LastRequestTimestamp: cp.LastRequestSentAt(),
|
|
FirstResponseTimestamp: cp.FirstResponseReceivedAt(),
|
|
LastResponseTimestamp: cp.LastResponseReceivedAt(),
|
|
FirstRequestReceivedTimestamp: cp.FirstRequestReceivedAt(),
|
|
LastRequestReceivedTimestamp: cp.LastRequestReceivedAt(),
|
|
|
|
TotalRoundTripTime: cp.TotalRoundTripTime(),
|
|
CurrentRoundTripTime: cp.CurrentRoundTripTime(),
|
|
// AvailableOutgoingBitrate float64
|
|
// AvailableIncomingBitrate float64
|
|
// CircuitBreakerTriggerCount uint32
|
|
RequestsReceived: cp.RequestsReceived(),
|
|
RequestsSent: cp.RequestsSent(),
|
|
ResponsesReceived: cp.ResponsesReceived(),
|
|
ResponsesSent: cp.ResponsesSent(),
|
|
// RetransmissionsReceived uint64
|
|
// RetransmissionsSent uint64
|
|
// ConsentRequestsSent uint64
|
|
// ConsentExpiredTimestamp time.Time
|
|
}
|
|
result = append(result, stat)
|
|
}
|
|
res = result
|
|
})
|
|
if err != nil {
|
|
a.log.Errorf("Failed to get candidate pairs stats: %v", err)
|
|
|
|
return []CandidatePairStats{}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
// GetSelectedCandidatePairStats returns a candidate pair stats for selected candidate pair.
|
|
// Returns false if there is no selected pair.
|
|
func (a *Agent) GetSelectedCandidatePairStats() (CandidatePairStats, bool) {
|
|
isAvailable := false
|
|
var res CandidatePairStats
|
|
err := a.loop.Run(a.loop, func(_ context.Context) {
|
|
sp := a.getSelectedPair()
|
|
if sp == nil {
|
|
return
|
|
}
|
|
|
|
isAvailable = true
|
|
res = CandidatePairStats{
|
|
Timestamp: time.Now(),
|
|
LocalCandidateID: sp.Local.ID(),
|
|
RemoteCandidateID: sp.Remote.ID(),
|
|
State: sp.state,
|
|
Nominated: sp.nominated,
|
|
PacketsSent: sp.PacketsSent(),
|
|
PacketsReceived: sp.PacketsReceived(),
|
|
BytesSent: sp.BytesSent(),
|
|
BytesReceived: sp.BytesReceived(),
|
|
LastPacketSentTimestamp: sp.LastPacketSentAt(),
|
|
LastPacketReceivedTimestamp: sp.LastPacketReceivedAt(),
|
|
// FirstRequestTimestamp time.Time
|
|
// LastRequestTimestamp time.Time
|
|
// LastResponseTimestamp time.Time
|
|
TotalRoundTripTime: sp.TotalRoundTripTime(),
|
|
CurrentRoundTripTime: sp.CurrentRoundTripTime(),
|
|
// AvailableOutgoingBitrate float64
|
|
// AvailableIncomingBitrate float64
|
|
// CircuitBreakerTriggerCount uint32
|
|
// RequestsReceived uint64
|
|
// RequestsSent uint64
|
|
ResponsesReceived: sp.ResponsesReceived(),
|
|
// ResponsesSent uint64
|
|
// RetransmissionsReceived uint64
|
|
// RetransmissionsSent uint64
|
|
// ConsentRequestsSent uint64
|
|
// ConsentExpiredTimestamp time.Time
|
|
}
|
|
})
|
|
if err != nil {
|
|
a.log.Errorf("Failed to get selected candidate pair stats: %v", err)
|
|
|
|
return CandidatePairStats{}, false
|
|
}
|
|
|
|
return res, isAvailable
|
|
}
|
|
|
|
// GetLocalCandidatesStats returns a list of local candidates stats.
|
|
func (a *Agent) GetLocalCandidatesStats() []CandidateStats {
|
|
var res []CandidateStats
|
|
err := a.loop.Run(a.loop, func(_ context.Context) {
|
|
result := make([]CandidateStats, 0, len(a.localCandidates))
|
|
for networkType, localCandidates := range a.localCandidates {
|
|
for _, cand := range localCandidates {
|
|
relayProtocol := ""
|
|
if cand.Type() == CandidateTypeRelay {
|
|
if cRelay, ok := cand.(*CandidateRelay); ok {
|
|
relayProtocol = cRelay.RelayProtocol()
|
|
}
|
|
}
|
|
stat := CandidateStats{
|
|
Timestamp: time.Now(),
|
|
ID: cand.ID(),
|
|
NetworkType: networkType,
|
|
IP: cand.Address(),
|
|
Port: cand.Port(),
|
|
CandidateType: cand.Type(),
|
|
Priority: cand.Priority(),
|
|
// URL string
|
|
RelayProtocol: relayProtocol,
|
|
// Deleted bool
|
|
}
|
|
result = append(result, stat)
|
|
}
|
|
}
|
|
res = result
|
|
})
|
|
if err != nil {
|
|
a.log.Errorf("Failed to get candidate pair stats: %v", err)
|
|
|
|
return []CandidateStats{}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
// GetRemoteCandidatesStats returns a list of remote candidates stats.
|
|
func (a *Agent) GetRemoteCandidatesStats() []CandidateStats {
|
|
var res []CandidateStats
|
|
err := a.loop.Run(a.loop, func(_ context.Context) {
|
|
result := make([]CandidateStats, 0, len(a.remoteCandidates))
|
|
for networkType, remoteCandidates := range a.remoteCandidates {
|
|
for _, c := range remoteCandidates {
|
|
stat := CandidateStats{
|
|
Timestamp: time.Now(),
|
|
ID: c.ID(),
|
|
NetworkType: networkType,
|
|
IP: c.Address(),
|
|
Port: c.Port(),
|
|
CandidateType: c.Type(),
|
|
Priority: c.Priority(),
|
|
// URL string
|
|
RelayProtocol: "",
|
|
}
|
|
result = append(result, stat)
|
|
}
|
|
}
|
|
res = result
|
|
})
|
|
if err != nil {
|
|
a.log.Errorf("Failed to get candidate pair stats: %v", err)
|
|
|
|
return []CandidateStats{}
|
|
}
|
|
|
|
return res
|
|
}
|