api: add new stats (#5582)
- RTSPSession.outboundRTPPacketsDiscarded - Path.inboundFramesInError - SRTConn.outboundFramesDiscarded - WebRTCSession.outboundFramesDiscarded - RTMPConn.outboundFramesDiscarded - HLSMuxer.outboundFramesDiscarded
This commit is contained in:
@@ -973,12 +973,23 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/PathTrackCodec'
|
$ref: '#/components/schemas/PathTrackCodec'
|
||||||
|
inboundBytes:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
|
outboundBytes:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
|
inboundFramesInError:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
bytesReceived:
|
bytesReceived:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
|
deprecated: true
|
||||||
bytesSent:
|
bytesSent:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
|
deprecated: true
|
||||||
readers:
|
readers:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@@ -1023,9 +1034,16 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
lastRequest:
|
lastRequest:
|
||||||
type: string
|
type: string
|
||||||
|
outboundBytes:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
|
outboundFramesDiscarded:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
bytesSent:
|
bytesSent:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
|
deprecated: true
|
||||||
|
|
||||||
HLSMuxerList:
|
HLSMuxerList:
|
||||||
type: object
|
type: object
|
||||||
@@ -1089,12 +1107,23 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
user:
|
user:
|
||||||
type: string
|
type: string
|
||||||
|
inboundBytes:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
|
outboundBytes:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
|
outboundFramesDiscarded:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
bytesReceived:
|
bytesReceived:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
|
deprecated: true
|
||||||
bytesSent:
|
bytesSent:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
|
deprecated: true
|
||||||
|
|
||||||
RTMPConnList:
|
RTMPConnList:
|
||||||
type: object
|
type: object
|
||||||
@@ -1214,6 +1243,9 @@ components:
|
|||||||
outboundRTPPacketsReportedLost:
|
outboundRTPPacketsReportedLost:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
|
outboundRTPPacketsDiscarded:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
outboundRTCPPackets:
|
outboundRTCPPackets:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
@@ -1500,6 +1532,9 @@ components:
|
|||||||
type: number
|
type: number
|
||||||
format: double
|
format: double
|
||||||
description: Percentage of retransmitted data vs. received data
|
description: Percentage of retransmitted data vs. received data
|
||||||
|
outboundFramesDiscarded:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
|
|
||||||
SRTConnList:
|
SRTConnList:
|
||||||
type: object
|
type: object
|
||||||
@@ -1589,6 +1624,9 @@ components:
|
|||||||
outboundRTCPPackets:
|
outboundRTCPPackets:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
|
outboundFramesDiscarded:
|
||||||
|
type: integer
|
||||||
|
format: uint64
|
||||||
bytesReceived:
|
bytesReceived:
|
||||||
type: integer
|
type: integer
|
||||||
format: uint64
|
format: uint64
|
||||||
|
|||||||
@@ -37,16 +37,20 @@ func TestHLSMuxersList(t *testing.T) {
|
|||||||
hlsServer := &testHLSServer{
|
hlsServer := &testHLSServer{
|
||||||
muxers: map[string]*defs.APIHLSMuxer{
|
muxers: map[string]*defs.APIHLSMuxer{
|
||||||
"test1": {
|
"test1": {
|
||||||
Path: "test1",
|
Path: "test1",
|
||||||
Created: now,
|
Created: now,
|
||||||
LastRequest: now.Add(5 * time.Second),
|
LastRequest: now.Add(5 * time.Second),
|
||||||
BytesSent: 1234,
|
OutboundBytes: 1234,
|
||||||
|
OutboundFramesDiscarded: 10,
|
||||||
|
BytesSent: 1234,
|
||||||
},
|
},
|
||||||
"test2": {
|
"test2": {
|
||||||
Path: "test2",
|
Path: "test2",
|
||||||
Created: now.Add(time.Minute),
|
Created: now.Add(time.Minute),
|
||||||
LastRequest: now.Add(time.Minute + 10*time.Second),
|
LastRequest: now.Add(time.Minute + 10*time.Second),
|
||||||
BytesSent: 5678,
|
OutboundBytes: 5678,
|
||||||
|
OutboundFramesDiscarded: 20,
|
||||||
|
BytesSent: 5678,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -80,10 +84,12 @@ func TestHLSMuxersGet(t *testing.T) {
|
|||||||
hlsServer := &testHLSServer{
|
hlsServer := &testHLSServer{
|
||||||
muxers: map[string]*defs.APIHLSMuxer{
|
muxers: map[string]*defs.APIHLSMuxer{
|
||||||
"mypath": {
|
"mypath": {
|
||||||
Path: "mypath",
|
Path: "mypath",
|
||||||
Created: now,
|
Created: now,
|
||||||
LastRequest: now.Add(5 * time.Second),
|
LastRequest: now.Add(5 * time.Second),
|
||||||
BytesSent: 9999,
|
OutboundBytes: 9999,
|
||||||
|
OutboundFramesDiscarded: 12,
|
||||||
|
BytesSent: 9999,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -108,5 +114,7 @@ func TestHLSMuxersGet(t *testing.T) {
|
|||||||
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/hlsmuxers/get/mypath", nil, &out)
|
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/hlsmuxers/get/mypath", nil, &out)
|
||||||
|
|
||||||
require.Equal(t, "mypath", out.Path)
|
require.Equal(t, "mypath", out.Path)
|
||||||
|
require.Equal(t, uint64(9999), out.OutboundBytes)
|
||||||
|
require.Equal(t, uint64(12), out.OutboundFramesDiscarded)
|
||||||
require.Equal(t, uint64(9999), out.BytesSent)
|
require.Equal(t, uint64(9999), out.BytesSent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,26 +36,32 @@ func TestPathsList(t *testing.T) {
|
|||||||
pathManager := &testPathManager{
|
pathManager := &testPathManager{
|
||||||
paths: map[string]*defs.APIPath{
|
paths: map[string]*defs.APIPath{
|
||||||
"test1": {
|
"test1": {
|
||||||
Name: "test1",
|
Name: "test1",
|
||||||
ConfName: "test1",
|
ConfName: "test1",
|
||||||
Source: &defs.APIPathSource{Type: defs.APIPathSourceTypeRTSPSession, ID: "pub1"},
|
Source: &defs.APIPathSource{Type: defs.APIPathSourceTypeRTSPSession, ID: "pub1"},
|
||||||
Ready: true,
|
Ready: true,
|
||||||
ReadyTime: &now,
|
ReadyTime: &now,
|
||||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecOpus},
|
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecOpus},
|
||||||
BytesReceived: 1000,
|
InboundBytes: 1000,
|
||||||
BytesSent: 2000,
|
OutboundBytes: 2000,
|
||||||
|
InboundFramesInError: 3,
|
||||||
|
BytesReceived: 1000,
|
||||||
|
BytesSent: 2000,
|
||||||
Readers: []defs.APIPathReader{
|
Readers: []defs.APIPathReader{
|
||||||
{Type: defs.APIPathReaderTypeRTSPSession, ID: "reader1"},
|
{Type: defs.APIPathReaderTypeRTSPSession, ID: "reader1"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"test2": {
|
"test2": {
|
||||||
Name: "test2",
|
Name: "test2",
|
||||||
ConfName: "test2",
|
ConfName: "test2",
|
||||||
Ready: false,
|
Ready: false,
|
||||||
Tracks: []defs.APIPathTrackCodec{},
|
Tracks: []defs.APIPathTrackCodec{},
|
||||||
BytesReceived: 500,
|
InboundBytes: 500,
|
||||||
BytesSent: 100,
|
OutboundBytes: 100,
|
||||||
Readers: []defs.APIPathReader{},
|
InboundFramesInError: 1,
|
||||||
|
BytesReceived: 500,
|
||||||
|
BytesSent: 100,
|
||||||
|
Readers: []defs.APIPathReader{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -89,14 +95,17 @@ func TestPathsGet(t *testing.T) {
|
|||||||
pathManager := &testPathManager{
|
pathManager := &testPathManager{
|
||||||
paths: map[string]*defs.APIPath{
|
paths: map[string]*defs.APIPath{
|
||||||
"mystream": {
|
"mystream": {
|
||||||
Name: "mystream",
|
Name: "mystream",
|
||||||
ConfName: "mystream",
|
ConfName: "mystream",
|
||||||
Source: &defs.APIPathSource{Type: defs.APIPathSourceTypeRTSPSession, ID: "session123"},
|
Source: &defs.APIPathSource{Type: defs.APIPathSourceTypeRTSPSession, ID: "session123"},
|
||||||
Ready: true,
|
Ready: true,
|
||||||
ReadyTime: &now,
|
ReadyTime: &now,
|
||||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecOpus},
|
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecOpus},
|
||||||
BytesReceived: 123456,
|
InboundBytes: 123456,
|
||||||
BytesSent: 789012,
|
OutboundBytes: 789012,
|
||||||
|
InboundFramesInError: 12,
|
||||||
|
BytesReceived: 123456,
|
||||||
|
BytesSent: 789012,
|
||||||
Readers: []defs.APIPathReader{
|
Readers: []defs.APIPathReader{
|
||||||
{Type: defs.APIPathReaderTypeHLSMuxer, ID: "muxer1"},
|
{Type: defs.APIPathReaderTypeHLSMuxer, ID: "muxer1"},
|
||||||
{Type: defs.APIPathReaderTypeWebRTCSession, ID: "session456"},
|
{Type: defs.APIPathReaderTypeWebRTCSession, ID: "session456"},
|
||||||
@@ -131,6 +140,9 @@ func TestPathsGet(t *testing.T) {
|
|||||||
require.Equal(t, defs.APIPathSourceTypeRTSPSession, out.Source.Type)
|
require.Equal(t, defs.APIPathSourceTypeRTSPSession, out.Source.Type)
|
||||||
require.Len(t, out.Tracks, 2)
|
require.Len(t, out.Tracks, 2)
|
||||||
require.Len(t, out.Readers, 2)
|
require.Len(t, out.Readers, 2)
|
||||||
|
require.Equal(t, uint64(123456), out.InboundBytes)
|
||||||
|
require.Equal(t, uint64(789012), out.OutboundBytes)
|
||||||
|
require.Equal(t, uint64(12), out.InboundFramesInError)
|
||||||
require.Equal(t, uint64(123456), out.BytesReceived)
|
require.Equal(t, uint64(123456), out.BytesReceived)
|
||||||
require.Equal(t, uint64(789012), out.BytesSent)
|
require.Equal(t, uint64(789012), out.BytesSent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,24 +67,30 @@ func TestRTMPConnsList(t *testing.T) {
|
|||||||
rtmpServer := &testRTMPServer{
|
rtmpServer := &testRTMPServer{
|
||||||
conns: map[uuid.UUID]*defs.APIRTMPConn{
|
conns: map[uuid.UUID]*defs.APIRTMPConn{
|
||||||
id1: {
|
id1: {
|
||||||
ID: id1,
|
ID: id1,
|
||||||
Created: now,
|
Created: now,
|
||||||
RemoteAddr: "192.168.1.1:5000",
|
RemoteAddr: "192.168.1.1:5000",
|
||||||
State: defs.APIRTMPConnStatePublish,
|
State: defs.APIRTMPConnStatePublish,
|
||||||
Path: "stream1",
|
Path: "stream1",
|
||||||
Query: "token=abc",
|
Query: "token=abc",
|
||||||
BytesReceived: 1000,
|
InboundBytes: 1000,
|
||||||
BytesSent: 2000,
|
OutboundBytes: 2000,
|
||||||
|
OutboundFramesDiscarded: 11,
|
||||||
|
BytesReceived: 1000,
|
||||||
|
BytesSent: 2000,
|
||||||
},
|
},
|
||||||
id2: {
|
id2: {
|
||||||
ID: id2,
|
ID: id2,
|
||||||
Created: now.Add(time.Minute),
|
Created: now.Add(time.Minute),
|
||||||
RemoteAddr: "192.168.1.2:5001",
|
RemoteAddr: "192.168.1.2:5001",
|
||||||
State: defs.APIRTMPConnStateRead,
|
State: defs.APIRTMPConnStateRead,
|
||||||
Path: "stream2",
|
Path: "stream2",
|
||||||
Query: "",
|
Query: "",
|
||||||
BytesReceived: 500,
|
InboundBytes: 500,
|
||||||
BytesSent: 1500,
|
OutboundBytes: 1500,
|
||||||
|
OutboundFramesDiscarded: 22,
|
||||||
|
BytesReceived: 500,
|
||||||
|
BytesSent: 1500,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -148,14 +154,17 @@ func TestRTMPConnsGet(t *testing.T) {
|
|||||||
rtmpServer := &testRTMPServer{
|
rtmpServer := &testRTMPServer{
|
||||||
conns: map[uuid.UUID]*defs.APIRTMPConn{
|
conns: map[uuid.UUID]*defs.APIRTMPConn{
|
||||||
id: {
|
id: {
|
||||||
ID: id,
|
ID: id,
|
||||||
Created: now,
|
Created: now,
|
||||||
RemoteAddr: "192.168.1.100:5000",
|
RemoteAddr: "192.168.1.100:5000",
|
||||||
State: defs.APIRTMPConnStatePublish,
|
State: defs.APIRTMPConnStatePublish,
|
||||||
Path: ca.path,
|
Path: ca.path,
|
||||||
Query: "key=value",
|
Query: "key=value",
|
||||||
BytesReceived: 999999,
|
InboundBytes: 999999,
|
||||||
BytesSent: 888888,
|
OutboundBytes: 888888,
|
||||||
|
OutboundFramesDiscarded: 33,
|
||||||
|
BytesReceived: 999999,
|
||||||
|
BytesSent: 888888,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -189,6 +198,9 @@ func TestRTMPConnsGet(t *testing.T) {
|
|||||||
require.Equal(t, "192.168.1.100:5000", out.RemoteAddr)
|
require.Equal(t, "192.168.1.100:5000", out.RemoteAddr)
|
||||||
require.Equal(t, defs.APIRTMPConnStatePublish, out.State)
|
require.Equal(t, defs.APIRTMPConnStatePublish, out.State)
|
||||||
require.Equal(t, ca.path, out.Path)
|
require.Equal(t, ca.path, out.Path)
|
||||||
|
require.Equal(t, uint64(999999), out.InboundBytes)
|
||||||
|
require.Equal(t, uint64(888888), out.OutboundBytes)
|
||||||
|
require.Equal(t, uint64(33), out.OutboundFramesDiscarded)
|
||||||
require.Equal(t, uint64(999999), out.BytesReceived)
|
require.Equal(t, uint64(999999), out.BytesReceived)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,38 +50,40 @@ func TestSRTConnsList(t *testing.T) {
|
|||||||
srtServer := &testSRTServer{
|
srtServer := &testSRTServer{
|
||||||
conns: map[uuid.UUID]*defs.APISRTConn{
|
conns: map[uuid.UUID]*defs.APISRTConn{
|
||||||
id1: {
|
id1: {
|
||||||
ID: id1,
|
ID: id1,
|
||||||
Created: now,
|
Created: now,
|
||||||
RemoteAddr: "192.168.1.1:5000",
|
RemoteAddr: "192.168.1.1:5000",
|
||||||
State: defs.APISRTConnStatePublish,
|
State: defs.APISRTConnStatePublish,
|
||||||
Path: "stream1",
|
Path: "stream1",
|
||||||
Query: "token=abc",
|
Query: "token=abc",
|
||||||
PacketsSent: 1000,
|
PacketsSent: 1000,
|
||||||
PacketsReceived: 2000,
|
PacketsReceived: 2000,
|
||||||
PacketsSentUnique: 950,
|
PacketsSentUnique: 950,
|
||||||
PacketsReceivedUnique: 1950,
|
PacketsReceivedUnique: 1950,
|
||||||
BytesReceived: 100000,
|
BytesReceived: 100000,
|
||||||
BytesSent: 200000,
|
BytesSent: 200000,
|
||||||
MsRTT: 10.5,
|
OutboundFramesDiscarded: 5,
|
||||||
MbpsSendRate: 5.2,
|
MsRTT: 10.5,
|
||||||
MbpsReceiveRate: 4.8,
|
MbpsSendRate: 5.2,
|
||||||
|
MbpsReceiveRate: 4.8,
|
||||||
},
|
},
|
||||||
id2: {
|
id2: {
|
||||||
ID: id2,
|
ID: id2,
|
||||||
Created: now.Add(time.Minute),
|
Created: now.Add(time.Minute),
|
||||||
RemoteAddr: "192.168.1.2:5001",
|
RemoteAddr: "192.168.1.2:5001",
|
||||||
State: defs.APISRTConnStateRead,
|
State: defs.APISRTConnStateRead,
|
||||||
Path: "stream2",
|
Path: "stream2",
|
||||||
Query: "",
|
Query: "",
|
||||||
PacketsSent: 500,
|
PacketsSent: 500,
|
||||||
PacketsReceived: 1500,
|
PacketsReceived: 1500,
|
||||||
PacketsSentUnique: 480,
|
PacketsSentUnique: 480,
|
||||||
PacketsReceivedUnique: 1470,
|
PacketsReceivedUnique: 1470,
|
||||||
BytesReceived: 50000,
|
BytesReceived: 50000,
|
||||||
BytesSent: 150000,
|
BytesSent: 150000,
|
||||||
MsRTT: 15.2,
|
OutboundFramesDiscarded: 6,
|
||||||
MbpsSendRate: 3.5,
|
MsRTT: 15.2,
|
||||||
MbpsReceiveRate: 3.2,
|
MbpsSendRate: 3.5,
|
||||||
|
MbpsReceiveRate: 3.2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -176,6 +178,7 @@ func TestSRTConnsGet(t *testing.T) {
|
|||||||
PacketsReceivedAvgBelatedTime: 50,
|
PacketsReceivedAvgBelatedTime: 50,
|
||||||
PacketsSendLossRate: 0.5,
|
PacketsSendLossRate: 0.5,
|
||||||
PacketsReceivedLossRate: 0.6,
|
PacketsReceivedLossRate: 0.6,
|
||||||
|
OutboundFramesDiscarded: 7,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -205,6 +208,7 @@ func TestSRTConnsGet(t *testing.T) {
|
|||||||
require.Equal(t, "mystream", out.Path)
|
require.Equal(t, "mystream", out.Path)
|
||||||
require.Equal(t, uint64(999999), out.BytesReceived)
|
require.Equal(t, uint64(999999), out.BytesReceived)
|
||||||
require.Equal(t, uint64(888888), out.BytesSent)
|
require.Equal(t, uint64(888888), out.BytesSent)
|
||||||
|
require.Equal(t, uint64(7), out.OutboundFramesDiscarded)
|
||||||
require.Equal(t, 25.5, out.MsRTT)
|
require.Equal(t, 25.5, out.MsRTT)
|
||||||
require.Equal(t, 10.5, out.MbpsSendRate)
|
require.Equal(t, 10.5, out.MbpsSendRate)
|
||||||
require.Equal(t, 9.8, out.MbpsReceiveRate)
|
require.Equal(t, 9.8, out.MbpsReceiveRate)
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ func TestWebRTCSessionsList(t *testing.T) {
|
|||||||
OutboundBytes: 2000,
|
OutboundBytes: 2000,
|
||||||
OutboundRTPPackets: 200,
|
OutboundRTPPackets: 200,
|
||||||
OutboundRTCPPackets: 15,
|
OutboundRTCPPackets: 15,
|
||||||
|
OutboundFramesDiscarded: 11,
|
||||||
BytesReceived: 1000,
|
BytesReceived: 1000,
|
||||||
BytesSent: 2000,
|
BytesSent: 2000,
|
||||||
RTPPacketsReceived: 100,
|
RTPPacketsReceived: 100,
|
||||||
@@ -94,6 +95,7 @@ func TestWebRTCSessionsList(t *testing.T) {
|
|||||||
OutboundBytes: 1500,
|
OutboundBytes: 1500,
|
||||||
OutboundRTPPackets: 150,
|
OutboundRTPPackets: 150,
|
||||||
OutboundRTCPPackets: 10,
|
OutboundRTCPPackets: 10,
|
||||||
|
OutboundFramesDiscarded: 22,
|
||||||
BytesReceived: 500,
|
BytesReceived: 500,
|
||||||
BytesSent: 1500,
|
BytesSent: 1500,
|
||||||
RTPPacketsReceived: 50,
|
RTPPacketsReceived: 50,
|
||||||
@@ -154,6 +156,7 @@ func TestWebRTCSessionsGet(t *testing.T) {
|
|||||||
OutboundBytes: 888888,
|
OutboundBytes: 888888,
|
||||||
OutboundRTPPackets: 20000,
|
OutboundRTPPackets: 20000,
|
||||||
OutboundRTCPPackets: 200,
|
OutboundRTCPPackets: 200,
|
||||||
|
OutboundFramesDiscarded: 33,
|
||||||
BytesReceived: 999999,
|
BytesReceived: 999999,
|
||||||
BytesSent: 888888,
|
BytesSent: 888888,
|
||||||
RTPPacketsReceived: 10000,
|
RTPPacketsReceived: 10000,
|
||||||
@@ -196,6 +199,7 @@ func TestWebRTCSessionsGet(t *testing.T) {
|
|||||||
require.Equal(t, uint64(888888), out.OutboundBytes)
|
require.Equal(t, uint64(888888), out.OutboundBytes)
|
||||||
require.Equal(t, uint64(10000), out.InboundRTPPackets)
|
require.Equal(t, uint64(10000), out.InboundRTPPackets)
|
||||||
require.Equal(t, uint64(20000), out.OutboundRTPPackets)
|
require.Equal(t, uint64(20000), out.OutboundRTPPackets)
|
||||||
|
require.Equal(t, uint64(33), out.OutboundFramesDiscarded)
|
||||||
require.Equal(t, uint64(999999), out.BytesReceived)
|
require.Equal(t, uint64(999999), out.BytesReceived)
|
||||||
require.Equal(t, uint64(888888), out.BytesSent)
|
require.Equal(t, uint64(888888), out.BytesSent)
|
||||||
require.Equal(t, uint64(10000), out.RTPPacketsReceived)
|
require.Equal(t, uint64(10000), out.RTPPacketsReceived)
|
||||||
|
|||||||
+62
-37
@@ -80,12 +80,15 @@ func TestAPIPathsList(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type path struct {
|
type path struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Source pathSource `json:"source"`
|
Source pathSource `json:"source"`
|
||||||
Ready bool `json:"ready"`
|
Ready bool `json:"ready"`
|
||||||
Tracks []defs.APIPathTrackCodec `json:"tracks"`
|
Tracks []defs.APIPathTrackCodec `json:"tracks"`
|
||||||
BytesReceived uint64 `json:"bytesReceived"`
|
InboundBytes uint64 `json:"inboundBytes"`
|
||||||
BytesSent uint64 `json:"bytesSent"`
|
OutboundBytes uint64 `json:"outboundBytes"`
|
||||||
|
InboundFramesInError uint64 `json:"inboundFramesInError"`
|
||||||
|
BytesReceived uint64 `json:"bytesReceived"`
|
||||||
|
BytesSent uint64 `json:"bytesSent"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type pathList struct {
|
type pathList struct {
|
||||||
@@ -136,9 +139,11 @@ func TestAPIPathsList(t *testing.T) {
|
|||||||
Source: pathSource{
|
Source: pathSource{
|
||||||
Type: "rtspSession",
|
Type: "rtspSession",
|
||||||
},
|
},
|
||||||
Ready: true,
|
Ready: true,
|
||||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecMPEG4Audio},
|
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecMPEG4Audio},
|
||||||
BytesReceived: 17,
|
InboundBytes: 17,
|
||||||
|
InboundFramesInError: 0,
|
||||||
|
BytesReceived: 17,
|
||||||
}},
|
}},
|
||||||
}, out)
|
}, out)
|
||||||
})
|
})
|
||||||
@@ -296,12 +301,15 @@ func TestAPIPathsGet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type path struct {
|
type path struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Source pathSource `json:"source"`
|
Source pathSource `json:"source"`
|
||||||
Ready bool `json:"Ready"`
|
Ready bool `json:"Ready"`
|
||||||
Tracks []defs.APIPathTrackCodec `json:"tracks"`
|
Tracks []defs.APIPathTrackCodec `json:"tracks"`
|
||||||
BytesReceived uint64 `json:"bytesReceived"`
|
InboundBytes uint64 `json:"inboundBytes"`
|
||||||
BytesSent uint64 `json:"bytesSent"`
|
OutboundBytes uint64 `json:"outboundBytes"`
|
||||||
|
InboundFramesInError uint64 `json:"inboundFramesInError"`
|
||||||
|
BytesReceived uint64 `json:"bytesReceived"`
|
||||||
|
BytesSent uint64 `json:"bytesSent"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var pathName string
|
var pathName string
|
||||||
@@ -652,6 +660,7 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
||||||
"outboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"],
|
"outboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"],
|
||||||
"outboundRTPPacketsReportedLost": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsReportedLost"],
|
"outboundRTPPacketsReportedLost": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsReportedLost"],
|
||||||
|
"outboundRTPPacketsDiscarded": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsDiscarded"],
|
||||||
"outboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"],
|
"outboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"],
|
||||||
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
||||||
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
||||||
@@ -712,6 +721,7 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
||||||
"outboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"],
|
"outboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"],
|
||||||
"outboundRTPPacketsReportedLost": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsReportedLost"],
|
"outboundRTPPacketsReportedLost": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsReportedLost"],
|
||||||
|
"outboundRTPPacketsDiscarded": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsDiscarded"],
|
||||||
"outboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"],
|
"outboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"],
|
||||||
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
||||||
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
||||||
@@ -743,15 +753,18 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
"itemCount": float64(1),
|
"itemCount": float64(1),
|
||||||
"items": []any{
|
"items": []any{
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
"inboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundBytes"],
|
||||||
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
||||||
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
|
"outboundFramesDiscarded": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundFramesDiscarded"],
|
||||||
"id": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["id"],
|
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
||||||
"path": "mypath",
|
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
||||||
"query": "key=val",
|
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
|
||||||
"user": "",
|
"id": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["id"],
|
||||||
"remoteAddr": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["remoteAddr"],
|
"path": "mypath",
|
||||||
"state": "publish",
|
"query": "key=val",
|
||||||
|
"user": "",
|
||||||
|
"remoteAddr": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["remoteAddr"],
|
||||||
|
"state": "publish",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, out1)
|
}, out1)
|
||||||
@@ -762,15 +775,18 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
"itemCount": float64(1),
|
"itemCount": float64(1),
|
||||||
"items": []any{
|
"items": []any{
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
"inboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["inboundBytes"],
|
||||||
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
||||||
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
|
"outboundFramesDiscarded": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundFramesDiscarded"],
|
||||||
"id": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["id"],
|
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
||||||
"path": "mypath",
|
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
||||||
"query": "key=val",
|
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
|
||||||
"user": "",
|
"id": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["id"],
|
||||||
"remoteAddr": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["remoteAddr"],
|
"path": "mypath",
|
||||||
"state": "publish",
|
"query": "key=val",
|
||||||
|
"user": "",
|
||||||
|
"remoteAddr": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["remoteAddr"],
|
||||||
|
"state": "publish",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, out1)
|
}, out1)
|
||||||
@@ -781,10 +797,12 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
"pageCount": float64(1),
|
"pageCount": float64(1),
|
||||||
"items": []any{
|
"items": []any{
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
||||||
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
|
"outboundFramesDiscarded": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundFramesDiscarded"],
|
||||||
"lastRequest": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["lastRequest"],
|
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
||||||
"path": "mypath",
|
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
|
||||||
|
"lastRequest": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["lastRequest"],
|
||||||
|
"path": "mypath",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, out1)
|
}, out1)
|
||||||
@@ -803,6 +821,7 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
"outboundBytes": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"],
|
||||||
"outboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"],
|
"outboundRTPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"],
|
||||||
"outboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"],
|
"outboundRTCPPackets": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"],
|
||||||
|
"outboundFramesDiscarded": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundFramesDiscarded"],
|
||||||
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
"bytesReceived": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"],
|
||||||
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
"bytesSent": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"],
|
||||||
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
|
"created": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["created"],
|
||||||
@@ -841,6 +860,7 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
"bytesReceivedLoss": float64(0),
|
"bytesReceivedLoss": float64(0),
|
||||||
"bytesReceivedRetrans": float64(0),
|
"bytesReceivedRetrans": float64(0),
|
||||||
"bytesReceivedUndecrypt": float64(0),
|
"bytesReceivedUndecrypt": float64(0),
|
||||||
|
"outboundFramesDiscarded": out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundFramesDiscarded"],
|
||||||
"bytesReceivedUnique": float64(628),
|
"bytesReceivedUnique": float64(628),
|
||||||
"bytesRetrans": float64(0),
|
"bytesRetrans": float64(0),
|
||||||
"bytesSendBuf": float64(0),
|
"bytesSendBuf": float64(0),
|
||||||
@@ -926,6 +946,7 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
out2.(map[string]any)["outboundBytes"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"]
|
out2.(map[string]any)["outboundBytes"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"]
|
||||||
out2.(map[string]any)["outboundRTPPackets"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"]
|
out2.(map[string]any)["outboundRTPPackets"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"]
|
||||||
out2.(map[string]any)["outboundRTPPacketsReportedLost"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsReportedLost"]
|
out2.(map[string]any)["outboundRTPPacketsReportedLost"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsReportedLost"]
|
||||||
|
out2.(map[string]any)["outboundRTPPacketsDiscarded"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPacketsDiscarded"]
|
||||||
out2.(map[string]any)["outboundRTCPPackets"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"]
|
out2.(map[string]any)["outboundRTCPPackets"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"]
|
||||||
out2.(map[string]any)["bytesReceived"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"]
|
out2.(map[string]any)["bytesReceived"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"]
|
||||||
out2.(map[string]any)["bytesSent"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"]
|
out2.(map[string]any)["bytesSent"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"]
|
||||||
@@ -947,6 +968,7 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
out2.(map[string]any)["outboundBytes"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"]
|
out2.(map[string]any)["outboundBytes"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundBytes"]
|
||||||
out2.(map[string]any)["outboundRTPPackets"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"]
|
out2.(map[string]any)["outboundRTPPackets"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTPPackets"]
|
||||||
out2.(map[string]any)["outboundRTCPPackets"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"]
|
out2.(map[string]any)["outboundRTCPPackets"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundRTCPPackets"]
|
||||||
|
out2.(map[string]any)["outboundFramesDiscarded"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["outboundFramesDiscarded"]
|
||||||
out2.(map[string]any)["bytesReceived"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"]
|
out2.(map[string]any)["bytesReceived"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesReceived"]
|
||||||
out2.(map[string]any)["bytesSent"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"]
|
out2.(map[string]any)["bytesSent"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["bytesSent"]
|
||||||
out2.(map[string]any)["rtpPacketsReceived"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["rtpPacketsReceived"]
|
out2.(map[string]any)["rtpPacketsReceived"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["rtpPacketsReceived"]
|
||||||
@@ -955,6 +977,9 @@ func TestAPIProtocolListGet(t *testing.T) {
|
|||||||
out2.(map[string]any)["rtpPacketsJitter"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["rtpPacketsJitter"]
|
out2.(map[string]any)["rtpPacketsJitter"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["rtpPacketsJitter"]
|
||||||
out2.(map[string]any)["rtcpPacketsReceived"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["rtcpPacketsReceived"]
|
out2.(map[string]any)["rtcpPacketsReceived"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["rtcpPacketsReceived"]
|
||||||
out2.(map[string]any)["rtcpPacketsSent"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["rtcpPacketsSent"]
|
out2.(map[string]any)["rtcpPacketsSent"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["rtcpPacketsSent"]
|
||||||
|
|
||||||
|
case "hls":
|
||||||
|
out2.(map[string]any)["lastRequest"] = out1.(map[string]any)["items"].([]any)[0].(map[string]any)["lastRequest"]
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Equal(t, out1.(map[string]any)["items"].([]any)[0], out2)
|
require.Equal(t, out1.(map[string]any)["items"].([]any)[0], out2)
|
||||||
|
|||||||
@@ -76,10 +76,15 @@ func TestMetrics(t *testing.T) {
|
|||||||
bo := httpPullFile(t, hc, "http://localhost:9998/metrics")
|
bo := httpPullFile(t, hc, "http://localhost:9998/metrics")
|
||||||
|
|
||||||
require.Equal(t, `paths 0
|
require.Equal(t, `paths 0
|
||||||
|
paths_inbound_bytes 0
|
||||||
|
paths_outbound_bytes 0
|
||||||
|
paths_inbound_frames_in_error 0
|
||||||
paths_bytes_received 0
|
paths_bytes_received 0
|
||||||
paths_bytes_sent 0
|
paths_bytes_sent 0
|
||||||
paths_readers 0
|
paths_readers 0
|
||||||
hls_muxers 0
|
hls_muxers 0
|
||||||
|
hls_muxers_outbound_bytes 0
|
||||||
|
hls_muxers_outbound_frames_discarded 0
|
||||||
hls_muxers_bytes_sent 0
|
hls_muxers_bytes_sent 0
|
||||||
rtsp_conns 0
|
rtsp_conns 0
|
||||||
rtsp_conns_inbound_bytes 0
|
rtsp_conns_inbound_bytes 0
|
||||||
@@ -97,6 +102,7 @@ rtsp_sessions_inbound_rtcp_packets_in_error 0
|
|||||||
rtsp_sessions_outbound_bytes 0
|
rtsp_sessions_outbound_bytes 0
|
||||||
rtsp_sessions_outbound_rtp_packets 0
|
rtsp_sessions_outbound_rtp_packets 0
|
||||||
rtsp_sessions_outbound_rtp_packets_reported_lost 0
|
rtsp_sessions_outbound_rtp_packets_reported_lost 0
|
||||||
|
rtsp_sessions_outbound_rtp_packets_discarded 0
|
||||||
rtsp_sessions_outbound_rtcp_packets 0
|
rtsp_sessions_outbound_rtcp_packets 0
|
||||||
rtsp_sessions_bytes_received 0
|
rtsp_sessions_bytes_received 0
|
||||||
rtsp_sessions_bytes_sent 0
|
rtsp_sessions_bytes_sent 0
|
||||||
@@ -124,6 +130,7 @@ rtsps_sessions_inbound_rtcp_packets_in_error 0
|
|||||||
rtsps_sessions_outbound_bytes 0
|
rtsps_sessions_outbound_bytes 0
|
||||||
rtsps_sessions_outbound_rtp_packets 0
|
rtsps_sessions_outbound_rtp_packets 0
|
||||||
rtsps_sessions_outbound_rtp_packets_reported_lost 0
|
rtsps_sessions_outbound_rtp_packets_reported_lost 0
|
||||||
|
rtsps_sessions_outbound_rtp_packets_discarded 0
|
||||||
rtsps_sessions_outbound_rtcp_packets 0
|
rtsps_sessions_outbound_rtcp_packets 0
|
||||||
rtsps_sessions_bytes_received 0
|
rtsps_sessions_bytes_received 0
|
||||||
rtsps_sessions_bytes_sent 0
|
rtsps_sessions_bytes_sent 0
|
||||||
@@ -136,9 +143,15 @@ rtsps_sessions_rtcp_packets_received 0
|
|||||||
rtsps_sessions_rtcp_packets_sent 0
|
rtsps_sessions_rtcp_packets_sent 0
|
||||||
rtsps_sessions_rtcp_packets_in_error 0
|
rtsps_sessions_rtcp_packets_in_error 0
|
||||||
rtmp_conns 0
|
rtmp_conns 0
|
||||||
|
rtmp_conns_inbound_bytes 0
|
||||||
|
rtmp_conns_outbound_bytes 0
|
||||||
|
rtmp_conns_outbound_frames_discarded 0
|
||||||
rtmp_conns_bytes_received 0
|
rtmp_conns_bytes_received 0
|
||||||
rtmp_conns_bytes_sent 0
|
rtmp_conns_bytes_sent 0
|
||||||
rtmps_conns 0
|
rtmps_conns 0
|
||||||
|
rtmps_conns_inbound_bytes 0
|
||||||
|
rtmps_conns_outbound_bytes 0
|
||||||
|
rtmps_conns_outbound_frames_discarded 0
|
||||||
rtmps_conns_bytes_received 0
|
rtmps_conns_bytes_received 0
|
||||||
rtmps_conns_bytes_sent 0
|
rtmps_conns_bytes_sent 0
|
||||||
srt_conns 0
|
srt_conns 0
|
||||||
@@ -195,6 +208,7 @@ srt_conns_packets_reorder_tolerance 0
|
|||||||
srt_conns_packets_received_avg_belated_time 0
|
srt_conns_packets_received_avg_belated_time 0
|
||||||
srt_conns_packets_send_loss_rate 0
|
srt_conns_packets_send_loss_rate 0
|
||||||
srt_conns_packets_received_loss_rate 0
|
srt_conns_packets_received_loss_rate 0
|
||||||
|
srt_conns_outbound_frames_discarded 0
|
||||||
webrtc_sessions 0
|
webrtc_sessions 0
|
||||||
webrtc_sessions_inbound_bytes 0
|
webrtc_sessions_inbound_bytes 0
|
||||||
webrtc_sessions_inbound_rtp_packets 0
|
webrtc_sessions_inbound_rtp_packets 0
|
||||||
@@ -204,6 +218,7 @@ webrtc_sessions_inbound_rtcp_packets 0
|
|||||||
webrtc_sessions_outbound_bytes 0
|
webrtc_sessions_outbound_bytes 0
|
||||||
webrtc_sessions_outbound_rtp_packets 0
|
webrtc_sessions_outbound_rtp_packets 0
|
||||||
webrtc_sessions_outbound_rtcp_packets 0
|
webrtc_sessions_outbound_rtcp_packets 0
|
||||||
|
webrtc_sessions_outbound_frames_discarded 0
|
||||||
webrtc_sessions_bytes_received 0
|
webrtc_sessions_bytes_received 0
|
||||||
webrtc_sessions_bytes_sent 0
|
webrtc_sessions_bytes_sent 0
|
||||||
webrtc_sessions_rtp_packets_received 0
|
webrtc_sessions_rtp_packets_received 0
|
||||||
@@ -395,40 +410,70 @@ webrtc_sessions_rtcp_packets_sent 0
|
|||||||
|
|
||||||
require.Regexp(t,
|
require.Regexp(t,
|
||||||
`^paths\{name=".*?",state="ready"\} 1`+"\n"+
|
`^paths\{name=".*?",state="ready"\} 1`+"\n"+
|
||||||
|
`paths_inbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_outbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_inbound_frames_in_error\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
||||||
|
`paths_inbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_outbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_inbound_frames_in_error\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
||||||
|
`paths_inbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_outbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_inbound_frames_in_error\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
||||||
|
`paths_inbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_outbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_inbound_frames_in_error\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
||||||
|
`paths_inbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_outbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_inbound_frames_in_error\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
`paths\{name=".*?",state="ready"\} 1`+"\n"+
|
||||||
|
`paths_inbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_outbound_bytes\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
|
`paths_inbound_frames_in_error\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_received\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_bytes_sent\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
`paths_readers\{name=".*?",state="ready"\} [0-9]+`+"\n"+
|
||||||
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
||||||
|
`hls_muxers_outbound_bytes\{name=".*?"\} 0`+"\n"+
|
||||||
|
`hls_muxers_outbound_frames_discarded\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
||||||
|
`hls_muxers_outbound_bytes\{name=".*?"\} 0`+"\n"+
|
||||||
|
`hls_muxers_outbound_frames_discarded\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
||||||
|
`hls_muxers_outbound_bytes\{name=".*?"\} 0`+"\n"+
|
||||||
|
`hls_muxers_outbound_frames_discarded\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
||||||
|
`hls_muxers_outbound_bytes\{name=".*?"\} 0`+"\n"+
|
||||||
|
`hls_muxers_outbound_frames_discarded\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
||||||
|
`hls_muxers_outbound_bytes\{name=".*?"\} 0`+"\n"+
|
||||||
|
`hls_muxers_outbound_frames_discarded\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
`hls_muxers\{name=".*?"\} 1`+"\n"+
|
||||||
|
`hls_muxers_outbound_bytes\{name=".*?"\} 0`+"\n"+
|
||||||
|
`hls_muxers_outbound_frames_discarded\{name=".*?"\} 0`+"\n"+
|
||||||
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
`hls_muxers_bytes_sent\{name=".*?"\} 0`+"\n"+
|
||||||
`rtsp_conns\{id=".*?"\} 1`+"\n"+
|
`rtsp_conns\{id=".*?"\} 1`+"\n"+
|
||||||
`rtsp_conns_inbound_bytes\{id=".*?"\} [0-9]+`+"\n"+
|
`rtsp_conns_inbound_bytes\{id=".*?"\} [0-9]+`+"\n"+
|
||||||
@@ -447,6 +492,8 @@ webrtc_sessions_rtcp_packets_sent 0
|
|||||||
`rtsp_sessions_outbound_rtp_packets\{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=".*?",`+
|
`rtsp_sessions_outbound_rtp_packets_reported_lost\{id=".*?",path=".*?",`+
|
||||||
`remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
|
`rtsp_sessions_outbound_rtp_packets_discarded\{id=".*?",path=".*?",`+
|
||||||
|
`remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtsp_sessions_outbound_rtcp_packets\{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_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 0`+"\n"+
|
||||||
`rtsp_sessions_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`rtsp_sessions_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
@@ -475,6 +522,8 @@ webrtc_sessions_rtcp_packets_sent 0
|
|||||||
`rtsps_sessions_outbound_rtp_packets\{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=".*?",`+
|
`rtsps_sessions_outbound_rtp_packets_reported_lost\{id=".*?",path=".*?",`+
|
||||||
`remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
|
`rtsps_sessions_outbound_rtp_packets_discarded\{id=".*?",path=".*?",`+
|
||||||
|
`remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtsps_sessions_outbound_rtcp_packets\{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_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 0`+"\n"+
|
||||||
`rtsps_sessions_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`rtsps_sessions_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
@@ -487,9 +536,15 @@ webrtc_sessions_rtcp_packets_sent 0
|
|||||||
`rtsps_sessions_rtcp_packets_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`rtsps_sessions_rtcp_packets_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtsps_sessions_rtcp_packets_in_error\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`rtsps_sessions_rtcp_packets_in_error\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtmp_conns\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
|
`rtmp_conns\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
|
||||||
|
`rtmp_conns_inbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
|
`rtmp_conns_outbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
|
`rtmp_conns_outbound_frames_discarded\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtmp_conns_bytes_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`rtmp_conns_bytes_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtmp_conns_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`rtmp_conns_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtmps_conns\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
|
`rtmps_conns\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
|
||||||
|
`rtmps_conns_inbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
|
`rtmps_conns_outbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
|
`rtmps_conns_outbound_frames_discarded\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtmps_conns_bytes_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`rtmps_conns_bytes_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`rtmps_conns_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`rtmps_conns_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`srt_conns\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
|
`srt_conns\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
|
||||||
@@ -546,6 +601,7 @@ webrtc_sessions_rtcp_packets_sent 0
|
|||||||
`srt_conns_packets_received_avg_belated_time\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`srt_conns_packets_received_avg_belated_time\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`srt_conns_packets_send_loss_rate\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`srt_conns_packets_send_loss_rate\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`srt_conns_packets_received_loss_rate\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`srt_conns_packets_received_loss_rate\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
|
`srt_conns_outbound_frames_discarded\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`webrtc_sessions\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
|
`webrtc_sessions\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} 1`+"\n"+
|
||||||
`webrtc_sessions_inbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`webrtc_sessions_inbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`webrtc_sessions_inbound_rtp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`webrtc_sessions_inbound_rtp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
@@ -555,6 +611,7 @@ webrtc_sessions_rtcp_packets_sent 0
|
|||||||
`webrtc_sessions_outbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`webrtc_sessions_outbound_bytes\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`webrtc_sessions_outbound_rtp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`webrtc_sessions_outbound_rtp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`webrtc_sessions_outbound_rtcp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`webrtc_sessions_outbound_rtcp_packets\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
|
`webrtc_sessions_outbound_frames_discarded\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`webrtc_sessions_bytes_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`webrtc_sessions_bytes_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`webrtc_sessions_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`webrtc_sessions_bytes_sent\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
`webrtc_sessions_rtp_packets_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
`webrtc_sessions_rtp_packets_received\{id=".*?",path=".*?",remoteAddr=".*?",state="publish"\} [0-9]+`+"\n"+
|
||||||
@@ -584,6 +641,9 @@ webrtc_sessions_rtcp_packets_sent 0
|
|||||||
bo := httpPullFile(t, hc, "http://localhost:9998/metrics")
|
bo := httpPullFile(t, hc, "http://localhost:9998/metrics")
|
||||||
|
|
||||||
require.Equal(t, "paths 0\n"+
|
require.Equal(t, "paths 0\n"+
|
||||||
|
"paths_inbound_bytes 0\n"+
|
||||||
|
"paths_outbound_bytes 0\n"+
|
||||||
|
"paths_inbound_frames_in_error 0\n"+
|
||||||
"paths_bytes_received 0\n"+
|
"paths_bytes_received 0\n"+
|
||||||
"paths_bytes_sent 0\n"+
|
"paths_bytes_sent 0\n"+
|
||||||
"paths_readers 0\n",
|
"paths_readers 0\n",
|
||||||
|
|||||||
@@ -661,6 +661,24 @@ func (pa *path) doAPIPathsGet(req pathAPIPathsGetReq) {
|
|||||||
}
|
}
|
||||||
return defs.MediasToCodecs(pa.stream.Desc.Medias)
|
return defs.MediasToCodecs(pa.stream.Desc.Medias)
|
||||||
}(),
|
}(),
|
||||||
|
InboundBytes: func() uint64 {
|
||||||
|
if !pa.isAvailable() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return pa.stream.InboundBytes()
|
||||||
|
}(),
|
||||||
|
OutboundBytes: func() uint64 {
|
||||||
|
if !pa.isAvailable() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return pa.stream.OutboundBytes()
|
||||||
|
}(),
|
||||||
|
InboundFramesInError: func() uint64 {
|
||||||
|
if !pa.isAvailable() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return pa.stream.InboundFramesInError()
|
||||||
|
}(),
|
||||||
BytesReceived: func() uint64 {
|
BytesReceived: func() uint64 {
|
||||||
if !pa.isAvailable() {
|
if !pa.isAvailable() {
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
package counterdumper
|
package counterdumper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync/atomic"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,7 +14,9 @@ const (
|
|||||||
type Dumper struct {
|
type Dumper struct {
|
||||||
OnReport func(v uint64)
|
OnReport func(v uint64)
|
||||||
|
|
||||||
counter *uint64
|
mutex sync.Mutex
|
||||||
|
counter uint64
|
||||||
|
absCounter uint64
|
||||||
|
|
||||||
terminate chan struct{}
|
terminate chan struct{}
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
@@ -22,7 +24,6 @@ type Dumper struct {
|
|||||||
|
|
||||||
// Start starts the counter.
|
// Start starts the counter.
|
||||||
func (c *Dumper) Start() {
|
func (c *Dumper) Start() {
|
||||||
c.counter = new(uint64)
|
|
||||||
c.terminate = make(chan struct{})
|
c.terminate = make(chan struct{})
|
||||||
c.done = make(chan struct{})
|
c.done = make(chan struct{})
|
||||||
|
|
||||||
@@ -37,12 +38,25 @@ func (c *Dumper) Stop() {
|
|||||||
|
|
||||||
// Increase increases the counter value by 1.
|
// Increase increases the counter value by 1.
|
||||||
func (c *Dumper) Increase() {
|
func (c *Dumper) Increase() {
|
||||||
atomic.AddUint64(c.counter, 1)
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
c.counter++
|
||||||
|
c.absCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add adds value to the counter.
|
// Add adds value to the counter.
|
||||||
func (c *Dumper) Add(v uint64) {
|
func (c *Dumper) Add(v uint64) {
|
||||||
atomic.AddUint64(c.counter, v)
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
c.counter += v
|
||||||
|
c.absCounter += v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns the counter value.
|
||||||
|
func (c *Dumper) Get() uint64 {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
return c.absCounter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Dumper) run() {
|
func (c *Dumper) run() {
|
||||||
@@ -57,7 +71,11 @@ func (c *Dumper) run() {
|
|||||||
return
|
return
|
||||||
|
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
v := atomic.SwapUint64(c.counter, 0)
|
c.mutex.Lock()
|
||||||
|
var v uint64
|
||||||
|
v, c.counter = c.counter, 0
|
||||||
|
c.mutex.Unlock()
|
||||||
|
|
||||||
if v != 0 {
|
if v != 0 {
|
||||||
c.OnReport(v)
|
c.OnReport(v)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,13 @@ type APIHLSServer interface {
|
|||||||
|
|
||||||
// APIHLSMuxer is an HLS muxer.
|
// APIHLSMuxer is an HLS muxer.
|
||||||
type APIHLSMuxer struct {
|
type APIHLSMuxer struct {
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
LastRequest time.Time `json:"lastRequest"`
|
LastRequest time.Time `json:"lastRequest"`
|
||||||
BytesSent uint64 `json:"bytesSent"`
|
OutboundBytes uint64 `json:"outboundBytes"`
|
||||||
|
OutboundFramesDiscarded uint64 `json:"outboundFramesDiscarded"`
|
||||||
|
// deprecated
|
||||||
|
BytesSent uint64 `json:"bytesSent" deprecated:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIHLSMuxerList is a list of HLS muxers.
|
// APIHLSMuxerList is a list of HLS muxers.
|
||||||
|
|||||||
+17
-13
@@ -63,19 +63,23 @@ type APIPathReader struct {
|
|||||||
|
|
||||||
// APIPath is a path.
|
// APIPath is a path.
|
||||||
type APIPath struct {
|
type APIPath struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ConfName string `json:"confName"`
|
ConfName string `json:"confName"`
|
||||||
Ready bool `json:"ready" deprecated:"true"`
|
Ready bool `json:"ready" deprecated:"true"`
|
||||||
ReadyTime *time.Time `json:"readyTime" deprecated:"true"`
|
ReadyTime *time.Time `json:"readyTime" deprecated:"true"`
|
||||||
Available bool `json:"available"`
|
Available bool `json:"available"`
|
||||||
AvailableTime *time.Time `json:"availableTime"`
|
AvailableTime *time.Time `json:"availableTime"`
|
||||||
Online bool `json:"online"`
|
Online bool `json:"online"`
|
||||||
OnlineTime *time.Time `json:"onlineTime"`
|
OnlineTime *time.Time `json:"onlineTime"`
|
||||||
Source *APIPathSource `json:"source"`
|
Source *APIPathSource `json:"source"`
|
||||||
Tracks []APIPathTrackCodec `json:"tracks"`
|
Tracks []APIPathTrackCodec `json:"tracks"`
|
||||||
BytesReceived uint64 `json:"bytesReceived"`
|
Readers []APIPathReader `json:"readers"`
|
||||||
BytesSent uint64 `json:"bytesSent"`
|
InboundBytes uint64 `json:"inboundBytes"`
|
||||||
Readers []APIPathReader `json:"readers"`
|
OutboundBytes uint64 `json:"outboundBytes"`
|
||||||
|
InboundFramesInError uint64 `json:"inboundFramesInError"`
|
||||||
|
// deprecated
|
||||||
|
BytesReceived uint64 `json:"bytesReceived" deprecated:"true"`
|
||||||
|
BytesSent uint64 `json:"bytesSent" deprecated:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIPathList is a list of paths.
|
// APIPathList is a list of paths.
|
||||||
|
|||||||
@@ -25,15 +25,19 @@ const (
|
|||||||
|
|
||||||
// APIRTMPConn is a RTMP connection.
|
// APIRTMPConn is a RTMP connection.
|
||||||
type APIRTMPConn struct {
|
type APIRTMPConn struct {
|
||||||
ID uuid.UUID `json:"id"`
|
ID uuid.UUID `json:"id"`
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
RemoteAddr string `json:"remoteAddr"`
|
RemoteAddr string `json:"remoteAddr"`
|
||||||
State APIRTMPConnState `json:"state"`
|
State APIRTMPConnState `json:"state"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Query string `json:"query"`
|
Query string `json:"query"`
|
||||||
User string `json:"user"`
|
User string `json:"user"`
|
||||||
BytesReceived uint64 `json:"bytesReceived"`
|
InboundBytes uint64 `json:"inboundBytes"`
|
||||||
BytesSent uint64 `json:"bytesSent"`
|
OutboundBytes uint64 `json:"outboundBytes"`
|
||||||
|
OutboundFramesDiscarded uint64 `json:"outboundFramesDiscarded"`
|
||||||
|
// deprecated
|
||||||
|
BytesReceived uint64 `json:"bytesReceived" deprecated:"true"`
|
||||||
|
BytesSent uint64 `json:"bytesSent" deprecated:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIRTMPConnList is a list of RTMP connections.
|
// APIRTMPConnList is a list of RTMP connections.
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ type APIRTSPSession struct {
|
|||||||
OutboundBytes uint64 `json:"outboundBytes"`
|
OutboundBytes uint64 `json:"outboundBytes"`
|
||||||
OutboundRTPPackets uint64 `json:"outboundRTPPackets"`
|
OutboundRTPPackets uint64 `json:"outboundRTPPackets"`
|
||||||
OutboundRTPPacketsReportedLost uint64 `json:"outboundRTPPacketsReportedLost"`
|
OutboundRTPPacketsReportedLost uint64 `json:"outboundRTPPacketsReportedLost"`
|
||||||
|
OutboundRTPPacketsDiscarded uint64 `json:"outboundRTPPacketsDiscarded"`
|
||||||
OutboundRTCPPackets uint64 `json:"outboundRTCPPackets"`
|
OutboundRTCPPackets uint64 `json:"outboundRTCPPackets"`
|
||||||
// deprecated
|
// deprecated
|
||||||
BytesReceived uint64 `json:"bytesReceived" deprecated:"true"`
|
BytesReceived uint64 `json:"bytesReceived" deprecated:"true"`
|
||||||
|
|||||||
@@ -153,6 +153,8 @@ type APISRTConn struct {
|
|||||||
PacketsSendLossRate float64 `json:"packetsSendLossRate"`
|
PacketsSendLossRate float64 `json:"packetsSendLossRate"`
|
||||||
// Percentage of retransmitted data vs. received data
|
// Percentage of retransmitted data vs. received data
|
||||||
PacketsReceivedLossRate float64 `json:"packetsReceivedLossRate"`
|
PacketsReceivedLossRate float64 `json:"packetsReceivedLossRate"`
|
||||||
|
|
||||||
|
OutboundFramesDiscarded uint64 `json:"outboundFramesDiscarded"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// APISRTConnList is a list of SRT connections.
|
// APISRTConnList is a list of SRT connections.
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ type APIWebRTCSession struct {
|
|||||||
OutboundBytes uint64 `json:"outboundBytes"`
|
OutboundBytes uint64 `json:"outboundBytes"`
|
||||||
OutboundRTPPackets uint64 `json:"outboundRTPPackets"`
|
OutboundRTPPackets uint64 `json:"outboundRTPPackets"`
|
||||||
OutboundRTCPPackets uint64 `json:"outboundRTCPPackets"`
|
OutboundRTCPPackets uint64 `json:"outboundRTCPPackets"`
|
||||||
|
OutboundFramesDiscarded uint64 `json:"outboundFramesDiscarded"`
|
||||||
// deprecated
|
// deprecated
|
||||||
BytesReceived uint64 `json:"bytesReceived" deprecated:"true"`
|
BytesReceived uint64 `json:"bytesReceived" deprecated:"true"`
|
||||||
BytesSent uint64 `json:"bytesSent" deprecated:"true"`
|
BytesSent uint64 `json:"bytesSent" deprecated:"true"`
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ const (
|
|||||||
type Dumper struct {
|
type Dumper struct {
|
||||||
OnReport func(v uint64, last error)
|
OnReport func(v uint64, last error)
|
||||||
|
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
counter uint64
|
counter uint64
|
||||||
last error
|
absCounter uint64
|
||||||
|
last error
|
||||||
|
|
||||||
terminate chan struct{}
|
terminate chan struct{}
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
@@ -41,9 +42,17 @@ func (c *Dumper) Add(err error) {
|
|||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
defer c.mutex.Unlock()
|
defer c.mutex.Unlock()
|
||||||
c.counter++
|
c.counter++
|
||||||
|
c.absCounter++
|
||||||
c.last = err
|
c.last = err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get returns the total number of errors.
|
||||||
|
func (c *Dumper) Get() uint64 {
|
||||||
|
c.mutex.Lock()
|
||||||
|
defer c.mutex.Unlock()
|
||||||
|
return c.absCounter
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Dumper) run() {
|
func (c *Dumper) run() {
|
||||||
defer close(c.done)
|
defer close(c.done)
|
||||||
|
|
||||||
|
|||||||
@@ -223,6 +223,10 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
"state": state,
|
"state": state,
|
||||||
})
|
})
|
||||||
out += metric("paths", ta, 1)
|
out += metric("paths", ta, 1)
|
||||||
|
out += metric("paths_inbound_bytes", ta, int64(i.InboundBytes))
|
||||||
|
out += metric("paths_outbound_bytes", ta, int64(i.OutboundBytes))
|
||||||
|
out += metric("paths_inbound_frames_in_error", ta, int64(i.InboundFramesInError))
|
||||||
|
// deprecated
|
||||||
out += metric("paths_bytes_received", ta, int64(i.BytesReceived))
|
out += metric("paths_bytes_received", ta, int64(i.BytesReceived))
|
||||||
out += metric("paths_bytes_sent", ta, int64(i.BytesSent))
|
out += metric("paths_bytes_sent", ta, int64(i.BytesSent))
|
||||||
out += metric("paths_readers", ta, int64(len(i.Readers)))
|
out += metric("paths_readers", ta, int64(len(i.Readers)))
|
||||||
@@ -230,6 +234,10 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
} else if pathFilter == "" {
|
} else if pathFilter == "" {
|
||||||
out += metric("paths", "", 0)
|
out += metric("paths", "", 0)
|
||||||
|
out += metric("paths_inbound_bytes", "", 0)
|
||||||
|
out += metric("paths_outbound_bytes", "", 0)
|
||||||
|
out += metric("paths_inbound_frames_in_error", "", 0)
|
||||||
|
// deprecated
|
||||||
out += metric("paths_bytes_received", "", 0)
|
out += metric("paths_bytes_received", "", 0)
|
||||||
out += metric("paths_bytes_sent", "", 0)
|
out += metric("paths_bytes_sent", "", 0)
|
||||||
out += metric("paths_readers", "", 0)
|
out += metric("paths_readers", "", 0)
|
||||||
@@ -248,11 +256,17 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
"name": i.Path,
|
"name": i.Path,
|
||||||
})
|
})
|
||||||
out += metric("hls_muxers", ta, 1)
|
out += metric("hls_muxers", ta, 1)
|
||||||
|
out += metric("hls_muxers_outbound_bytes", ta, int64(i.OutboundBytes))
|
||||||
|
out += metric("hls_muxers_outbound_frames_discarded", ta, int64(i.OutboundFramesDiscarded))
|
||||||
|
// deprecated
|
||||||
out += metric("hls_muxers_bytes_sent", ta, int64(i.BytesSent))
|
out += metric("hls_muxers_bytes_sent", ta, int64(i.BytesSent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if hlsMuxerFilter == "" {
|
} else if hlsMuxerFilter == "" {
|
||||||
out += metric("hls_muxers", "", 0)
|
out += metric("hls_muxers", "", 0)
|
||||||
|
out += metric("hls_muxers_outbound_bytes", "", 0)
|
||||||
|
out += metric("hls_muxers_outbound_frames_discarded", "", 0)
|
||||||
|
// deprecated
|
||||||
out += metric("hls_muxers_bytes_sent", "", 0)
|
out += metric("hls_muxers_bytes_sent", "", 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,6 +322,7 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
out += metric("rtsp_sessions_outbound_bytes", ta, int64(i.OutboundBytes))
|
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", ta, int64(i.OutboundRTPPackets))
|
||||||
out += metric("rtsp_sessions_outbound_rtp_packets_reported_lost", ta, int64(i.OutboundRTPPacketsReportedLost))
|
out += metric("rtsp_sessions_outbound_rtp_packets_reported_lost", ta, int64(i.OutboundRTPPacketsReportedLost))
|
||||||
|
out += metric("rtsp_sessions_outbound_rtp_packets_discarded", ta, int64(i.OutboundRTPPacketsDiscarded))
|
||||||
out += metric("rtsp_sessions_outbound_rtcp_packets", ta, int64(i.OutboundRTCPPackets))
|
out += metric("rtsp_sessions_outbound_rtcp_packets", ta, int64(i.OutboundRTCPPackets))
|
||||||
// deprecated
|
// deprecated
|
||||||
out += metric("rtsp_sessions_bytes_received", ta, int64(i.BytesReceived))
|
out += metric("rtsp_sessions_bytes_received", ta, int64(i.BytesReceived))
|
||||||
@@ -334,6 +349,7 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
out += metric("rtsp_sessions_outbound_bytes", "", 0)
|
out += metric("rtsp_sessions_outbound_bytes", "", 0)
|
||||||
out += metric("rtsp_sessions_outbound_rtp_packets", "", 0)
|
out += metric("rtsp_sessions_outbound_rtp_packets", "", 0)
|
||||||
out += metric("rtsp_sessions_outbound_rtp_packets_reported_lost", "", 0)
|
out += metric("rtsp_sessions_outbound_rtp_packets_reported_lost", "", 0)
|
||||||
|
out += metric("rtsp_sessions_outbound_rtp_packets_discarded", "", 0)
|
||||||
out += metric("rtsp_sessions_outbound_rtcp_packets", "", 0)
|
out += metric("rtsp_sessions_outbound_rtcp_packets", "", 0)
|
||||||
// deprecated
|
// deprecated
|
||||||
out += metric("rtsp_sessions_bytes_received", "", 0)
|
out += metric("rtsp_sessions_bytes_received", "", 0)
|
||||||
@@ -401,6 +417,7 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
out += metric("rtsps_sessions_outbound_bytes", ta, int64(i.OutboundBytes))
|
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", ta, int64(i.OutboundRTPPackets))
|
||||||
out += metric("rtsps_sessions_outbound_rtp_packets_reported_lost", ta, int64(i.OutboundRTPPacketsReportedLost))
|
out += metric("rtsps_sessions_outbound_rtp_packets_reported_lost", ta, int64(i.OutboundRTPPacketsReportedLost))
|
||||||
|
out += metric("rtsps_sessions_outbound_rtp_packets_discarded", ta, int64(i.OutboundRTPPacketsDiscarded))
|
||||||
out += metric("rtsps_sessions_outbound_rtcp_packets", ta, int64(i.OutboundRTCPPackets))
|
out += metric("rtsps_sessions_outbound_rtcp_packets", ta, int64(i.OutboundRTCPPackets))
|
||||||
// deprecated
|
// deprecated
|
||||||
out += metric("rtsps_sessions_bytes_received", ta, int64(i.BytesReceived))
|
out += metric("rtsps_sessions_bytes_received", ta, int64(i.BytesReceived))
|
||||||
@@ -427,6 +444,7 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
out += metric("rtsps_sessions_outbound_bytes", "", 0)
|
out += metric("rtsps_sessions_outbound_bytes", "", 0)
|
||||||
out += metric("rtsps_sessions_outbound_rtp_packets", "", 0)
|
out += metric("rtsps_sessions_outbound_rtp_packets", "", 0)
|
||||||
out += metric("rtsps_sessions_outbound_rtp_packets_reported_lost", "", 0)
|
out += metric("rtsps_sessions_outbound_rtp_packets_reported_lost", "", 0)
|
||||||
|
out += metric("rtsps_sessions_outbound_rtp_packets_discarded", "", 0)
|
||||||
out += metric("rtsps_sessions_outbound_rtcp_packets", "", 0)
|
out += metric("rtsps_sessions_outbound_rtcp_packets", "", 0)
|
||||||
// deprecated
|
// deprecated
|
||||||
out += metric("rtsps_sessions_bytes_received", "", 0)
|
out += metric("rtsps_sessions_bytes_received", "", 0)
|
||||||
@@ -458,12 +476,20 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
"remoteAddr": i.RemoteAddr,
|
"remoteAddr": i.RemoteAddr,
|
||||||
})
|
})
|
||||||
out += metric("rtmp_conns", ta, 1)
|
out += metric("rtmp_conns", ta, 1)
|
||||||
|
out += metric("rtmp_conns_inbound_bytes", ta, int64(i.InboundBytes))
|
||||||
|
out += metric("rtmp_conns_outbound_bytes", ta, int64(i.OutboundBytes))
|
||||||
|
out += metric("rtmp_conns_outbound_frames_discarded", ta, int64(i.OutboundFramesDiscarded))
|
||||||
|
// deprecated
|
||||||
out += metric("rtmp_conns_bytes_received", ta, int64(i.BytesReceived))
|
out += metric("rtmp_conns_bytes_received", ta, int64(i.BytesReceived))
|
||||||
out += metric("rtmp_conns_bytes_sent", ta, int64(i.BytesSent))
|
out += metric("rtmp_conns_bytes_sent", ta, int64(i.BytesSent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if rtmpConnFilter == "" {
|
} else if rtmpConnFilter == "" {
|
||||||
out += metric("rtmp_conns", "", 0)
|
out += metric("rtmp_conns", "", 0)
|
||||||
|
out += metric("rtmp_conns_inbound_bytes", "", 0)
|
||||||
|
out += metric("rtmp_conns_outbound_bytes", "", 0)
|
||||||
|
out += metric("rtmp_conns_outbound_frames_discarded", "", 0)
|
||||||
|
// deprecated
|
||||||
out += metric("rtmp_conns_bytes_received", "", 0)
|
out += metric("rtmp_conns_bytes_received", "", 0)
|
||||||
out += metric("rtmp_conns_bytes_sent", "", 0)
|
out += metric("rtmp_conns_bytes_sent", "", 0)
|
||||||
}
|
}
|
||||||
@@ -484,12 +510,20 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
"remoteAddr": i.RemoteAddr,
|
"remoteAddr": i.RemoteAddr,
|
||||||
})
|
})
|
||||||
out += metric("rtmps_conns", ta, 1)
|
out += metric("rtmps_conns", ta, 1)
|
||||||
|
out += metric("rtmps_conns_inbound_bytes", ta, int64(i.InboundBytes))
|
||||||
|
out += metric("rtmps_conns_outbound_bytes", ta, int64(i.OutboundBytes))
|
||||||
|
out += metric("rtmps_conns_outbound_frames_discarded", ta, int64(i.OutboundFramesDiscarded))
|
||||||
|
// deprecated
|
||||||
out += metric("rtmps_conns_bytes_received", ta, int64(i.BytesReceived))
|
out += metric("rtmps_conns_bytes_received", ta, int64(i.BytesReceived))
|
||||||
out += metric("rtmps_conns_bytes_sent", ta, int64(i.BytesSent))
|
out += metric("rtmps_conns_bytes_sent", ta, int64(i.BytesSent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if rtmpsConnFilter == "" {
|
} else if rtmpsConnFilter == "" {
|
||||||
out += metric("rtmps_conns", "", 0)
|
out += metric("rtmps_conns", "", 0)
|
||||||
|
out += metric("rtmps_conns_inbound_bytes", "", 0)
|
||||||
|
out += metric("rtmps_conns_outbound_bytes", "", 0)
|
||||||
|
out += metric("rtmps_conns_outbound_frames_discarded", "", 0)
|
||||||
|
// deprecated
|
||||||
out += metric("rtmps_conns_bytes_received", "", 0)
|
out += metric("rtmps_conns_bytes_received", "", 0)
|
||||||
out += metric("rtmps_conns_bytes_sent", "", 0)
|
out += metric("rtmps_conns_bytes_sent", "", 0)
|
||||||
}
|
}
|
||||||
@@ -563,6 +597,7 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
out += metric("srt_conns_packets_received_avg_belated_time", ta, int64(i.PacketsReceivedAvgBelatedTime))
|
out += metric("srt_conns_packets_received_avg_belated_time", ta, int64(i.PacketsReceivedAvgBelatedTime))
|
||||||
out += metricFloat("srt_conns_packets_send_loss_rate", ta, i.PacketsSendLossRate)
|
out += metricFloat("srt_conns_packets_send_loss_rate", ta, i.PacketsSendLossRate)
|
||||||
out += metricFloat("srt_conns_packets_received_loss_rate", ta, i.PacketsReceivedLossRate)
|
out += metricFloat("srt_conns_packets_received_loss_rate", ta, i.PacketsReceivedLossRate)
|
||||||
|
out += metric("srt_conns_outbound_frames_discarded", ta, int64(i.OutboundFramesDiscarded))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if srtConnFilter == "" {
|
} else if srtConnFilter == "" {
|
||||||
@@ -620,6 +655,7 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
out += metric("srt_conns_packets_received_avg_belated_time", "", 0)
|
out += metric("srt_conns_packets_received_avg_belated_time", "", 0)
|
||||||
out += metricFloat("srt_conns_packets_send_loss_rate", "", 0)
|
out += metricFloat("srt_conns_packets_send_loss_rate", "", 0)
|
||||||
out += metricFloat("srt_conns_packets_received_loss_rate", "", 0)
|
out += metricFloat("srt_conns_packets_received_loss_rate", "", 0)
|
||||||
|
out += metric("srt_conns_outbound_frames_discarded", "", 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,6 +682,7 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
out += metric("webrtc_sessions_outbound_bytes", ta, int64(i.OutboundBytes))
|
out += metric("webrtc_sessions_outbound_bytes", ta, int64(i.OutboundBytes))
|
||||||
out += metric("webrtc_sessions_outbound_rtp_packets", ta, int64(i.OutboundRTPPackets))
|
out += metric("webrtc_sessions_outbound_rtp_packets", ta, int64(i.OutboundRTPPackets))
|
||||||
out += metric("webrtc_sessions_outbound_rtcp_packets", ta, int64(i.OutboundRTCPPackets))
|
out += metric("webrtc_sessions_outbound_rtcp_packets", ta, int64(i.OutboundRTCPPackets))
|
||||||
|
out += metric("webrtc_sessions_outbound_frames_discarded", ta, int64(i.OutboundFramesDiscarded))
|
||||||
// deprecated
|
// deprecated
|
||||||
out += metric("webrtc_sessions_bytes_received", ta, int64(i.BytesReceived))
|
out += metric("webrtc_sessions_bytes_received", ta, int64(i.BytesReceived))
|
||||||
out += metric("webrtc_sessions_bytes_sent", ta, int64(i.BytesSent))
|
out += metric("webrtc_sessions_bytes_sent", ta, int64(i.BytesSent))
|
||||||
@@ -667,6 +704,7 @@ func (m *Metrics) onMetrics(ctx *gin.Context) {
|
|||||||
out += metric("webrtc_sessions_outbound_bytes", "", 0)
|
out += metric("webrtc_sessions_outbound_bytes", "", 0)
|
||||||
out += metric("webrtc_sessions_outbound_rtp_packets", "", 0)
|
out += metric("webrtc_sessions_outbound_rtp_packets", "", 0)
|
||||||
out += metric("webrtc_sessions_outbound_rtcp_packets", "", 0)
|
out += metric("webrtc_sessions_outbound_rtcp_packets", "", 0)
|
||||||
|
out += metric("webrtc_sessions_outbound_frames_discarded", "", 0)
|
||||||
// deprecated
|
// deprecated
|
||||||
out += metric("webrtc_sessions_bytes_received", "", 0)
|
out += metric("webrtc_sessions_bytes_received", "", 0)
|
||||||
out += metric("webrtc_sessions_bytes_sent", "", 0)
|
out += metric("webrtc_sessions_bytes_sent", "", 0)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -22,6 +23,18 @@ func ptrOf[T any](v T) *T {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func requireMetricsLines(t *testing.T, body []byte, lines []string) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
got := string(body)
|
||||||
|
for _, line := range lines {
|
||||||
|
require.Contains(t, got, line+"\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
nonEmptyLines := strings.Count(strings.TrimSpace(got), "\n") + 1
|
||||||
|
require.GreaterOrEqual(t, nonEmptyLines, len(lines))
|
||||||
|
}
|
||||||
|
|
||||||
type dummyPathManager struct{}
|
type dummyPathManager struct{}
|
||||||
|
|
||||||
func (dummyPathManager) APIPathsList() (*defs.APIPathList, error) {
|
func (dummyPathManager) APIPathsList() (*defs.APIPathList, error) {
|
||||||
@@ -35,11 +48,14 @@ func (dummyPathManager) APIPathsList() (*defs.APIPathList, error) {
|
|||||||
Type: defs.APIPathSourceTypeRTSPSession,
|
Type: defs.APIPathSourceTypeRTSPSession,
|
||||||
ID: "123324354",
|
ID: "123324354",
|
||||||
},
|
},
|
||||||
Ready: true,
|
Ready: true,
|
||||||
ReadyTime: ptrOf(time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC)),
|
ReadyTime: ptrOf(time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC)),
|
||||||
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecH265},
|
Tracks: []defs.APIPathTrackCodec{defs.APIPathTrackCodecH264, defs.APIPathTrackCodecH265},
|
||||||
BytesReceived: 123,
|
InboundBytes: 123,
|
||||||
BytesSent: 456,
|
OutboundBytes: 456,
|
||||||
|
InboundFramesInError: 7,
|
||||||
|
BytesReceived: 123,
|
||||||
|
BytesSent: 456,
|
||||||
Readers: []defs.APIPathReader{
|
Readers: []defs.APIPathReader{
|
||||||
{
|
{
|
||||||
Type: defs.APIPathReaderTypeRTSPSession,
|
Type: defs.APIPathReaderTypeRTSPSession,
|
||||||
@@ -61,10 +77,12 @@ func (dummyHLSServer) APIMuxersList() (*defs.APIHLSMuxerList, error) {
|
|||||||
ItemCount: 1,
|
ItemCount: 1,
|
||||||
PageCount: 1,
|
PageCount: 1,
|
||||||
Items: []defs.APIHLSMuxer{{
|
Items: []defs.APIHLSMuxer{{
|
||||||
Path: "mypath",
|
Path: "mypath",
|
||||||
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||||
LastRequest: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
LastRequest: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||||
BytesSent: 789,
|
OutboundBytes: 789,
|
||||||
|
OutboundFramesDiscarded: 12,
|
||||||
|
BytesSent: 789,
|
||||||
}},
|
}},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -118,6 +136,7 @@ func (dummyRTSPServer) APISessionsList() (*defs.APIRTSPSessionList, error) {
|
|||||||
OutboundBytes: 456,
|
OutboundBytes: 456,
|
||||||
OutboundRTPPackets: 123,
|
OutboundRTPPackets: 123,
|
||||||
OutboundRTPPacketsReportedLost: 321,
|
OutboundRTPPacketsReportedLost: 321,
|
||||||
|
OutboundRTPPacketsDiscarded: 111,
|
||||||
OutboundRTCPPackets: 789,
|
OutboundRTCPPackets: 789,
|
||||||
BytesReceived: 123,
|
BytesReceived: 123,
|
||||||
BytesSent: 456,
|
BytesSent: 456,
|
||||||
@@ -148,14 +167,17 @@ func (dummyRTMPServer) APIConnsList() (*defs.APIRTMPConnList, error) {
|
|||||||
ItemCount: 1,
|
ItemCount: 1,
|
||||||
PageCount: 1,
|
PageCount: 1,
|
||||||
Items: []defs.APIRTMPConn{{
|
Items: []defs.APIRTMPConn{{
|
||||||
ID: uuid.MustParse("9a07afe4-fc07-4c9b-be6e-6255720c36d0"),
|
ID: uuid.MustParse("9a07afe4-fc07-4c9b-be6e-6255720c36d0"),
|
||||||
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
Created: time.Date(2003, 11, 4, 23, 15, 7, 0, time.UTC),
|
||||||
RemoteAddr: "3.3.3.3:5678",
|
RemoteAddr: "3.3.3.3:5678",
|
||||||
State: defs.APIRTMPConnStateRead,
|
State: defs.APIRTMPConnStateRead,
|
||||||
Path: "mypath",
|
Path: "mypath",
|
||||||
Query: "myquery",
|
Query: "myquery",
|
||||||
BytesReceived: 123,
|
InboundBytes: 123,
|
||||||
BytesSent: 456,
|
OutboundBytes: 456,
|
||||||
|
OutboundFramesDiscarded: 12,
|
||||||
|
BytesReceived: 123,
|
||||||
|
BytesSent: 456,
|
||||||
}},
|
}},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -192,6 +214,7 @@ func (dummyWebRTCServer) APISessionsList() (*defs.APIWebRTCSessionList, error) {
|
|||||||
OutboundBytes: 456,
|
OutboundBytes: 456,
|
||||||
OutboundRTPPackets: 123,
|
OutboundRTPPackets: 123,
|
||||||
OutboundRTCPPackets: 456,
|
OutboundRTCPPackets: 456,
|
||||||
|
OutboundFramesDiscarded: 12,
|
||||||
BytesReceived: 123,
|
BytesReceived: 123,
|
||||||
BytesSent: 456,
|
BytesSent: 456,
|
||||||
RTPPacketsReceived: 789,
|
RTPPacketsReceived: 789,
|
||||||
@@ -294,158 +317,35 @@ func TestMetrics(t *testing.T) {
|
|||||||
byts, err := io.ReadAll(res.Body)
|
byts, err := io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t,
|
requireMetricsLines(t, byts, []string{
|
||||||
`paths{name="mypath",state="ready"} 1`+"\n"+
|
`paths{name="mypath",state="ready"} 1`,
|
||||||
`paths_bytes_received{name="mypath",state="ready"} 123`+"\n"+
|
`paths_inbound_bytes{name="mypath",state="ready"} 123`,
|
||||||
`paths_bytes_sent{name="mypath",state="ready"} 456`+"\n"+
|
`paths_outbound_bytes{name="mypath",state="ready"} 456`,
|
||||||
`paths_readers{name="mypath",state="ready"} 1`+"\n"+
|
`paths_inbound_frames_in_error{name="mypath",state="ready"} 7`,
|
||||||
`hls_muxers{name="mypath"} 1`+"\n"+
|
`paths_bytes_received{name="mypath",state="ready"} 123`,
|
||||||
`hls_muxers_bytes_sent{name="mypath"} 789`+"\n"+
|
`paths_bytes_sent{name="mypath",state="ready"} 456`,
|
||||||
`rtsp_conns{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 1`+"\n"+
|
`paths_readers{name="mypath",state="ready"} 1`,
|
||||||
`rtsp_conns_inbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`+"\n"+
|
`hls_muxers{name="mypath"} 1`,
|
||||||
`rtsp_conns_outbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 456`+"\n"+
|
`hls_muxers_outbound_bytes{name="mypath"} 789`,
|
||||||
`rtsp_conns_bytes_received{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`+"\n"+
|
`hls_muxers_outbound_frames_discarded{name="mypath"} 12`,
|
||||||
`rtsp_conns_bytes_sent{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 456`+"\n"+
|
`rtsp_conns_inbound_bytes{id="18294761-f9d1-4ea9-9a35-fe265b62eb41"} 123`,
|
||||||
`rtsp_sessions{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`rtsp_sessions_outbound_rtp_packets_discarded{id="124b22ce-9c34-4387-b045-44caf98049f7",` +
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 1`+"\n"+
|
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 111`,
|
||||||
`rtsp_sessions_inbound_bytes{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`rtsps_sessions_outbound_rtp_packets_discarded{id="124b22ce-9c34-4387-b045-44caf98049f7",` +
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
|
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 111`,
|
||||||
`rtsp_sessions_inbound_rtp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`rtmp_conns_inbound_bytes{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",` +
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 123`,
|
||||||
`rtsp_sessions_inbound_rtp_packets_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`rtmp_conns_outbound_bytes{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",` +
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 456`,
|
||||||
`rtsp_sessions_inbound_rtp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`rtmp_conns_outbound_frames_discarded{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",` +
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 12`,
|
||||||
`rtsp_sessions_inbound_rtp_packets_jitter{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`rtmp_conns_bytes_received{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",` +
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
|
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 123`,
|
||||||
`rtsp_sessions_inbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`webrtc_sessions_outbound_bytes{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",` +
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 456`,
|
||||||
`rtsp_sessions_inbound_rtcp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`webrtc_sessions_outbound_frames_discarded{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",` +
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 12`,
|
||||||
`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",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
|
||||||
`rtsp_sessions_rtp_packets_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
|
||||||
`rtsp_sessions_rtp_packets_sent{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
|
|
||||||
`rtsp_sessions_rtp_packets_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
|
||||||
`rtsp_sessions_rtp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
|
||||||
`rtsp_sessions_rtp_packets_jitter{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
|
|
||||||
`rtsp_sessions_rtcp_packets_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
|
||||||
`rtsp_sessions_rtcp_packets_sent{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
|
||||||
`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",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
|
||||||
`rtsps_sessions_rtp_packets_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
|
||||||
`rtsps_sessions_rtp_packets_sent{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
|
|
||||||
`rtsps_sessions_rtp_packets_lost{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
|
||||||
`rtsps_sessions_rtp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
|
||||||
`rtsps_sessions_rtp_packets_jitter{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
|
|
||||||
`rtsps_sessions_rtcp_packets_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
|
||||||
`rtsps_sessions_rtcp_packets_sent{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
|
||||||
`rtsps_sessions_rtcp_packets_in_error{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 456`+"\n"+
|
|
||||||
`rtmp_conns{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",`+
|
|
||||||
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 1`+"\n"+
|
|
||||||
`rtmp_conns_bytes_received{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",`+
|
|
||||||
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 123`+"\n"+
|
|
||||||
`rtmp_conns_bytes_sent{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",`+
|
|
||||||
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 456`+"\n"+
|
|
||||||
`rtmps_conns{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",`+
|
|
||||||
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 1`+"\n"+
|
|
||||||
`rtmps_conns_bytes_received{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",`+
|
|
||||||
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 123`+"\n"+
|
|
||||||
`rtmps_conns_bytes_sent{id="9a07afe4-fc07-4c9b-be6e-6255720c36d0",`+
|
|
||||||
`path="mypath",remoteAddr="3.3.3.3:5678",state="read"} 456`+"\n"+
|
|
||||||
`webrtc_sessions{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 1`+"\n"+
|
|
||||||
`webrtc_sessions_inbound_bytes{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 123`+"\n"+
|
|
||||||
`webrtc_sessions_inbound_rtp_packets{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 789`+"\n"+
|
|
||||||
`webrtc_sessions_inbound_rtp_packets_lost{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 456`+"\n"+
|
|
||||||
`webrtc_sessions_inbound_rtp_packets_jitter{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 789`+"\n"+
|
|
||||||
`webrtc_sessions_inbound_rtcp_packets{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 123`+"\n"+
|
|
||||||
`webrtc_sessions_outbound_bytes{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 456`+"\n"+
|
|
||||||
`webrtc_sessions_outbound_rtp_packets{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 123`+"\n"+
|
|
||||||
`webrtc_sessions_outbound_rtcp_packets{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 456`+"\n"+
|
|
||||||
`webrtc_sessions_bytes_received{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 123`+"\n"+
|
|
||||||
`webrtc_sessions_bytes_sent{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 456`+"\n"+
|
|
||||||
`webrtc_sessions_rtp_packets_received{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 789`+"\n"+
|
|
||||||
`webrtc_sessions_rtp_packets_sent{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 123`+"\n"+
|
|
||||||
`webrtc_sessions_rtp_packets_lost{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 456`+"\n"+
|
|
||||||
`webrtc_sessions_rtp_packets_jitter{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 789`+"\n"+
|
|
||||||
`webrtc_sessions_rtcp_packets_received{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 123`+"\n"+
|
|
||||||
`webrtc_sessions_rtcp_packets_sent{id="f47ac10b-58cc-4372-a567-0e02b2c3d479",`+
|
|
||||||
`path="mypath",remoteAddr="127.0.0.1:3455",state="read"} 456`+"\n",
|
|
||||||
string(byts))
|
|
||||||
|
|
||||||
require.True(t, checked)
|
require.True(t, checked)
|
||||||
}
|
}
|
||||||
@@ -558,6 +458,9 @@ func TestFilter(t *testing.T) {
|
|||||||
case "path":
|
case "path":
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
`paths{name="mypath",state="ready"} 1`+"\n"+
|
`paths{name="mypath",state="ready"} 1`+"\n"+
|
||||||
|
`paths_inbound_bytes{name="mypath",state="ready"} 123`+"\n"+
|
||||||
|
`paths_outbound_bytes{name="mypath",state="ready"} 456`+"\n"+
|
||||||
|
`paths_inbound_frames_in_error{name="mypath",state="ready"} 7`+"\n"+
|
||||||
`paths_bytes_received{name="mypath",state="ready"} 123`+"\n"+
|
`paths_bytes_received{name="mypath",state="ready"} 123`+"\n"+
|
||||||
`paths_bytes_sent{name="mypath",state="ready"} 456`+"\n"+
|
`paths_bytes_sent{name="mypath",state="ready"} 456`+"\n"+
|
||||||
`paths_readers{name="mypath",state="ready"} 1`+"\n",
|
`paths_readers{name="mypath",state="ready"} 1`+"\n",
|
||||||
@@ -566,6 +469,8 @@ func TestFilter(t *testing.T) {
|
|||||||
case "hls_muxer":
|
case "hls_muxer":
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
`hls_muxers{name="mypath"} 1`+"\n"+
|
`hls_muxers{name="mypath"} 1`+"\n"+
|
||||||
|
`hls_muxers_outbound_bytes{name="mypath"} 789`+"\n"+
|
||||||
|
`hls_muxers_outbound_frames_discarded{name="mypath"} 12`+"\n"+
|
||||||
`hls_muxers_bytes_sent{name="mypath"} 789`+"\n",
|
`hls_muxers_bytes_sent{name="mypath"} 789`+"\n",
|
||||||
string(byts))
|
string(byts))
|
||||||
|
|
||||||
@@ -602,6 +507,8 @@ func TestFilter(t *testing.T) {
|
|||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 123`+"\n"+
|
`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",`+
|
`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"+
|
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 321`+"\n"+
|
||||||
|
`rtsp_sessions_outbound_rtp_packets_discarded{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
||||||
|
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 111`+"\n"+
|
||||||
`rtsp_sessions_outbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`rtsp_sessions_outbound_rtcp_packets{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
||||||
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
`path="mypath",remoteAddr="124.5.5.5:34542",state="publish"} 789`+"\n"+
|
||||||
`rtsp_sessions_bytes_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
`rtsp_sessions_bytes_received{id="124b22ce-9c34-4387-b045-44caf98049f7",`+
|
||||||
|
|||||||
@@ -203,13 +203,7 @@ func (s *httpServer) onRequest(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mi := mux.getInstance()
|
|
||||||
if mi == nil {
|
|
||||||
ctx.Writer.WriteHeader(http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Request.URL.Path = fname
|
ctx.Request.URL.Path = fname
|
||||||
mi.handleRequest(ctx)
|
mux.handleRequest(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import (
|
|||||||
"github.com/bluenviron/mediamtx/internal/defs"
|
"github.com/bluenviron/mediamtx/internal/defs"
|
||||||
"github.com/bluenviron/mediamtx/internal/logger"
|
"github.com/bluenviron/mediamtx/internal/logger"
|
||||||
"github.com/bluenviron/mediamtx/internal/protocols/hls"
|
"github.com/bluenviron/mediamtx/internal/protocols/hls"
|
||||||
|
"github.com/bluenviron/mediamtx/internal/stream"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -43,8 +45,13 @@ func (w *responseWriterWithCounter) Write(p []byte) (int, error) {
|
|||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type muxerGetInstanceRes struct {
|
||||||
|
instance *muxerInstance
|
||||||
|
cumulatedOutboundFramesDiscarded uint64
|
||||||
|
}
|
||||||
|
|
||||||
type muxerGetInstanceReq struct {
|
type muxerGetInstanceReq struct {
|
||||||
res chan *muxerInstance
|
res chan muxerGetInstanceRes
|
||||||
}
|
}
|
||||||
|
|
||||||
type muxer struct {
|
type muxer struct {
|
||||||
@@ -138,22 +145,7 @@ func (m *muxer) runInner() error {
|
|||||||
|
|
||||||
defer m.path.RemoveReader(defs.PathRemoveReaderReq{Author: m})
|
defer m.path.RemoveReader(defs.PathRemoveReaderReq{Author: m})
|
||||||
|
|
||||||
var instanceError chan error
|
mi, err := m.createInstance(res.Stream)
|
||||||
var recreateTimer *time.Timer
|
|
||||||
|
|
||||||
mi := &muxerInstance{
|
|
||||||
variant: m.variant,
|
|
||||||
segmentCount: m.segmentCount,
|
|
||||||
segmentDuration: m.segmentDuration,
|
|
||||||
partDuration: m.partDuration,
|
|
||||||
segmentMaxSize: m.segmentMaxSize,
|
|
||||||
directory: m.directory,
|
|
||||||
pathName: m.pathName,
|
|
||||||
stream: res.Stream,
|
|
||||||
bytesSent: m.bytesSent,
|
|
||||||
parent: m,
|
|
||||||
}
|
|
||||||
err = mi.initialize()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if m.remoteAddr != "" || errors.Is(err, hls.ErrNoSupportedCodecs) {
|
if m.remoteAddr != "" || errors.Is(err, hls.ErrNoSupportedCodecs) {
|
||||||
return err
|
return err
|
||||||
@@ -161,11 +153,6 @@ func (m *muxer) runInner() error {
|
|||||||
|
|
||||||
m.Log(logger.Error, err.Error())
|
m.Log(logger.Error, err.Error())
|
||||||
mi = nil
|
mi = nil
|
||||||
instanceError = make(chan error)
|
|
||||||
recreateTimer = time.NewTimer(recreatePause)
|
|
||||||
} else {
|
|
||||||
instanceError = mi.errorChan()
|
|
||||||
recreateTimer = emptyTimer()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -174,6 +161,17 @@ func (m *muxer) runInner() error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var instanceError chan error
|
||||||
|
var recreateTimer *time.Timer
|
||||||
|
|
||||||
|
if mi != nil {
|
||||||
|
instanceError = mi.errorChan()
|
||||||
|
recreateTimer = emptyTimer()
|
||||||
|
} else {
|
||||||
|
instanceError = make(chan error)
|
||||||
|
recreateTimer = time.NewTimer(recreatePause)
|
||||||
|
}
|
||||||
|
|
||||||
var activityCheckTimer *time.Timer
|
var activityCheckTimer *time.Timer
|
||||||
if m.remoteAddr != "" {
|
if m.remoteAddr != "" {
|
||||||
activityCheckTimer = time.NewTimer(closeCheckPeriod)
|
activityCheckTimer = time.NewTimer(closeCheckPeriod)
|
||||||
@@ -181,10 +179,15 @@ func (m *muxer) runInner() error {
|
|||||||
activityCheckTimer = emptyTimer()
|
activityCheckTimer = emptyTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cumulatedOutboundFramesDiscarded := uint64(0)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case req := <-m.chGetInstance:
|
case req := <-m.chGetInstance:
|
||||||
req.res <- mi
|
req.res <- muxerGetInstanceRes{
|
||||||
|
instance: mi,
|
||||||
|
cumulatedOutboundFramesDiscarded: cumulatedOutboundFramesDiscarded,
|
||||||
|
}
|
||||||
|
|
||||||
case err = <-instanceError:
|
case err = <-instanceError:
|
||||||
if m.remoteAddr != "" {
|
if m.remoteAddr != "" {
|
||||||
@@ -193,24 +196,13 @@ func (m *muxer) runInner() error {
|
|||||||
|
|
||||||
m.Log(logger.Error, err.Error())
|
m.Log(logger.Error, err.Error())
|
||||||
mi.close()
|
mi.close()
|
||||||
|
cumulatedOutboundFramesDiscarded += mi.reader.OutboundFramesDiscarded()
|
||||||
mi = nil
|
mi = nil
|
||||||
instanceError = make(chan error)
|
instanceError = make(chan error)
|
||||||
recreateTimer = time.NewTimer(recreatePause)
|
recreateTimer = time.NewTimer(recreatePause)
|
||||||
|
|
||||||
case <-recreateTimer.C:
|
case <-recreateTimer.C:
|
||||||
mi = &muxerInstance{
|
mi, err = m.createInstance(res.Stream)
|
||||||
variant: m.variant,
|
|
||||||
segmentCount: m.segmentCount,
|
|
||||||
segmentDuration: m.segmentDuration,
|
|
||||||
partDuration: m.partDuration,
|
|
||||||
segmentMaxSize: m.segmentMaxSize,
|
|
||||||
directory: m.directory,
|
|
||||||
pathName: m.pathName,
|
|
||||||
stream: res.Stream,
|
|
||||||
bytesSent: m.bytesSent,
|
|
||||||
parent: m,
|
|
||||||
}
|
|
||||||
err = mi.initialize()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.Log(logger.Error, err.Error())
|
m.Log(logger.Error, err.Error())
|
||||||
mi = nil
|
mi = nil
|
||||||
@@ -232,17 +224,31 @@ func (m *muxer) runInner() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *muxer) getInstance() *muxerInstance {
|
func (m *muxer) createInstance(strm *stream.Stream) (*muxerInstance, error) {
|
||||||
atomic.StoreInt64(m.lastRequestTime, time.Now().UnixNano())
|
mi := &muxerInstance{
|
||||||
|
variant: m.variant,
|
||||||
|
segmentCount: m.segmentCount,
|
||||||
|
segmentDuration: m.segmentDuration,
|
||||||
|
partDuration: m.partDuration,
|
||||||
|
segmentMaxSize: m.segmentMaxSize,
|
||||||
|
directory: m.directory,
|
||||||
|
pathName: m.pathName,
|
||||||
|
stream: strm,
|
||||||
|
parent: m,
|
||||||
|
}
|
||||||
|
err := mi.initialize()
|
||||||
|
return mi, err
|
||||||
|
}
|
||||||
|
|
||||||
req := muxerGetInstanceReq{res: make(chan *muxerInstance)}
|
func (m *muxer) getInstance() muxerGetInstanceRes {
|
||||||
|
req := muxerGetInstanceReq{res: make(chan muxerGetInstanceRes)}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case m.chGetInstance <- req:
|
case m.chGetInstance <- req:
|
||||||
return <-req.res
|
return <-req.res
|
||||||
|
|
||||||
case <-m.ctx.Done():
|
case <-m.ctx.Done():
|
||||||
return nil
|
return muxerGetInstanceRes{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,11 +260,37 @@ func (m *muxer) APIReaderDescribe() *defs.APIPathReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *muxer) handleRequest(ctx *gin.Context) {
|
||||||
|
atomic.StoreInt64(m.lastRequestTime, time.Now().UnixNano())
|
||||||
|
|
||||||
|
res := m.getInstance()
|
||||||
|
if res.instance == nil {
|
||||||
|
ctx.Writer.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w := &responseWriterWithCounter{
|
||||||
|
ResponseWriter: ctx.Writer,
|
||||||
|
bytesSent: m.bytesSent,
|
||||||
|
}
|
||||||
|
|
||||||
|
res.instance.handleRequest(w, ctx.Request)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *muxer) apiItem() *defs.APIHLSMuxer {
|
func (m *muxer) apiItem() *defs.APIHLSMuxer {
|
||||||
|
res := m.getInstance()
|
||||||
|
|
||||||
|
outboundFramesDiscarded := res.cumulatedOutboundFramesDiscarded
|
||||||
|
if res.instance != nil {
|
||||||
|
outboundFramesDiscarded += res.instance.reader.OutboundFramesDiscarded()
|
||||||
|
}
|
||||||
|
|
||||||
return &defs.APIHLSMuxer{
|
return &defs.APIHLSMuxer{
|
||||||
Path: m.pathName,
|
Path: m.pathName,
|
||||||
Created: m.created,
|
Created: m.created,
|
||||||
LastRequest: time.Unix(0, atomic.LoadInt64(m.lastRequestTime)),
|
LastRequest: time.Unix(0, atomic.LoadInt64(m.lastRequestTime)),
|
||||||
BytesSent: atomic.LoadUint64(m.bytesSent),
|
OutboundBytes: atomic.LoadUint64(m.bytesSent),
|
||||||
|
OutboundFramesDiscarded: outboundFramesDiscarded,
|
||||||
|
BytesSent: atomic.LoadUint64(m.bytesSent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package hls
|
package hls
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
@@ -11,7 +12,6 @@ import (
|
|||||||
"github.com/bluenviron/mediamtx/internal/logger"
|
"github.com/bluenviron/mediamtx/internal/logger"
|
||||||
"github.com/bluenviron/mediamtx/internal/protocols/hls"
|
"github.com/bluenviron/mediamtx/internal/protocols/hls"
|
||||||
"github.com/bluenviron/mediamtx/internal/stream"
|
"github.com/bluenviron/mediamtx/internal/stream"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type muxerInstance struct {
|
type muxerInstance struct {
|
||||||
@@ -23,7 +23,6 @@ type muxerInstance struct {
|
|||||||
directory string
|
directory string
|
||||||
pathName string
|
pathName string
|
||||||
stream *stream.Stream
|
stream *stream.Stream
|
||||||
bytesSent *uint64
|
|
||||||
parent logger.Writer
|
parent logger.Writer
|
||||||
|
|
||||||
hmuxer *gohlslib.Muxer
|
hmuxer *gohlslib.Muxer
|
||||||
@@ -89,11 +88,6 @@ func (mi *muxerInstance) errorChan() chan error {
|
|||||||
return mi.reader.Error()
|
return mi.reader.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mi *muxerInstance) handleRequest(ctx *gin.Context) {
|
func (mi *muxerInstance) handleRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
w := &responseWriterWithCounter{
|
mi.hmuxer.Handle(w, r)
|
||||||
ResponseWriter: ctx.Writer,
|
|
||||||
bytesSent: mi.bytesSent,
|
|
||||||
}
|
|
||||||
|
|
||||||
mi.hmuxer.Handle(w, ctx.Request)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ type conn struct {
|
|||||||
pathName string
|
pathName string
|
||||||
query string
|
query string
|
||||||
user string
|
user string
|
||||||
|
reader *stream.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) initialize() {
|
func (c *conn) initialize() {
|
||||||
@@ -210,6 +211,10 @@ func (c *conn) runRead() error {
|
|||||||
res.Stream.AddReader(r)
|
res.Stream.AddReader(r)
|
||||||
defer res.Stream.RemoveReader(r)
|
defer res.Stream.RemoveReader(r)
|
||||||
|
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.reader = r
|
||||||
|
c.mutex.Unlock()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-c.ctx.Done():
|
case <-c.ctx.Done():
|
||||||
return fmt.Errorf("terminated")
|
return fmt.Errorf("terminated")
|
||||||
@@ -320,21 +325,29 @@ func (c *conn) apiItem() *defs.APIRTMPConn {
|
|||||||
|
|
||||||
bytesReceived := uint64(0)
|
bytesReceived := uint64(0)
|
||||||
bytesSent := uint64(0)
|
bytesSent := uint64(0)
|
||||||
|
outboundFramesDiscarded := uint64(0)
|
||||||
|
|
||||||
if c.rconn != nil {
|
if c.rconn != nil {
|
||||||
bytesReceived = c.rconn.BytesReceived()
|
bytesReceived = c.rconn.BytesReceived()
|
||||||
bytesSent = c.rconn.BytesSent()
|
bytesSent = c.rconn.BytesSent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.reader != nil {
|
||||||
|
outboundFramesDiscarded = c.reader.OutboundFramesDiscarded()
|
||||||
|
}
|
||||||
|
|
||||||
return &defs.APIRTMPConn{
|
return &defs.APIRTMPConn{
|
||||||
ID: c.uuid,
|
ID: c.uuid,
|
||||||
Created: c.created,
|
Created: c.created,
|
||||||
RemoteAddr: c.remoteAddr().String(),
|
RemoteAddr: c.remoteAddr().String(),
|
||||||
State: c.state,
|
State: c.state,
|
||||||
Path: c.pathName,
|
Path: c.pathName,
|
||||||
Query: c.query,
|
Query: c.query,
|
||||||
User: c.user,
|
User: c.user,
|
||||||
BytesReceived: bytesReceived,
|
InboundBytes: bytesReceived,
|
||||||
BytesSent: bytesSent,
|
OutboundBytes: bytesSent,
|
||||||
|
BytesReceived: bytesReceived,
|
||||||
|
BytesSent: bytesSent,
|
||||||
|
OutboundFramesDiscarded: outboundFramesDiscarded,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,15 +196,18 @@ func TestServerPublish(t *testing.T) {
|
|||||||
require.Equal(t, &defs.APIRTMPConnList{
|
require.Equal(t, &defs.APIRTMPConnList{
|
||||||
Items: []defs.APIRTMPConn{
|
Items: []defs.APIRTMPConn{
|
||||||
{
|
{
|
||||||
ID: list.Items[0].ID,
|
ID: list.Items[0].ID,
|
||||||
Created: list.Items[0].Created,
|
Created: list.Items[0].Created,
|
||||||
RemoteAddr: list.Items[0].RemoteAddr,
|
RemoteAddr: list.Items[0].RemoteAddr,
|
||||||
State: "publish",
|
State: "publish",
|
||||||
Path: "teststream",
|
Path: "teststream",
|
||||||
Query: "user=myuser&pass=mypass¶m=value",
|
Query: "user=myuser&pass=mypass¶m=value",
|
||||||
User: "myuser",
|
User: "myuser",
|
||||||
BytesReceived: list.Items[0].BytesReceived,
|
InboundBytes: list.Items[0].InboundBytes,
|
||||||
BytesSent: list.Items[0].BytesSent,
|
OutboundBytes: list.Items[0].OutboundBytes,
|
||||||
|
OutboundFramesDiscarded: list.Items[0].OutboundFramesDiscarded,
|
||||||
|
BytesReceived: list.Items[0].BytesReceived,
|
||||||
|
BytesSent: list.Items[0].BytesSent,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, list)
|
}, list)
|
||||||
@@ -354,15 +357,18 @@ func TestServerRead(t *testing.T) {
|
|||||||
require.Equal(t, &defs.APIRTMPConnList{
|
require.Equal(t, &defs.APIRTMPConnList{
|
||||||
Items: []defs.APIRTMPConn{
|
Items: []defs.APIRTMPConn{
|
||||||
{
|
{
|
||||||
ID: list.Items[0].ID,
|
ID: list.Items[0].ID,
|
||||||
Created: list.Items[0].Created,
|
Created: list.Items[0].Created,
|
||||||
RemoteAddr: list.Items[0].RemoteAddr,
|
RemoteAddr: list.Items[0].RemoteAddr,
|
||||||
State: "read",
|
State: "read",
|
||||||
Path: "teststream",
|
Path: "teststream",
|
||||||
Query: "user=myuser&pass=mypass¶m=value",
|
Query: "user=myuser&pass=mypass¶m=value",
|
||||||
User: "myuser",
|
User: "myuser",
|
||||||
BytesReceived: list.Items[0].BytesReceived,
|
InboundBytes: list.Items[0].InboundBytes,
|
||||||
BytesSent: list.Items[0].BytesSent,
|
OutboundBytes: list.Items[0].OutboundBytes,
|
||||||
|
OutboundFramesDiscarded: list.Items[0].OutboundFramesDiscarded,
|
||||||
|
BytesReceived: list.Items[0].BytesReceived,
|
||||||
|
BytesSent: list.Items[0].BytesSent,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, list)
|
}, list)
|
||||||
|
|||||||
@@ -489,6 +489,7 @@ func (s *session) apiItem() *defs.APIRTSPSession {
|
|||||||
OutboundBytes: stats.OutboundBytes,
|
OutboundBytes: stats.OutboundBytes,
|
||||||
OutboundRTPPackets: stats.OutboundRTPPackets,
|
OutboundRTPPackets: stats.OutboundRTPPackets,
|
||||||
OutboundRTPPacketsReportedLost: stats.OutboundRTPPacketsReportedLost,
|
OutboundRTPPacketsReportedLost: stats.OutboundRTPPacketsReportedLost,
|
||||||
|
OutboundRTPPacketsDiscarded: s.outboundRTPPacketsDiscarded.Get(),
|
||||||
OutboundRTCPPackets: stats.OutboundRTCPPackets,
|
OutboundRTCPPackets: stats.OutboundRTCPPackets,
|
||||||
BytesReceived: stats.InboundBytes,
|
BytesReceived: stats.InboundBytes,
|
||||||
BytesSent: stats.OutboundBytes,
|
BytesSent: stats.OutboundBytes,
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ type conn struct {
|
|||||||
query string
|
query string
|
||||||
user string
|
user string
|
||||||
sconn srt.Conn
|
sconn srt.Conn
|
||||||
|
reader *stream.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) initialize() {
|
func (c *conn) initialize() {
|
||||||
@@ -335,6 +336,10 @@ func (c *conn) runRead(streamID *streamID) error {
|
|||||||
res.Stream.AddReader(r)
|
res.Stream.AddReader(r)
|
||||||
defer res.Stream.RemoveReader(r)
|
defer res.Stream.RemoveReader(r)
|
||||||
|
|
||||||
|
c.mutex.Lock()
|
||||||
|
c.reader = r
|
||||||
|
c.mutex.Unlock()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-c.ctx.Done():
|
case <-c.ctx.Done():
|
||||||
return fmt.Errorf("terminated")
|
return fmt.Errorf("terminated")
|
||||||
@@ -433,5 +438,9 @@ func (c *conn) apiItem() *defs.APISRTConn {
|
|||||||
item.PacketsReceivedLossRate = s.Instantaneous.PktRecvLossRate
|
item.PacketsReceivedLossRate = s.Instantaneous.PktRecvLossRate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.reader != nil {
|
||||||
|
item.OutboundFramesDiscarded = c.reader.OutboundFramesDiscarded()
|
||||||
|
}
|
||||||
|
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ func TestServerPublish(t *testing.T) {
|
|||||||
BytesSendDrop: list.Items[0].BytesSendDrop,
|
BytesSendDrop: list.Items[0].BytesSendDrop,
|
||||||
BytesReceivedDrop: list.Items[0].BytesReceivedDrop,
|
BytesReceivedDrop: list.Items[0].BytesReceivedDrop,
|
||||||
BytesReceivedUndecrypt: list.Items[0].BytesReceivedUndecrypt,
|
BytesReceivedUndecrypt: list.Items[0].BytesReceivedUndecrypt,
|
||||||
|
OutboundFramesDiscarded: list.Items[0].OutboundFramesDiscarded,
|
||||||
UsPacketsSendPeriod: list.Items[0].UsPacketsSendPeriod,
|
UsPacketsSendPeriod: list.Items[0].UsPacketsSendPeriod,
|
||||||
PacketsFlowWindow: list.Items[0].PacketsFlowWindow,
|
PacketsFlowWindow: list.Items[0].PacketsFlowWindow,
|
||||||
PacketsFlightSize: list.Items[0].PacketsFlightSize,
|
PacketsFlightSize: list.Items[0].PacketsFlightSize,
|
||||||
|
|||||||
@@ -342,6 +342,7 @@ func TestServerPublish(t *testing.T) {
|
|||||||
OutboundBytes: list.Items[0].OutboundBytes,
|
OutboundBytes: list.Items[0].OutboundBytes,
|
||||||
OutboundRTPPackets: list.Items[0].OutboundRTPPackets,
|
OutboundRTPPackets: list.Items[0].OutboundRTPPackets,
|
||||||
OutboundRTCPPackets: list.Items[0].OutboundRTCPPackets,
|
OutboundRTCPPackets: list.Items[0].OutboundRTCPPackets,
|
||||||
|
OutboundFramesDiscarded: list.Items[0].OutboundFramesDiscarded,
|
||||||
BytesReceived: list.Items[0].BytesReceived,
|
BytesReceived: list.Items[0].BytesReceived,
|
||||||
BytesSent: list.Items[0].BytesSent,
|
BytesSent: list.Items[0].BytesSent,
|
||||||
RTPPacketsReceived: list.Items[0].RTPPacketsReceived,
|
RTPPacketsReceived: list.Items[0].RTPPacketsReceived,
|
||||||
@@ -635,6 +636,7 @@ func TestServerRead(t *testing.T) {
|
|||||||
OutboundBytes: list.Items[0].OutboundBytes,
|
OutboundBytes: list.Items[0].OutboundBytes,
|
||||||
OutboundRTPPackets: list.Items[0].OutboundRTPPackets,
|
OutboundRTPPackets: list.Items[0].OutboundRTPPackets,
|
||||||
OutboundRTCPPackets: list.Items[0].OutboundRTCPPackets,
|
OutboundRTCPPackets: list.Items[0].OutboundRTCPPackets,
|
||||||
|
OutboundFramesDiscarded: list.Items[0].OutboundFramesDiscarded,
|
||||||
BytesReceived: list.Items[0].BytesReceived,
|
BytesReceived: list.Items[0].BytesReceived,
|
||||||
BytesSent: list.Items[0].BytesSent,
|
BytesSent: list.Items[0].BytesSent,
|
||||||
RTPPacketsReceived: list.Items[0].RTPPacketsReceived,
|
RTPPacketsReceived: list.Items[0].RTPPacketsReceived,
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ type session struct {
|
|||||||
uuid uuid.UUID
|
uuid uuid.UUID
|
||||||
secret uuid.UUID
|
secret uuid.UUID
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
|
reader *stream.Reader
|
||||||
pc *webrtc.PeerConnection
|
pc *webrtc.PeerConnection
|
||||||
user string
|
user string
|
||||||
|
|
||||||
@@ -387,6 +388,10 @@ func (s *session) runRead() (int, error) {
|
|||||||
res.Stream.AddReader(r)
|
res.Stream.AddReader(r)
|
||||||
defer res.Stream.RemoveReader(r)
|
defer res.Stream.RemoveReader(r)
|
||||||
|
|
||||||
|
s.mutex.Lock()
|
||||||
|
s.reader = r
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-pc.Failed():
|
case <-pc.Failed():
|
||||||
return 0, fmt.Errorf("peer connection closed")
|
return 0, fmt.Errorf("peer connection closed")
|
||||||
@@ -479,6 +484,7 @@ func (s *session) apiItem() *defs.APIWebRTCSession {
|
|||||||
rtpPacketsJitter := float64(0)
|
rtpPacketsJitter := float64(0)
|
||||||
rtcpPacketsReceived := uint64(0)
|
rtcpPacketsReceived := uint64(0)
|
||||||
rtcpPacketsSent := uint64(0)
|
rtcpPacketsSent := uint64(0)
|
||||||
|
outboundFramesDiscarded := uint64(0)
|
||||||
|
|
||||||
if s.pc != nil {
|
if s.pc != nil {
|
||||||
peerConnectionEstablished = true
|
peerConnectionEstablished = true
|
||||||
@@ -495,6 +501,10 @@ func (s *session) apiItem() *defs.APIWebRTCSession {
|
|||||||
rtcpPacketsSent = stats.RTCPPacketsSent
|
rtcpPacketsSent = stats.RTCPPacketsSent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.reader != nil {
|
||||||
|
outboundFramesDiscarded = s.reader.OutboundFramesDiscarded()
|
||||||
|
}
|
||||||
|
|
||||||
return &defs.APIWebRTCSession{
|
return &defs.APIWebRTCSession{
|
||||||
ID: s.uuid,
|
ID: s.uuid,
|
||||||
Created: s.created,
|
Created: s.created,
|
||||||
@@ -519,6 +529,7 @@ func (s *session) apiItem() *defs.APIWebRTCSession {
|
|||||||
OutboundBytes: bytesSent,
|
OutboundBytes: bytesSent,
|
||||||
OutboundRTPPackets: rtpPacketsSent,
|
OutboundRTPPackets: rtpPacketsSent,
|
||||||
OutboundRTCPPackets: rtcpPacketsSent,
|
OutboundRTCPPackets: rtcpPacketsSent,
|
||||||
|
OutboundFramesDiscarded: outboundFramesDiscarded,
|
||||||
BytesReceived: bytesReceived,
|
BytesReceived: bytesReceived,
|
||||||
BytesSent: bytesSent,
|
BytesSent: bytesSent,
|
||||||
RTPPacketsReceived: rtpPacketsReceived,
|
RTPPacketsReceived: rtpPacketsReceived,
|
||||||
|
|||||||
@@ -65,6 +65,11 @@ func (r *Reader) Formats() []format.Format {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OutboundFramesDiscarded returns the number of frames discarded because the reader is too slow.
|
||||||
|
func (r *Reader) OutboundFramesDiscarded() uint64 {
|
||||||
|
return r.outboundFramesDiscarded.Get()
|
||||||
|
}
|
||||||
|
|
||||||
// error returns whenever there's an error.
|
// error returns whenever there's an error.
|
||||||
// It can be called only after stream.AddReader().
|
// It can be called only after stream.AddReader().
|
||||||
func (r *Reader) Error() chan error {
|
func (r *Reader) Error() chan error {
|
||||||
|
|||||||
@@ -483,6 +483,11 @@ func (s *Stream) OutboundBytes() uint64 {
|
|||||||
return outboundBytes
|
return outboundBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InboundFramesInError returns the number of frames received with processing errors.
|
||||||
|
func (s *Stream) InboundFramesInError() uint64 {
|
||||||
|
return s.inboundFramesInError.Get()
|
||||||
|
}
|
||||||
|
|
||||||
// RTSPStream returns the RTSP stream.
|
// RTSPStream returns the RTSP stream.
|
||||||
func (s *Stream) RTSPStream(server *gortsplib.Server) *gortsplib.ServerStream {
|
func (s *Stream) RTSPStream(server *gortsplib.Server) *gortsplib.ServerStream {
|
||||||
s.mutex.Lock()
|
s.mutex.Lock()
|
||||||
|
|||||||
Reference in New Issue
Block a user