metrics: return metrics even if there are no paths or clients (#1688)

This commit is contained in:
Alessandro Ros 2023-04-11 20:47:29 +02:00 committed by GitHub
parent 88953f36a6
commit 79872cabd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 111 additions and 41 deletions

View File

@ -16,8 +16,8 @@ import (
"github.com/aler9/mediamtx/internal/logger"
)
func metric(key string, value int64) string {
return key + " " + strconv.FormatInt(value, 10) + "\n"
func metric(key string, tags string, value int64) string {
return key + tags + " " + strconv.FormatInt(value, 10) + "\n"
}
type metricsParent interface {
@ -87,7 +87,7 @@ func (m *metrics) onMetrics(ctx *gin.Context) {
out := ""
res := m.pathManager.apiPathsList()
if res.err == nil {
if res.err == nil && len(res.data.Items) != 0 {
for name, i := range res.data.Items {
var state string
if i.SourceReady {
@ -97,44 +97,57 @@ func (m *metrics) onMetrics(ctx *gin.Context) {
}
tags := "{name=\"" + name + "\",state=\"" + state + "\"}"
out += metric("paths"+tags, 1)
out += metric("paths_bytes_received"+tags, int64(i.BytesReceived))
out += metric("paths", tags, 1)
out += metric("paths_bytes_received", tags, int64(i.BytesReceived))
}
} else {
out += metric("paths", "", 0)
}
if !interfaceIsEmpty(m.hlsServer) {
res := m.hlsServer.apiMuxersList()
if res.err == nil {
if res.err == nil && len(res.data.Items) != 0 {
for name, i := range res.data.Items {
tags := "{name=\"" + name + "\"}"
out += metric("hls_muxers"+tags, 1)
out += metric("hls_muxers_bytes_sent"+tags, int64(i.BytesSent))
out += metric("hls_muxers", tags, 1)
out += metric("hls_muxers_bytes_sent", tags, int64(i.BytesSent))
}
} else {
out += metric("hls_muxers", "", 0)
out += metric("hls_muxers_bytes_sent", "", 0)
}
}
if !interfaceIsEmpty(m.rtspServer) { //nolint:dupl
func() {
res := m.rtspServer.apiConnsList()
if res.err == nil {
if res.err == nil && len(res.data.Items) != 0 {
for id, i := range res.data.Items {
tags := "{id=\"" + id + "\"}"
out += metric("rtsp_conns"+tags, 1)
out += metric("rtsp_conns_bytes_received"+tags, int64(i.BytesReceived))
out += metric("rtsp_conns_bytes_sent"+tags, int64(i.BytesSent))
out += metric("rtsp_conns", tags, 1)
out += metric("rtsp_conns_bytes_received", tags, int64(i.BytesReceived))
out += metric("rtsp_conns_bytes_sent", tags, int64(i.BytesSent))
}
} else {
out += metric("rtsp_conns", "", 0)
out += metric("rtsp_conns_bytes_received", "", 0)
out += metric("rtsp_conns_bytes_sent", "", 0)
}
}()
func() {
res := m.rtspServer.apiSessionsList()
if res.err == nil {
if res.err == nil && len(res.data.Items) != 0 {
for id, i := range res.data.Items {
tags := "{id=\"" + id + "\",state=\"" + i.State + "\"}"
out += metric("rtsp_sessions"+tags, 1)
out += metric("rtsp_sessions_bytes_received"+tags, int64(i.BytesReceived))
out += metric("rtsp_sessions_bytes_sent"+tags, int64(i.BytesSent))
out += metric("rtsp_sessions", tags, 1)
out += metric("rtsp_sessions_bytes_received", tags, int64(i.BytesReceived))
out += metric("rtsp_sessions_bytes_sent", tags, int64(i.BytesSent))
}
} else {
out += metric("rtsp_sessions", "", 0)
out += metric("rtsp_sessions_bytes_received", "", 0)
out += metric("rtsp_sessions_bytes_sent", "", 0)
}
}()
}
@ -142,50 +155,66 @@ func (m *metrics) onMetrics(ctx *gin.Context) {
if !interfaceIsEmpty(m.rtspsServer) { //nolint:dupl
func() {
res := m.rtspsServer.apiConnsList()
if res.err == nil {
if res.err == nil && len(res.data.Items) != 0 {
for id, i := range res.data.Items {
tags := "{id=\"" + id + "\"}"
out += metric("rtsps_conns"+tags, 1)
out += metric("rtsps_conns_bytes_received"+tags, int64(i.BytesReceived))
out += metric("rtsps_conns_bytes_sent"+tags, int64(i.BytesSent))
out += metric("rtsps_conns", tags, 1)
out += metric("rtsps_conns_bytes_received", tags, int64(i.BytesReceived))
out += metric("rtsps_conns_bytes_sent", tags, int64(i.BytesSent))
}
} else {
out += metric("rtsps_conns", "", 0)
out += metric("rtsps_conns_bytes_received", "", 0)
out += metric("rtsps_conns_bytes_sent", "", 0)
}
}()
func() {
res := m.rtspsServer.apiSessionsList()
if res.err == nil {
if res.err == nil && len(res.data.Items) != 0 {
for id, i := range res.data.Items {
tags := "{id=\"" + id + "\",state=\"" + i.State + "\"}"
out += metric("rtsps_sessions"+tags, 1)
out += metric("rtsps_sessions_bytes_received"+tags, int64(i.BytesReceived))
out += metric("rtsps_sessions_bytes_sent"+tags, int64(i.BytesSent))
out += metric("rtsps_sessions", tags, 1)
out += metric("rtsps_sessions_bytes_received", tags, int64(i.BytesReceived))
out += metric("rtsps_sessions_bytes_sent", tags, int64(i.BytesSent))
}
} else {
out += metric("rtsps_sessions", "", 0)
out += metric("rtsps_sessions_bytes_received", "", 0)
out += metric("rtsps_sessions_bytes_sent", "", 0)
}
}()
}
if !interfaceIsEmpty(m.rtmpServer) {
res := m.rtmpServer.apiConnsList()
if res.err == nil {
if res.err == nil && len(res.data.Items) != 0 {
for id, i := range res.data.Items {
tags := "{id=\"" + id + "\",state=\"" + i.State + "\"}"
out += metric("rtmp_conns"+tags, 1)
out += metric("rtmp_conns_bytes_received"+tags, int64(i.BytesReceived))
out += metric("rtmp_conns_bytes_sent"+tags, int64(i.BytesSent))
out += metric("rtmp_conns", tags, 1)
out += metric("rtmp_conns_bytes_received", tags, int64(i.BytesReceived))
out += metric("rtmp_conns_bytes_sent", tags, int64(i.BytesSent))
}
} else {
out += metric("rtmp_conns", "", 0)
out += metric("rtmp_conns_bytes_received", "", 0)
out += metric("rtmp_conns_bytes_sent", "", 0)
}
}
if !interfaceIsEmpty(m.webRTCServer) {
res := m.webRTCServer.apiConnsList()
if res.err == nil {
if res.err == nil && len(res.data.Items) != 0 {
for id, i := range res.data.Items {
tags := "{id=\"" + id + "\"}"
out += metric("webrtc_conns"+tags, 1)
out += metric("webrtc_conns_bytes_received"+tags, int64(i.BytesReceived))
out += metric("webrtc_conns_bytes_sent"+tags, int64(i.BytesSent))
out += metric("webrtc_conns", tags, 1)
out += metric("webrtc_conns_bytes_received", tags, int64(i.BytesReceived))
out += metric("webrtc_conns_bytes_sent", tags, int64(i.BytesSent))
}
} else {
out += metric("webrtc_conns", "", 0)
out += metric("webrtc_conns_bytes_received", "", 0)
out += metric("webrtc_conns_bytes_sent", "", 0)
}
}

View File

@ -2,6 +2,7 @@ package core
import (
"crypto/tls"
"fmt"
"io"
"net"
"net/http"
@ -17,6 +18,25 @@ import (
"github.com/aler9/mediamtx/internal/rtmp"
)
func pullMetrics() ([]byte, error) {
req, err := http.NewRequest(http.MethodGet, "http://localhost:9998/metrics", nil)
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("bad status code: %v", res.StatusCode)
}
return io.ReadAll(res.Body)
}
func TestMetrics(t *testing.T) {
serverCertFpath, err := writeTempFile(serverCert)
require.NoError(t, err)
@ -37,6 +57,32 @@ func TestMetrics(t *testing.T) {
require.Equal(t, true, ok)
defer p.Close()
bo, err := pullMetrics()
require.NoError(t, err)
require.Equal(t, `paths 0
hls_muxers 0
hls_muxers_bytes_sent 0
rtsp_conns 0
rtsp_conns_bytes_received 0
rtsp_conns_bytes_sent 0
rtsp_sessions 0
rtsp_sessions_bytes_received 0
rtsp_sessions_bytes_sent 0
rtsps_conns 0
rtsps_conns_bytes_received 0
rtsps_conns_bytes_sent 0
rtsps_sessions 0
rtsps_sessions_bytes_received 0
rtsps_sessions_bytes_sent 0
rtmp_conns 0
rtmp_conns_bytes_received 0
rtmp_conns_bytes_sent 0
webrtc_conns 0
webrtc_conns_bytes_received 0
webrtc_conns_bytes_sent 0
`, string(bo))
medi := testMediaH264
source := gortsplib.Client{}
@ -83,15 +129,7 @@ func TestMetrics(t *testing.T) {
require.Equal(t, 200, res.StatusCode)
}()
req, err := http.NewRequest(http.MethodGet, "http://localhost:9998/metrics", nil)
require.NoError(t, err)
res, err := http.DefaultClient.Do(req)
require.NoError(t, err)
defer res.Body.Close()
require.Equal(t, http.StatusOK, res.StatusCode)
bo, err := io.ReadAll(res.Body)
bo, err = pullMetrics()
require.NoError(t, err)
require.Regexp(t,
@ -118,6 +156,9 @@ func TestMetrics(t *testing.T) {
`rtmp_conns\{id=".*?",state="publish"\} 1`+"\n"+
`rtmp_conns_bytes_received\{id=".*?",state="publish"\} [0-9]+`+"\n"+
`rtmp_conns_bytes_sent\{id=".*?",state="publish"\} [0-9]+`+"\n"+
`webrtc_conns 0`+"\n"+
`webrtc_conns_bytes_received 0`+"\n"+
`webrtc_conns_bytes_sent 0`+"\n"+
"$",
string(bo))
}