Skip to content

Commit

Permalink
Add Req/Res count/time to candidate stats (#3043)
Browse files Browse the repository at this point in the history
  • Loading branch information
cnderrauber authored Feb 27, 2025
1 parent 44062a7 commit dae0af9
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 61 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.20
require (
github.com/pion/datachannel v1.5.10
github.com/pion/dtls/v3 v3.0.4
github.com/pion/ice/v4 v4.0.6
github.com/pion/ice/v4 v4.0.7
github.com/pion/interceptor v0.1.37
github.com/pion/logging v0.2.3
github.com/pion/randutil v0.1.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk
github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M=
github.com/pion/dtls/v3 v3.0.4 h1:44CZekewMzfrn9pmGrj5BNnTMDCFwr+6sLH+cCuLM7U=
github.com/pion/dtls/v3 v3.0.4/go.mod h1:R373CsjxWqNPf6MEkfdy3aSe9niZvL/JaKlGeFphtMg=
github.com/pion/ice/v4 v4.0.6 h1:jmM9HwI9lfetQV/39uD0nY4y++XZNPhvzIPCb8EwxUM=
github.com/pion/ice/v4 v4.0.6/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw=
github.com/pion/ice/v4 v4.0.7 h1:mnwuT3n3RE/9va41/9QJqN5+Bhc0H/x/ZyiVlWMw35M=
github.com/pion/ice/v4 v4.0.7/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw=
github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI=
github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y=
github.com/pion/logging v0.2.3 h1:gHuf0zpoh1GW67Nr6Gj4cv5Z9ZscU7g/EaoC/Ke/igI=
Expand Down
67 changes: 41 additions & 26 deletions stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -2041,32 +2041,35 @@ func toICECandidatePairStats(candidatePairStats ice.CandidatePairStats) (ICECand
Type: StatsTypeCandidatePair,
ID: newICECandidatePairStatsID(candidatePairStats.LocalCandidateID, candidatePairStats.RemoteCandidateID),
// TransportID:
LocalCandidateID: candidatePairStats.LocalCandidateID,
RemoteCandidateID: candidatePairStats.RemoteCandidateID,
State: state,
Nominated: candidatePairStats.Nominated,
PacketsSent: candidatePairStats.PacketsSent,
PacketsReceived: candidatePairStats.PacketsReceived,
BytesSent: candidatePairStats.BytesSent,
BytesReceived: candidatePairStats.BytesReceived,
LastPacketSentTimestamp: statsTimestampFrom(candidatePairStats.LastPacketSentTimestamp),
LastPacketReceivedTimestamp: statsTimestampFrom(candidatePairStats.LastPacketReceivedTimestamp),
FirstRequestTimestamp: statsTimestampFrom(candidatePairStats.FirstRequestTimestamp),
LastRequestTimestamp: statsTimestampFrom(candidatePairStats.LastRequestTimestamp),
LastResponseTimestamp: statsTimestampFrom(candidatePairStats.LastResponseTimestamp),
TotalRoundTripTime: candidatePairStats.TotalRoundTripTime,
CurrentRoundTripTime: candidatePairStats.CurrentRoundTripTime,
AvailableOutgoingBitrate: candidatePairStats.AvailableOutgoingBitrate,
AvailableIncomingBitrate: candidatePairStats.AvailableIncomingBitrate,
CircuitBreakerTriggerCount: candidatePairStats.CircuitBreakerTriggerCount,
RequestsReceived: candidatePairStats.RequestsReceived,
RequestsSent: candidatePairStats.RequestsSent,
ResponsesReceived: candidatePairStats.ResponsesReceived,
ResponsesSent: candidatePairStats.ResponsesSent,
RetransmissionsReceived: candidatePairStats.RetransmissionsReceived,
RetransmissionsSent: candidatePairStats.RetransmissionsSent,
ConsentRequestsSent: candidatePairStats.ConsentRequestsSent,
ConsentExpiredTimestamp: statsTimestampFrom(candidatePairStats.ConsentExpiredTimestamp),
LocalCandidateID: candidatePairStats.LocalCandidateID,
RemoteCandidateID: candidatePairStats.RemoteCandidateID,
State: state,
Nominated: candidatePairStats.Nominated,
PacketsSent: candidatePairStats.PacketsSent,
PacketsReceived: candidatePairStats.PacketsReceived,
BytesSent: candidatePairStats.BytesSent,
BytesReceived: candidatePairStats.BytesReceived,
LastPacketSentTimestamp: statsTimestampFrom(candidatePairStats.LastPacketSentTimestamp),
LastPacketReceivedTimestamp: statsTimestampFrom(candidatePairStats.LastPacketReceivedTimestamp),
FirstRequestTimestamp: statsTimestampFrom(candidatePairStats.FirstRequestTimestamp),
LastRequestTimestamp: statsTimestampFrom(candidatePairStats.LastRequestTimestamp),
FirstResponseTimestamp: statsTimestampFrom(candidatePairStats.FirstResponseTimestamp),
LastResponseTimestamp: statsTimestampFrom(candidatePairStats.LastResponseTimestamp),
FirstRequestReceivedTimestamp: statsTimestampFrom(candidatePairStats.FirstRequestReceivedTimestamp),
LastRequestReceivedTimestamp: statsTimestampFrom(candidatePairStats.LastRequestReceivedTimestamp),
TotalRoundTripTime: candidatePairStats.TotalRoundTripTime,
CurrentRoundTripTime: candidatePairStats.CurrentRoundTripTime,
AvailableOutgoingBitrate: candidatePairStats.AvailableOutgoingBitrate,
AvailableIncomingBitrate: candidatePairStats.AvailableIncomingBitrate,
CircuitBreakerTriggerCount: candidatePairStats.CircuitBreakerTriggerCount,
RequestsReceived: candidatePairStats.RequestsReceived,
RequestsSent: candidatePairStats.RequestsSent,
ResponsesReceived: candidatePairStats.ResponsesReceived,
ResponsesSent: candidatePairStats.ResponsesSent,
RetransmissionsReceived: candidatePairStats.RetransmissionsReceived,
RetransmissionsSent: candidatePairStats.RetransmissionsSent,
ConsentRequestsSent: candidatePairStats.ConsentRequestsSent,
ConsentExpiredTimestamp: statsTimestampFrom(candidatePairStats.ConsentExpiredTimestamp),
}, nil
}

Expand Down Expand Up @@ -2163,10 +2166,22 @@ type ICECandidatePairStats struct {
// (LastRequestTimestamp - FirstRequestTimestamp) / RequestsSent.
LastRequestTimestamp StatsTimestamp `json:"lastRequestTimestamp"`

// FirstResponseTimestamp represents the timestamp at which the first STUN response
// was received on this particular candidate pair.
FirstResponseTimestamp StatsTimestamp `json:"firstResponseTimestamp"`

// LastResponseTimestamp represents the timestamp at which the last STUN response
// was received on this particular candidate pair.
LastResponseTimestamp StatsTimestamp `json:"lastResponseTimestamp"`

// FirstRequestReceivedTimestamp represents the timestamp at which the first
// connectivity check request was received.
FirstRequestReceivedTimestamp StatsTimestamp `json:"firstRequestReceivedTimestamp"`

// LastRequestReceivedTimestamp represents the timestamp at which the last
// connectivity check request was received.
LastRequestReceivedTimestamp StatsTimestamp `json:"lastRequestReceivedTimestamp"`

// TotalRoundTripTime represents the sum of all round trip time measurements
// in seconds since the beginning of the session, based on STUN connectivity
// check responses (ResponsesReceived), including those that reply to requests
Expand Down
70 changes: 38 additions & 32 deletions stats_go_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -853,38 +853,41 @@ func getStatsSamples() []statSample { //nolint:cyclop,maintidx
}
`
iceCandidatePairStats := ICECandidatePairStats{
Timestamp: 1688978831527.718,
Type: StatsTypeCandidatePair,
ID: "CPxIhBDNnT_LlMJOnBv",
TransportID: "T01",
LocalCandidateID: "IxIhBDNnT",
RemoteCandidateID: "ILlMJOnBv",
State: "waiting",
Nominated: true,
PacketsSent: 1,
PacketsReceived: 2,
BytesSent: 3,
BytesReceived: 4,
LastPacketSentTimestamp: 5,
LastPacketReceivedTimestamp: 6,
FirstRequestTimestamp: 7,
LastRequestTimestamp: 8,
LastResponseTimestamp: 9,
TotalRoundTripTime: 10,
CurrentRoundTripTime: 11,
AvailableOutgoingBitrate: 12,
AvailableIncomingBitrate: 13,
CircuitBreakerTriggerCount: 14,
RequestsReceived: 15,
RequestsSent: 16,
ResponsesReceived: 17,
ResponsesSent: 18,
RetransmissionsReceived: 19,
RetransmissionsSent: 20,
ConsentRequestsSent: 21,
ConsentExpiredTimestamp: 22,
PacketsDiscardedOnSend: 23,
BytesDiscardedOnSend: 24,
Timestamp: 1688978831527.718,
Type: StatsTypeCandidatePair,
ID: "CPxIhBDNnT_LlMJOnBv",
TransportID: "T01",
LocalCandidateID: "IxIhBDNnT",
RemoteCandidateID: "ILlMJOnBv",
State: "waiting",
Nominated: true,
PacketsSent: 1,
PacketsReceived: 2,
BytesSent: 3,
BytesReceived: 4,
LastPacketSentTimestamp: 5,
LastPacketReceivedTimestamp: 6,
FirstRequestTimestamp: 7,
LastRequestTimestamp: 8,
FirstResponseTimestamp: 9,
LastResponseTimestamp: 9,
FirstRequestReceivedTimestamp: 9,
LastRequestReceivedTimestamp: 9,
TotalRoundTripTime: 10,
CurrentRoundTripTime: 11,
AvailableOutgoingBitrate: 12,
AvailableIncomingBitrate: 13,
CircuitBreakerTriggerCount: 14,
RequestsReceived: 15,
RequestsSent: 16,
ResponsesReceived: 17,
ResponsesSent: 18,
RetransmissionsReceived: 19,
RetransmissionsSent: 20,
ConsentRequestsSent: 21,
ConsentExpiredTimestamp: 22,
PacketsDiscardedOnSend: 23,
BytesDiscardedOnSend: 24,
}
iceCandidatePairStatsJSON := `
{
Expand All @@ -904,7 +907,10 @@ func getStatsSamples() []statSample { //nolint:cyclop,maintidx
"lastPacketReceivedTimestamp": 6,
"firstRequestTimestamp": 7,
"lastRequestTimestamp": 8,
"firstResponseTimestamp": 9,
"lastResponseTimestamp": 9,
"firstRequestReceivedTimestamp": 9,
"lastRequestReceivedTimestamp": 9,
"totalRoundTripTime": 10,
"currentRoundTripTime": 11,
"availableOutgoingBitrate": 12,
Expand Down

0 comments on commit dae0af9

Please sign in to comment.