diff --git a/api/openapi.yaml b/api/openapi.yaml index 8a8405b6..de49a9a7 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -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 diff --git a/go.mod b/go.mod index 78331504..daee50a5 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 21dd8bb6..3a0abddd 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/internal/api/api_rtsp_test.go b/internal/api/api_rtsp_test.go index 776d2ee9..5d97a205 100644 --- a/internal/api/api_rtsp_test.go +++ b/internal/api/api_rtsp_test.go @@ -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) diff --git a/internal/core/api_test.go b/internal/core/api_test.go index e8f58041..cb1f0cb2 100644 --- a/internal/core/api_test.go +++ b/internal/core/api_test.go @@ -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) diff --git a/internal/core/metrics_test.go b/internal/core/metrics_test.go index 1391dfea..3dd4a182 100644 --- a/internal/core/metrics_test.go +++ b/internal/core/metrics_test.go @@ -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"+ diff --git a/internal/core/path.go b/internal/core/path.go index e36baf7b..c25b25aa 100644 --- a/internal/core/path.go +++ b/internal/core/path.go @@ -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)) diff --git a/internal/defs/api_rtsp.go b/internal/defs/api_rtsp.go index b78b7055..e04a03e0 100644 --- a/internal/defs/api_rtsp.go +++ b/internal/defs/api_rtsp.go @@ -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. diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 94526f44..99cc573b 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -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) diff --git a/internal/metrics/metrics_test.go b/internal/metrics/metrics_test.go index 481ae7fe..c3e15346 100644 --- a/internal/metrics/metrics_test.go +++ b/internal/metrics/metrics_test.go @@ -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",`+ diff --git a/internal/protocols/webrtc/peer_connection.go b/internal/protocols/webrtc/peer_connection.go index 377924bd..c6c41270 100644 --- a/internal/protocols/webrtc/peer_connection.go +++ b/internal/protocols/webrtc/peer_connection.go @@ -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 } } diff --git a/internal/servers/rtsp/conn.go b/internal/servers/rtsp/conn.go index 67b62a4a..b5bf14b4 100644 --- a/internal/servers/rtsp/conn.go +++ b/internal/servers/rtsp/conn.go @@ -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, } } diff --git a/internal/servers/rtsp/server_test.go b/internal/servers/rtsp/server_test.go index 8e6b230e..a524b0b9 100644 --- a/internal/servers/rtsp/server_test.go +++ b/internal/servers/rtsp/server_test.go @@ -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, diff --git a/internal/servers/rtsp/session.go b/internal/servers/rtsp/session.go index 1bea0229..6b69ca15 100644 --- a/internal/servers/rtsp/session.go +++ b/internal/servers/rtsp/session.go @@ -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, } } diff --git a/internal/stream/stream.go b/internal/stream/stream.go index bc2309cb..c7a1aaa9 100644 --- a/internal/stream/stream.go +++ b/internal/stream/stream.go @@ -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) { diff --git a/internal/stream/stream_standard_test.go b/internal/stream/stream_standard_test.go index 5f8fb5a7..7594cd1d 100644 --- a/internal/stream/stream_standard_test.go +++ b/internal/stream/stream_standard_test.go @@ -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) {