api: add RTSP reported lost packets (#5198) (#5579)

The new outboundRtpPacketsReportedLost property allows to track RTP
packets that have been reported lost by readers. Furthermore, stats now
have a "inbound" or "outbound" prefix to improve readability.
This commit is contained in:
Alessandro Ros
2026-03-16 22:10:18 +01:00
committed by GitHub
parent 9a485119ec
commit dfce20fefa
16 changed files with 530 additions and 175 deletions
+51
View File
@@ -1126,12 +1126,20 @@ components:
nullable: true
tunnel:
type: string
inboundBytes:
type: integer
format: uint64
outboundBytes:
type: integer
format: uint64
bytesReceived:
type: integer
format: uint64
deprecated: true
bytesSent:
type: integer
format: uint64
deprecated: true
RTSPConnList:
type: object
@@ -1176,36 +1184,79 @@ components:
items:
type: string
format: uuid
inboundBytes:
type: integer
format: uint64
inboundRTPPackets:
type: integer
format: uint64
inboundRTPPacketsLost:
type: integer
format: uint64
inboundRTPPacketsInError:
type: integer
format: uint64
inboundRTPPacketsJitter:
type: number
format: double
inboundRTCPPackets:
type: integer
format: uint64
inboundRTCPPacketsInError:
type: integer
format: uint64
outboundBytes:
type: integer
format: uint64
outboundRTPPackets:
type: integer
format: uint64
outboundRTPPacketsReportedLost:
type: integer
format: uint64
outboundRTCPPackets:
type: integer
format: uint64
bytesReceived:
type: integer
format: uint64
deprecated: true
bytesSent:
type: integer
format: uint64
deprecated: true
rtpPacketsReceived:
type: integer
format: uint64
deprecated: true
rtpPacketsSent:
type: integer
format: uint64
deprecated: true
rtpPacketsLost:
type: integer
format: uint64
deprecated: true
rtpPacketsInError:
type: integer
format: uint64
deprecated: true
rtpPacketsJitter:
type: number
format: double
deprecated: true
rtcpPacketsReceived:
type: integer
format: uint64
deprecated: true
rtcpPacketsSent:
type: integer
format: uint64
deprecated: true
rtcpPacketsInError:
type: integer
format: uint64
deprecated: true
RTSPSessionList:
type: object
+2 -2
View File
@@ -12,7 +12,7 @@ require (
github.com/asticode/go-astits v1.15.0
github.com/bluenviron/gohlslib/v2 v2.2.8
github.com/bluenviron/gortmplib v0.3.0
github.com/bluenviron/gortsplib/v5 v5.4.0
github.com/bluenviron/gortsplib/v5 v5.4.1-0.20260316202619-e63876e33be9
github.com/bluenviron/mediacommon/v2 v2.8.2
github.com/datarhei/gosrt v0.10.0
github.com/fsnotify/fsnotify v1.9.0
@@ -96,7 +96,7 @@ require (
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
golang.org/x/arch v0.22.0 // indirect
golang.org/x/net v0.51.0 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/text v0.35.0 // indirect
golang.org/x/time v0.12.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect
+4 -4
View File
@@ -37,8 +37,8 @@ github.com/bluenviron/gohlslib/v2 v2.2.8 h1:+KueZeydRDciIq2t3fwT4pshqN+Vreu4c2IM
github.com/bluenviron/gohlslib/v2 v2.2.8/go.mod h1:c4b9vKhyksO6fHhWdCpuuczxUNFeZtBahlFiwrvW2oA=
github.com/bluenviron/gortmplib v0.3.0 h1:jBNl7bYtXSq+USx70gQ4kzRsffM1h0XRjGwlHQHZVq8=
github.com/bluenviron/gortmplib v0.3.0/go.mod h1:3tUsWceMOrs8Ylt5UyQEHNHCVl52V1gi9tz+IaLTafI=
github.com/bluenviron/gortsplib/v5 v5.4.0 h1:xi9G4NU67+5uNxGZzJP87SwyaWKr+rUAzbIkOE2SQBo=
github.com/bluenviron/gortsplib/v5 v5.4.0/go.mod h1:+vGoi2RqF8LA7ktls7nC0JIF3DmOHwj0448kdQGYBEQ=
github.com/bluenviron/gortsplib/v5 v5.4.1-0.20260316202619-e63876e33be9 h1:BSz3Mt+1AqqFtB0zaScPCf3lrHr9L8aQ4XtBFWgrcxU=
github.com/bluenviron/gortsplib/v5 v5.4.1-0.20260316202619-e63876e33be9/go.mod h1:4K3mXlLQ3vN4AyQKtxQE8T5I0Fr1KTNanBCzxDBJKug=
github.com/bluenviron/mediacommon/v2 v2.8.2 h1:ZHuxthfO8o4/fhlG6JvoK5lT27tMWw4k5efpJlpu0yE=
github.com/bluenviron/mediacommon/v2 v2.8.2/go.mod h1:4AsE74EnTxkHeUs1VMER31fivU0jufZUAepaKFRV1lM=
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
@@ -261,8 +261,8 @@ golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
+100 -54
View File
@@ -89,6 +89,8 @@ func TestRTSPConnsList(t *testing.T) {
ID: id1,
Created: now,
RemoteAddr: "192.168.1.1:5000",
InboundBytes: 1000,
OutboundBytes: 2000,
BytesReceived: 1000,
BytesSent: 2000,
Session: &sessionID,
@@ -98,6 +100,8 @@ func TestRTSPConnsList(t *testing.T) {
ID: id2,
Created: now.Add(time.Minute),
RemoteAddr: "192.168.1.2:5001",
InboundBytes: 500,
OutboundBytes: 1500,
BytesReceived: 500,
BytesSent: 1500,
Session: nil,
@@ -175,6 +179,8 @@ func TestRTSPConnsGet(t *testing.T) {
ID: id,
Created: now,
RemoteAddr: "192.168.1.100:5000",
InboundBytes: 999999,
OutboundBytes: 888888,
BytesReceived: 999999,
BytesSent: 888888,
Session: &sessionID,
@@ -219,6 +225,8 @@ func TestRTSPConnsGet(t *testing.T) {
require.Equal(t, id, out.ID)
require.Equal(t, "192.168.1.100:5000", out.RemoteAddr)
require.Equal(t, uint64(999999), out.InboundBytes)
require.Equal(t, uint64(888888), out.OutboundBytes)
require.Equal(t, uint64(999999), out.BytesReceived)
require.NotNil(t, out.Session)
require.Equal(t, sessionID, *out.Session)
@@ -253,44 +261,66 @@ func TestRTSPSessionsList(t *testing.T) {
rtspServer := &testRTSPServer{
sessions: map[uuid.UUID]*defs.APIRTSPSession{
id1: {
ID: id1,
Created: now,
RemoteAddr: "192.168.1.1:5000",
State: defs.APIRTSPSessionStatePublish,
Path: "stream1",
Query: "token=abc",
Transport: &transport,
Profile: &profile,
BytesReceived: 1000,
BytesSent: 2000,
RTPPacketsReceived: 100,
RTPPacketsSent: 200,
RTPPacketsLost: 5,
RTPPacketsInError: 2,
RTPPacketsJitter: 0.5,
RTCPPacketsReceived: 10,
RTCPPacketsSent: 15,
RTCPPacketsInError: 1,
ID: id1,
Created: now,
RemoteAddr: "192.168.1.1:5000",
State: defs.APIRTSPSessionStatePublish,
Path: "stream1",
Query: "token=abc",
Transport: &transport,
Profile: &profile,
InboundBytes: 1000,
InboundRTPPackets: 100,
InboundRTPPacketsLost: 5,
InboundRTPPacketsInError: 2,
InboundRTPPacketsJitter: 0.5,
InboundRTCPPackets: 10,
InboundRTCPPacketsInError: 1,
OutboundBytes: 2000,
OutboundRTPPackets: 200,
OutboundRTPPacketsReportedLost: 7,
OutboundRTCPPackets: 15,
BytesReceived: 1000,
BytesSent: 2000,
RTPPacketsReceived: 100,
RTPPacketsSent: 200,
RTPPacketsLost: 5,
RTPPacketsInError: 2,
RTPPacketsJitter: 0.5,
RTCPPacketsReceived: 10,
RTCPPacketsSent: 15,
RTCPPacketsInError: 1,
},
id2: {
ID: id2,
Created: now.Add(time.Minute),
RemoteAddr: "192.168.1.2:5001",
State: defs.APIRTSPSessionStateRead,
Path: "stream2",
Query: "",
Transport: nil,
Profile: nil,
BytesReceived: 500,
BytesSent: 1500,
RTPPacketsReceived: 50,
RTPPacketsSent: 150,
RTPPacketsLost: 0,
RTPPacketsInError: 0,
RTPPacketsJitter: 0.1,
RTCPPacketsReceived: 5,
RTCPPacketsSent: 10,
RTCPPacketsInError: 0,
ID: id2,
Created: now.Add(time.Minute),
RemoteAddr: "192.168.1.2:5001",
State: defs.APIRTSPSessionStateRead,
Path: "stream2",
Query: "",
Transport: nil,
Profile: nil,
InboundBytes: 500,
InboundRTPPackets: 50,
InboundRTPPacketsLost: 0,
InboundRTPPacketsInError: 0,
InboundRTPPacketsJitter: 0.1,
InboundRTCPPackets: 5,
InboundRTCPPacketsInError: 0,
OutboundBytes: 1500,
OutboundRTPPackets: 150,
OutboundRTPPacketsReportedLost: 0,
OutboundRTCPPackets: 10,
BytesReceived: 500,
BytesSent: 1500,
RTPPacketsReceived: 50,
RTPPacketsSent: 150,
RTPPacketsLost: 0,
RTPPacketsInError: 0,
RTPPacketsJitter: 0.1,
RTCPPacketsReceived: 5,
RTCPPacketsSent: 10,
RTCPPacketsInError: 0,
},
},
}
@@ -362,24 +392,35 @@ func TestRTSPSessionsGet(t *testing.T) {
rtspServer := &testRTSPServer{
sessions: map[uuid.UUID]*defs.APIRTSPSession{
id: {
ID: id,
Created: now,
RemoteAddr: "192.168.1.100:5000",
State: defs.APIRTSPSessionStatePublish,
Path: "mystream",
Query: "key=value",
Transport: &transport,
Profile: &profile,
BytesReceived: 999999,
BytesSent: 888888,
RTPPacketsReceived: 10000,
RTPPacketsSent: 20000,
RTPPacketsLost: 50,
RTPPacketsInError: 10,
RTPPacketsJitter: 1.5,
RTCPPacketsReceived: 100,
RTCPPacketsSent: 200,
RTCPPacketsInError: 5,
ID: id,
Created: now,
RemoteAddr: "192.168.1.100:5000",
State: defs.APIRTSPSessionStatePublish,
Path: "mystream",
Query: "key=value",
Transport: &transport,
Profile: &profile,
InboundBytes: 999999,
InboundRTPPackets: 10000,
InboundRTPPacketsLost: 50,
InboundRTPPacketsInError: 10,
InboundRTPPacketsJitter: 1.5,
InboundRTCPPackets: 100,
InboundRTCPPacketsInError: 5,
OutboundBytes: 888888,
OutboundRTPPackets: 20000,
OutboundRTPPacketsReportedLost: 25,
OutboundRTCPPackets: 200,
BytesReceived: 999999,
BytesSent: 888888,
RTPPacketsReceived: 10000,
RTPPacketsSent: 20000,
RTPPacketsLost: 50,
RTPPacketsInError: 10,
RTPPacketsJitter: 1.5,
RTCPPacketsReceived: 100,
RTCPPacketsSent: 200,
RTCPPacketsInError: 5,
},
},
}
@@ -422,6 +463,11 @@ func TestRTSPSessionsGet(t *testing.T) {
require.Equal(t, "192.168.1.100:5000", out.RemoteAddr)
require.Equal(t, defs.APIRTSPSessionStatePublish, out.State)
require.Equal(t, "mystream", out.Path)
require.Equal(t, uint64(999999), out.InboundBytes)
require.Equal(t, uint64(888888), out.OutboundBytes)
require.Equal(t, uint64(10000), out.InboundRTPPackets)
require.Equal(t, uint64(20000), out.OutboundRTPPackets)
require.Equal(t, uint64(25), out.OutboundRTPPacketsReportedLost)
require.Equal(t, uint64(999999), out.BytesReceived)
require.NotNil(t, out.Transport)
require.Equal(t, "UDP", *out.Transport)
+66 -40
View File
@@ -623,6 +623,8 @@ func TestAPIProtocolListGet(t *testing.T) {
"itemCount": float64(1),
"items": []any{
map[string]any{
"inboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundBytes"],
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
@@ -640,26 +642,37 @@ func TestAPIProtocolListGet(t *testing.T) {
"itemCount": float64(1),
"items": []any{
map[string]any{
"bytesReceived": float64(0),
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
"id": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["id"],
"path": "mypath",
"query": "key=val",
"user": "",
"remoteAddr": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["remoteAddr"],
"state": "publish",
"transport": "UDP",
"profile": "AVP",
"rtpPacketsReceived": float64(0),
"rtpPacketsSent": float64(0),
"rtpPacketsLost": float64(0),
"rtpPacketsInError": float64(0),
"rtpPacketsJitter": float64(0),
"rtcpPacketsReceived": float64(0),
"rtcpPacketsSent": float64(0),
"rtcpPacketsInError": float64(0),
"conns": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["conns"],
"inboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundBytes"],
"inboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTPPackets"],
"inboundRTPPacketsLost": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTPPacketsLost"],
"inboundRTPPacketsInError": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTPPacketsInError"],
"inboundRTPPacketsJitter": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTPPacketsJitter"],
"inboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTCPPackets"],
"inboundRTCPPacketsInError": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTCPPacketsInError"],
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
"outboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"],
"outboundRTPPacketsReportedLost": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsReportedLost"],
"outboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"],
"bytesReceived": float64(0),
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
"id": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["id"],
"path": "mypath",
"query": "key=val",
"user": "",
"remoteAddr": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["remoteAddr"],
"state": "publish",
"transport": "UDP",
"profile": "AVP",
"rtpPacketsReceived": float64(0),
"rtpPacketsSent": float64(0),
"rtpPacketsLost": float64(0),
"rtpPacketsInError": float64(0),
"rtpPacketsJitter": float64(0),
"rtcpPacketsReceived": float64(0),
"rtcpPacketsSent": float64(0),
"rtcpPacketsInError": float64(0),
"conns": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["conns"],
},
},
}, out1)
@@ -670,6 +683,8 @@ func TestAPIProtocolListGet(t *testing.T) {
"itemCount": float64(1),
"items": []any{
map[string]any{
"inboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundBytes"],
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
@@ -687,26 +702,37 @@ func TestAPIProtocolListGet(t *testing.T) {
"itemCount": float64(1),
"items": []any{
map[string]any{
"bytesReceived": float64(0),
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
"id": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["id"],
"path": "mypath",
"query": "key=val",
"user": "",
"remoteAddr": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["remoteAddr"],
"state": "publish",
"transport": "UDP",
"profile": "SAVP",
"rtpPacketsReceived": float64(0),
"rtpPacketsSent": float64(0),
"rtpPacketsLost": float64(0),
"rtpPacketsInError": float64(0),
"rtpPacketsJitter": float64(0),
"rtcpPacketsReceived": float64(0),
"rtcpPacketsSent": float64(0),
"rtcpPacketsInError": float64(0),
"conns": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["conns"],
"inboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundBytes"],
"inboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTPPackets"],
"inboundRTPPacketsLost": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTPPacketsLost"],
"inboundRTPPacketsInError": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTPPacketsInError"],
"inboundRTPPacketsJitter": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTPPacketsJitter"],
"inboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTCPPackets"],
"inboundRTCPPacketsInError": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundRTCPPacketsInError"],
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
"outboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"],
"outboundRTPPacketsReportedLost": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsReportedLost"],
"outboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"],
"bytesReceived": float64(0),
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
"id": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["id"],
"path": "mypath",
"query": "key=val",
"user": "",
"remoteAddr": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["remoteAddr"],
"state": "publish",
"transport": "UDP",
"profile": "SAVP",
"rtpPacketsReceived": float64(0),
"rtpPacketsSent": float64(0),
"rtpPacketsLost": float64(0),
"rtpPacketsInError": float64(0),
"rtpPacketsJitter": float64(0),
"rtcpPacketsReceived": float64(0),
"rtcpPacketsSent": float64(0),
"rtcpPacketsInError": float64(0),
"conns": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["conns"],
},
},
}, out1)
+54
View File
@@ -82,9 +82,22 @@ paths_readers 0
hls_muxers 0
hls_muxers_bytes_sent 0
rtsp_conns 0
rtsp_conns_inbound_bytes 0
rtsp_conns_outbound_bytes 0
rtsp_conns_bytes_received 0
rtsp_conns_bytes_sent 0
rtsp_sessions 0
rtsp_sessions_inbound_bytes 0
rtsp_sessions_inbound_rtp_packets 0
rtsp_sessions_inbound_rtp_packets_lost 0
rtsp_sessions_inbound_rtp_packets_in_error 0
rtsp_sessions_inbound_rtp_packets_jitter 0
rtsp_sessions_inbound_rtcp_packets 0
rtsp_sessions_inbound_rtcp_packets_in_error 0
rtsp_sessions_outbound_bytes 0
rtsp_sessions_outbound_rtp_packets 0
rtsp_sessions_outbound_rtp_packets_reported_lost 0
rtsp_sessions_outbound_rtcp_packets 0
rtsp_sessions_bytes_received 0
rtsp_sessions_bytes_sent 0
rtsp_sessions_rtp_packets_received 0
@@ -96,9 +109,22 @@ rtsp_sessions_rtcp_packets_received 0
rtsp_sessions_rtcp_packets_sent 0
rtsp_sessions_rtcp_packets_in_error 0
rtsps_conns 0
rtsps_conns_inbound_bytes 0
rtsps_conns_outbound_bytes 0
rtsps_conns_bytes_received 0
rtsps_conns_bytes_sent 0
rtsps_sessions 0
rtsps_sessions_inbound_bytes 0
rtsps_sessions_inbound_rtp_packets 0
rtsps_sessions_inbound_rtp_packets_lost 0
rtsps_sessions_inbound_rtp_packets_in_error 0
rtsps_sessions_inbound_rtp_packets_jitter 0
rtsps_sessions_inbound_rtcp_packets 0
rtsps_sessions_inbound_rtcp_packets_in_error 0
rtsps_sessions_outbound_bytes 0
rtsps_sessions_outbound_rtp_packets 0
rtsps_sessions_outbound_rtp_packets_reported_lost 0
rtsps_sessions_outbound_rtcp_packets 0
rtsps_sessions_bytes_received 0
rtsps_sessions_bytes_sent 0
rtsps_sessions_rtp_packets_received 0
@@ -395,9 +421,23 @@ webrtc_sessions_rtcp_packets_sent 0
`hls_muxers\{name=".*?"\} 1`+"\n"+
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
`rtsp_conns\{id=".*?"\} 1`+"\n"+
`rtsp_conns_inbound_bytes\{id=".*?"\} [0-9]+`+"\n"+
`rtsp_conns_outbound_bytes\{id=".*?"\} [0-9]+`+"\n"+
`rtsp_conns_bytes_received\{id=".*?"\} [0-9]+`+"\n"+
`rtsp_conns_bytes_sent\{id=".*?"\} [0-9]+`+"\n"+
`rtsp_sessions\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
`rtsp_sessions_inbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_inbound_rtp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_inbound_rtp_packets_lost\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_inbound_rtp_packets_in_error\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_inbound_rtp_packets_jitter\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_inbound_rtcp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_inbound_rtcp_packets_in_error\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_outbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_outbound_rtp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_outbound_rtp_packets_reported_lost\{id=".*?",path=".*?",`+
`remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_outbound_rtcp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_bytes_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 0`+"\n"+
`rtsp_sessions_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_rtp_packets_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
@@ -409,9 +449,23 @@ webrtc_sessions_rtcp_packets_sent 0
`rtsp_sessions_rtcp_packets_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsp_sessions_rtcp_packets_in_error\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_conns\{id=".*?"\} 1`+"\n"+
`rtsps_conns_inbound_bytes\{id=".*?"\} [0-9]+`+"\n"+
`rtsps_conns_outbound_bytes\{id=".*?"\} [0-9]+`+"\n"+
`rtsps_conns_bytes_received\{id=".*?"\} [0-9]+`+"\n"+
`rtsps_conns_bytes_sent\{id=".*?"\} [0-9]+`+"\n"+
`rtsps_sessions\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
`rtsps_sessions_inbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_inbound_rtp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_inbound_rtp_packets_lost\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_inbound_rtp_packets_in_error\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_inbound_rtp_packets_jitter\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_inbound_rtcp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_inbound_rtcp_packets_in_error\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_outbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_outbound_rtp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_outbound_rtp_packets_reported_lost\{id=".*?",path=".*?",`+
`remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_outbound_rtcp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_bytes_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 0`+"\n"+
`rtsps_sessions_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
`rtsps_sessions_rtp_packets_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
+2 -2
View File
@@ -665,13 +665,13 @@ func (pa *path) doAPIPathsGet(req pathAPIPathsGetReq) {
if !pa.isAvailable() {
return 0
}
return pa.stream.BytesReceived()
return pa.stream.InboundBytes()
}(),
BytesSent: func() uint64 {
if !pa.isAvailable() {
return 0
}
return pa.stream.BytesSent()
return pa.stream.OutboundBytes()
}(),
Readers: func() []defs.APIPathReader {
ret := make([]defs.APIPathReader, len(pa.readers))
+35 -22
View File
@@ -22,8 +22,10 @@ type APIRTSPConn struct {
RemoteAddr string `json:"remoteAddr"`
Session *uuid.UUID `json:"session"`
Tunnel string `json:"tunnel"`
BytesReceived uint64 `json:"bytesReceived"`
BytesSent uint64 `json:"bytesSent"`
InboundBytes uint64 `json:"inboundBytes"`
OutboundBytes uint64 `json:"outboundBytes"`
BytesReceived uint64 `json:"bytesReceived" deprecated:"true"`
BytesSent uint64 `json:"bytesSent" deprecated:"true"`
}
// APIRTSPConnsList is a list of RTSP connections.
@@ -45,26 +47,37 @@ const (
// APIRTSPSession is a RTSP session.
type APIRTSPSession struct {
ID uuid.UUID `json:"id"`
Created time.Time `json:"created"`
RemoteAddr string `json:"remoteAddr"`
State APIRTSPSessionState `json:"state"`
Path string `json:"path"`
Query string `json:"query"`
User string `json:"user"`
Transport *string `json:"transport"`
Profile *string `json:"profile"`
Conns []uuid.UUID `json:"conns"`
BytesReceived uint64 `json:"bytesReceived"`
BytesSent uint64 `json:"bytesSent"`
RTPPacketsReceived uint64 `json:"rtpPacketsReceived"`
RTPPacketsSent uint64 `json:"rtpPacketsSent"`
RTPPacketsLost uint64 `json:"rtpPacketsLost"`
RTPPacketsInError uint64 `json:"rtpPacketsInError"`
RTPPacketsJitter float64 `json:"rtpPacketsJitter"`
RTCPPacketsReceived uint64 `json:"rtcpPacketsReceived"`
RTCPPacketsSent uint64 `json:"rtcpPacketsSent"`
RTCPPacketsInError uint64 `json:"rtcpPacketsInError"`
ID uuid.UUID `json:"id"`
Created time.Time `json:"created"`
RemoteAddr string `json:"remoteAddr"`
State APIRTSPSessionState `json:"state"`
Path string `json:"path"`
Query string `json:"query"`
User string `json:"user"`
Transport *string `json:"transport"`
Profile *string `json:"profile"`
Conns []uuid.UUID `json:"conns"`
InboundBytes uint64 `json:"inboundBytes"`
InboundRTPPackets uint64 `json:"inboundRTPPackets"`
InboundRTPPacketsLost uint64 `json:"inboundRTPPacketsLost"`
InboundRTPPacketsInError uint64 `json:"inboundRTPPacketsInError"`
InboundRTPPacketsJitter float64 `json:"inboundRTPPacketsJitter"`
InboundRTCPPackets uint64 `json:"inboundRTCPPackets"`
InboundRTCPPacketsInError uint64 `json:"inboundRTCPPacketsInError"`
OutboundBytes uint64 `json:"outboundBytes"`
OutboundRTPPackets uint64 `json:"outboundRTPPackets"`
OutboundRTPPacketsReportedLost uint64 `json:"outboundRTPPacketsReportedLost"`
OutboundRTCPPackets uint64 `json:"outboundRTCPPackets"`
BytesReceived uint64 `json:"bytesReceived" deprecated:"true"`
BytesSent uint64 `json:"bytesSent" deprecated:"true"`
RTPPacketsReceived uint64 `json:"rtpPacketsReceived" deprecated:"true"`
RTPPacketsSent uint64 `json:"rtpPacketsSent" deprecated:"true"`
RTPPacketsLost uint64 `json:"rtpPacketsLost" deprecated:"true"`
RTPPacketsInError uint64 `json:"rtpPacketsInError" deprecated:"true"`
RTPPacketsJitter float64 `json:"rtpPacketsJitter" deprecated:"true"`
RTCPPacketsReceived uint64 `json:"rtcpPacketsReceived" deprecated:"true"`
RTCPPacketsSent uint64 `json:"rtcpPacketsSent" deprecated:"true"`
RTCPPacketsInError uint64 `json:"rtcpPacketsInError" deprecated:"true"`
}
// APIRTSPSessionList is a list of RTSP sessions.
+60
View File
@@ -268,12 +268,18 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
"id": i.ID.String(),
})
out += metric("rtsp_conns", ta, 1)
out += metric("rtsp_conns_inbound_bytes", ta, int64(i.InboundBytes))
out += metric("rtsp_conns_outbound_bytes", ta, int64(i.OutboundBytes))
// deprecated
out += metric("rtsp_conns_bytes_received", ta, int64(i.BytesReceived))
out += metric("rtsp_conns_bytes_sent", ta, int64(i.BytesSent))
}
}
} else if rtspConnFilter == "" {
out += metric("rtsp_conns", "", 0)
out += metric("rtsp_conns_inbound_bytes", "", 0)
out += metric("rtsp_conns_outbound_bytes", "", 0)
// deprecated
out += metric("rtsp_conns_bytes_received", "", 0)
out += metric("rtsp_conns_bytes_sent", "", 0)
}
@@ -292,6 +298,18 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
"remoteAddr": i.RemoteAddr,
})
out += metric("rtsp_sessions", ta, 1)
out += metric("rtsp_sessions_inbound_bytes", ta, int64(i.InboundBytes))
out += metric("rtsp_sessions_inbound_rtp_packets", ta, int64(i.InboundRTPPackets))
out += metric("rtsp_sessions_inbound_rtp_packets_lost", ta, int64(i.InboundRTPPacketsLost))
out += metric("rtsp_sessions_inbound_rtp_packets_in_error", ta, int64(i.InboundRTPPacketsInError))
out += metricFloat("rtsp_sessions_inbound_rtp_packets_jitter", ta, i.InboundRTPPacketsJitter)
out += metric("rtsp_sessions_inbound_rtcp_packets", ta, int64(i.InboundRTCPPackets))
out += metric("rtsp_sessions_inbound_rtcp_packets_in_error", ta, int64(i.InboundRTCPPacketsInError))
out += metric("rtsp_sessions_outbound_bytes", ta, int64(i.OutboundBytes))
out += metric("rtsp_sessions_outbound_rtp_packets", ta, int64(i.OutboundRTPPackets))
out += metric("rtsp_sessions_outbound_rtp_packets_reported_lost", ta, int64(i.OutboundRTPPacketsReportedLost))
out += metric("rtsp_sessions_outbound_rtcp_packets", ta, int64(i.OutboundRTCPPackets))
// deprecated
out += metric("rtsp_sessions_bytes_received", ta, int64(i.BytesReceived))
out += metric("rtsp_sessions_bytes_sent", ta, int64(i.BytesSent))
out += metric("rtsp_sessions_rtp_packets_received", ta, int64(i.RTPPacketsReceived))
@@ -306,6 +324,18 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
}
} else if rtspSessionFilter == "" {
out += metric("rtsp_sessions", "", 0)
out += metric("rtsp_sessions_inbound_bytes", "", 0)
out += metric("rtsp_sessions_inbound_rtp_packets", "", 0)
out += metric("rtsp_sessions_inbound_rtp_packets_lost", "", 0)
out += metric("rtsp_sessions_inbound_rtp_packets_in_error", "", 0)
out += metricFloat("rtsp_sessions_inbound_rtp_packets_jitter", "", 0)
out += metric("rtsp_sessions_inbound_rtcp_packets", "", 0)
out += metric("rtsp_sessions_inbound_rtcp_packets_in_error", "", 0)
out += metric("rtsp_sessions_outbound_bytes", "", 0)
out += metric("rtsp_sessions_outbound_rtp_packets", "", 0)
out += metric("rtsp_sessions_outbound_rtp_packets_reported_lost", "", 0)
out += metric("rtsp_sessions_outbound_rtcp_packets", "", 0)
// deprecated
out += metric("rtsp_sessions_bytes_received", "", 0)
out += metric("rtsp_sessions_bytes_sent", "", 0)
out += metric("rtsp_sessions_rtp_packets_received", "", 0)
@@ -331,12 +361,18 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
"id": i.ID.String(),
})
out += metric("rtsps_conns", ta, 1)
out += metric("rtsps_conns_inbound_bytes", ta, int64(i.InboundBytes))
out += metric("rtsps_conns_outbound_bytes", ta, int64(i.OutboundBytes))
// deprecated
out += metric("rtsps_conns_bytes_received", ta, int64(i.BytesReceived))
out += metric("rtsps_conns_bytes_sent", ta, int64(i.BytesSent))
}
}
} else if rtspsConnFilter == "" {
out += metric("rtsps_conns", "", 0)
out += metric("rtsps_conns_inbound_bytes", "", 0)
out += metric("rtsps_conns_outbound_bytes", "", 0)
// deprecated
out += metric("rtsps_conns_bytes_received", "", 0)
out += metric("rtsps_conns_bytes_sent", "", 0)
}
@@ -355,6 +391,18 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
"remoteAddr": i.RemoteAddr,
})
out += metric("rtsps_sessions", ta, 1)
out += metric("rtsps_sessions_inbound_bytes", ta, int64(i.InboundBytes))
out += metric("rtsps_sessions_inbound_rtp_packets", ta, int64(i.InboundRTPPackets))
out += metric("rtsps_sessions_inbound_rtp_packets_lost", ta, int64(i.InboundRTPPacketsLost))
out += metric("rtsps_sessions_inbound_rtp_packets_in_error", ta, int64(i.InboundRTPPacketsInError))
out += metricFloat("rtsps_sessions_inbound_rtp_packets_jitter", ta, i.InboundRTPPacketsJitter)
out += metric("rtsps_sessions_inbound_rtcp_packets", ta, int64(i.InboundRTCPPackets))
out += metric("rtsps_sessions_inbound_rtcp_packets_in_error", ta, int64(i.InboundRTCPPacketsInError))
out += metric("rtsps_sessions_outbound_bytes", ta, int64(i.OutboundBytes))
out += metric("rtsps_sessions_outbound_rtp_packets", ta, int64(i.OutboundRTPPackets))
out += metric("rtsps_sessions_outbound_rtp_packets_reported_lost", ta, int64(i.OutboundRTPPacketsReportedLost))
out += metric("rtsps_sessions_outbound_rtcp_packets", ta, int64(i.OutboundRTCPPackets))
// deprecated
out += metric("rtsps_sessions_bytes_received", ta, int64(i.BytesReceived))
out += metric("rtsps_sessions_bytes_sent", ta, int64(i.BytesSent))
out += metric("rtsps_sessions_rtp_packets_received", ta, int64(i.RTPPacketsReceived))
@@ -369,6 +417,18 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
}
} else if rtspsSessionFilter == "" {
out += metric("rtsps_sessions", "", 0)
out += metric("rtsps_sessions_inbound_bytes", "", 0)
out += metric("rtsps_sessions_inbound_rtp_packets", "", 0)
out += metric("rtsps_sessions_inbound_rtp_packets_lost", "", 0)
out += metric("rtsps_sessions_inbound_rtp_packets_in_error", "", 0)
out += metricFloat("rtsps_sessions_inbound_rtp_packets_jitter", "", 0)
out += metric("rtsps_sessions_inbound_rtcp_packets", "", 0)
out += metric("rtsps_sessions_inbound_rtcp_packets_in_error", "", 0)
out += metric("rtsps_sessions_outbound_bytes", "", 0)
out += metric("rtsps_sessions_outbound_rtp_packets", "", 0)
out += metric("rtsps_sessions_outbound_rtp_packets_reported_lost", "", 0)
out += metric("rtsps_sessions_outbound_rtcp_packets", "", 0)
// deprecated
out += metric("rtsps_sessions_bytes_received", "", 0)
out += metric("rtsps_sessions_bytes_sent", "", 0)
out += metric("rtsps_sessions_rtp_packets_received", "", 0)
+102 -17
View File
@@ -83,6 +83,8 @@ func (dummyRTSPServer) APIConnsList() (*defs.APIRTSPConnsList, error) {
ID: uuid.MustParse("18294761-f9d1-4ea9-9a35-fe265b62eb41"),
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
RemoteAddr: "124.5.5.5:34542",
InboundBytes: 123,
OutboundBytes: 456,
BytesReceived: 123,
BytesSent: 456,
Session: nil,
@@ -99,23 +101,34 @@ func (dummyRTSPServer) APISessionsList() (*defs.APIRTSPSessionList, error) {
ItemCount: 1,
PageCount: 1,
Items: []defs.APIRTSPSession{{
ID: uuid.MustParse("124b22ce-9c34-4387-b045-44caf98049f7"),
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
RemoteAddr: "124.5.5.5:34542",
State: defs.APIRTSPSessionStatePublish,
Path: "mypath",
Query: "myquery",
Transport: nil,
BytesReceived: 123,
BytesSent: 456,
RTPPacketsReceived: 789,
RTPPacketsSent: 123,
RTPPacketsLost: 456,
RTPPacketsInError: 789,
RTPPacketsJitter: 123,
RTCPPacketsReceived: 456,
RTCPPacketsSent: 789,
RTCPPacketsInError: 456,
ID: uuid.MustParse("124b22ce-9c34-4387-b045-44caf98049f7"),
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
RemoteAddr: "124.5.5.5:34542",
State: defs.APIRTSPSessionStatePublish,
Path: "mypath",
Query: "myquery",
Transport: nil,
InboundBytes: 123,
InboundRTPPackets: 789,
InboundRTPPacketsLost: 456,
InboundRTPPacketsInError: 789,
InboundRTPPacketsJitter: 123,
InboundRTCPPackets: 456,
InboundRTCPPacketsInError: 456,
OutboundBytes: 456,
OutboundRTPPackets: 123,
OutboundRTPPacketsReportedLost: 321,
OutboundRTCPPackets: 789,
BytesReceived: 123,
BytesSent: 456,
RTPPacketsReceived: 789,
RTPPacketsSent: 123,
RTPPacketsLost: 456,
RTPPacketsInError: 789,
RTPPacketsJitter: 123,
RTCPPacketsReceived: 456,
RTCPPacketsSent: 789,
RTCPPacketsInError: 456,
}},
}, nil
}
@@ -281,10 +294,34 @@ func TestMetrics(t *testing.T) {
`hls_muxers{name="mypath"} 1`+"\n"+
`hls_muxers_bytes_sent{name="mypath"} 789`+"\n"+
`rtsp_conns{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 1`+"\n"+
`rtsp_conns_inbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`+"\n"+
`rtsp_conns_outbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 456`+"\n"+
`rtsp_conns_bytes_received{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`+"\n"+
`rtsp_conns_bytes_sent{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 456`+"\n"+
`rtsp_sessions{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 1`+"\n"+
`rtsp_sessions_inbound_bytes{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsp_sessions_inbound_rtp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsp_sessions_inbound_rtp_packets_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsp_sessions_inbound_rtp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsp_sessions_inbound_rtp_packets_jitter{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsp_sessions_inbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsp_sessions_inbound_rtcp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsp_sessions_outbound_bytes{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsp_sessions_outbound_rtp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsp_sessions_outbound_rtp_packets_reported_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 321`+"\n"+
`rtsp_sessions_outbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsp_sessions_bytes_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsp_sessions_bytes_sent{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
@@ -306,10 +343,34 @@ func TestMetrics(t *testing.T) {
`rtsp_sessions_rtcp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsps_conns{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 1`+"\n"+
`rtsps_conns_inbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`+"\n"+
`rtsps_conns_outbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 456`+"\n"+
`rtsps_conns_bytes_received{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`+"\n"+
`rtsps_conns_bytes_sent{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 456`+"\n"+
`rtsps_sessions{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 1`+"\n"+
`rtsps_sessions_inbound_bytes{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsps_sessions_inbound_rtp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsps_sessions_inbound_rtp_packets_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsps_sessions_inbound_rtp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsps_sessions_inbound_rtp_packets_jitter{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsps_sessions_inbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsps_sessions_inbound_rtcp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsps_sessions_outbound_bytes{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsps_sessions_outbound_rtp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsps_sessions_outbound_rtp_packets_reported_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 321`+"\n"+
`rtsps_sessions_outbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsps_sessions_bytes_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsps_sessions_bytes_sent{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
@@ -487,6 +548,8 @@ func TestFilter(t *testing.T) {
case "rtsp_conn":
require.Equal(t,
`rtsp_conns{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 1`+"\n"+
`rtsp_conns_inbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`+"\n"+
`rtsp_conns_outbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 456`+"\n"+
`rtsp_conns_bytes_received{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`+"\n"+
`rtsp_conns_bytes_sent{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 456`+"\n",
string(byts))
@@ -495,6 +558,28 @@ func TestFilter(t *testing.T) {
require.Equal(t,
`rtsp_sessions{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 1`+"\n"+
`rtsp_sessions_inbound_bytes{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsp_sessions_inbound_rtp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsp_sessions_inbound_rtp_packets_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsp_sessions_inbound_rtp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsp_sessions_inbound_rtp_packets_jitter{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsp_sessions_inbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsp_sessions_inbound_rtcp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsp_sessions_outbound_bytes{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
`rtsp_sessions_outbound_rtp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsp_sessions_outbound_rtp_packets_reported_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 321`+"\n"+
`rtsp_sessions_outbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
`rtsp_sessions_bytes_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
`rtsp_sessions_bytes_sent{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
+3 -3
View File
@@ -841,15 +841,15 @@ func (co *PeerConnection) Stats() *Stats {
if recvStats := tr.rtpReceiver.Stats(); recvStats != nil {
v += recvStats.Jitter
n++
packetsReceived += recvStats.TotalReceived
packetsLost += recvStats.TotalLost
packetsReceived += recvStats.Received
packetsLost += recvStats.Lost
}
}
}
for _, tr := range co.OutgoingTracks {
if sentStats := tr.rtcpSender.Stats(); sentStats != nil {
packetsSent += sentStats.TotalSent
packetsSent += sentStats.Sent
}
}
+4 -2
View File
@@ -233,7 +233,9 @@ func (c *conn) apiItem() *defs.APIRTSPConn {
return nil
}(),
Tunnel: tunnelLabel(c.rconn.Transport().Tunnel),
BytesReceived: stats.BytesReceived,
BytesSent: stats.BytesSent,
InboundBytes: stats.InboundBytes,
OutboundBytes: stats.OutboundBytes,
BytesReceived: stats.InboundBytes,
BytesSent: stats.OutboundBytes,
}
}
+7
View File
@@ -190,6 +190,9 @@ func TestServerPublish(t *testing.T) {
Path: "teststream",
Query: "param=value",
User: "myuser",
InboundBytes: list.Items[0].InboundBytes,
InboundRTPPackets: list.Items[0].InboundRTPPackets,
OutboundBytes: list.Items[0].OutboundBytes,
BytesReceived: list.Items[0].BytesReceived,
BytesSent: list.Items[0].BytesSent,
Conns: list.Items[0].Conns,
@@ -362,6 +365,10 @@ func TestServerRead(t *testing.T) {
Path: "teststream",
Query: "param=value",
User: "myuser",
InboundBytes: list.Items[0].InboundBytes,
InboundRTPPackets: list.Items[0].InboundRTPPackets,
OutboundBytes: list.Items[0].OutboundBytes,
OutboundRTPPackets: list.Items[0].OutboundRTPPackets,
BytesReceived: list.Items[0].BytesReceived,
BytesSent: list.Items[0].BytesSent,
Conns: list.Items[0].Conns,
+21 -10
View File
@@ -479,15 +479,26 @@ func (s *session) apiItem() *defs.APIRTSPSession {
return ret
}(),
BytesReceived: stats.BytesReceived,
BytesSent: stats.BytesSent,
RTPPacketsReceived: stats.RTPPacketsReceived,
RTPPacketsSent: stats.RTPPacketsSent,
RTPPacketsLost: stats.RTPPacketsLost,
RTPPacketsInError: stats.RTPPacketsInError,
RTPPacketsJitter: stats.RTPPacketsJitter,
RTCPPacketsReceived: stats.RTCPPacketsReceived,
RTCPPacketsSent: stats.RTCPPacketsSent,
RTCPPacketsInError: stats.RTCPPacketsInError,
InboundBytes: stats.InboundBytes,
InboundRTPPackets: stats.InboundRTPPackets,
InboundRTPPacketsLost: stats.InboundRTPPacketsLost,
InboundRTPPacketsInError: stats.InboundRTPPacketsInError,
InboundRTPPacketsJitter: stats.InboundRTPPacketsJitter,
InboundRTCPPackets: stats.InboundRTCPPackets,
InboundRTCPPacketsInError: stats.InboundRTCPPacketsInError,
OutboundBytes: stats.OutboundBytes,
OutboundRTPPackets: stats.OutboundRTPPackets,
OutboundRTPPacketsReportedLost: stats.OutboundRTPPacketsReportedLost,
OutboundRTCPPackets: stats.OutboundRTCPPackets,
BytesReceived: stats.InboundBytes,
BytesSent: stats.OutboundBytes,
RTPPacketsReceived: stats.InboundRTPPackets,
RTPPacketsSent: stats.OutboundRTPPackets,
RTPPacketsLost: stats.InboundRTPPacketsLost,
RTPPacketsInError: stats.InboundRTPPacketsInError,
RTPPacketsJitter: stats.InboundRTPPacketsJitter,
RTCPPacketsReceived: stats.InboundRTCPPackets,
RTCPPacketsSent: stats.OutboundRTCPPackets,
RTCPPacketsInError: stats.InboundRTCPPacketsInError,
}
}
+15 -15
View File
@@ -325,8 +325,8 @@ type Stream struct {
mutex sync.RWMutex
subStream *SubStream
offlineSubStream *offlineSubStream
bytesReceived *uint64
bytesSent *uint64
inboundBytes *uint64
outboundBytes *uint64
medias map[*description.Media]*streamMedia
rtspStream *gortsplib.ServerStream
rtspsStream *gortsplib.ServerStream
@@ -371,8 +371,8 @@ func (s *Stream) Initialize() error {
s.Desc = cloneDesc(s.offlineDesc)
}
s.bytesReceived = new(uint64)
s.bytesSent = new(uint64)
s.inboundBytes = new(uint64)
s.outboundBytes = new(uint64)
s.medias = make(map[*description.Media]*streamMedia)
s.readers = make(map[*Reader]struct{})
s.hasReaders = make(chan struct{})
@@ -459,28 +459,28 @@ func (s *Stream) StartOfflineSubStream() error {
return nil
}
// BytesReceived returns received bytes.
func (s *Stream) BytesReceived() uint64 {
return atomic.LoadUint64(s.bytesReceived)
// InboundBytes returns received bytes.
func (s *Stream) InboundBytes() uint64 {
return atomic.LoadUint64(s.inboundBytes)
}
// BytesSent returns sent bytes.
func (s *Stream) BytesSent() uint64 {
bytesSent := atomic.LoadUint64(s.bytesSent)
// OutboundBytes returns sent bytes.
func (s *Stream) OutboundBytes() uint64 {
outboundBytes := atomic.LoadUint64(s.outboundBytes)
s.mutex.RLock()
defer s.mutex.RUnlock()
if s.rtspStream != nil {
stats := s.rtspStream.Stats()
bytesSent += stats.BytesSent
outboundBytes += stats.OutboundBytes
}
if s.rtspsStream != nil {
stats := s.rtspsStream.Stats()
bytesSent += stats.BytesSent
outboundBytes += stats.OutboundBytes
}
return bytesSent
return outboundBytes
}
// RTSPStream returns the RTSP stream.
@@ -572,11 +572,11 @@ func (s *Stream) WaitForReaders() {
}
func (s *Stream) addBytesReceived(v uint64) {
atomic.AddUint64(s.bytesReceived, v)
atomic.AddUint64(s.inboundBytes, v)
}
func (s *Stream) addBytesSent(v uint64) {
atomic.AddUint64(s.bytesSent, v)
atomic.AddUint64(s.outboundBytes, v)
}
func (s *Stream) updateLastTime(pts time.Duration) {
+4 -4
View File
@@ -65,8 +65,8 @@ func TestStream(t *testing.T) {
<-recv
require.Equal(t, uint64(14), strm.BytesReceived())
require.Equal(t, uint64(14), strm.BytesSent())
require.Equal(t, uint64(14), strm.InboundBytes())
require.Equal(t, uint64(14), strm.OutboundBytes())
}
func TestStreamSkipBytesSent(t *testing.T) {
@@ -120,8 +120,8 @@ func TestStreamSkipBytesSent(t *testing.T) {
<-recv
require.Equal(t, uint64(14), strm.BytesReceived())
require.Equal(t, uint64(0), strm.BytesSent())
require.Equal(t, uint64(14), strm.InboundBytes())
require.Equal(t, uint64(0), strm.OutboundBytes())
}
func TestStreamResizeOversizedRTPPackets(t *testing.T) {