metrics: add hls_muxers metric
This commit is contained in:
@@ -430,6 +430,7 @@ rtsps_sessions{state="publish"} 0
|
||||
rtmp_conns{state="idle"} 0
|
||||
rtmp_conns{state="read"} 0
|
||||
rtmp_conns{state="publish"} 1
|
||||
hls_muxers{name="<name>"} 1
|
||||
```
|
||||
|
||||
where:
|
||||
@@ -444,6 +445,7 @@ where:
|
||||
* `rtmp_conns{state="idle"}` is the count of RTMP connections that are idle
|
||||
* `rtmp_conns{state="read"}` is the count of RTMP connections that are reading
|
||||
* `rtmp_conns{state="publish"}` is the count of RTMP connections that are publishing
|
||||
* `hls_muxers{name="<name>"}` is replicated for every HLS muxer and shows the name and state of every HLS muxer
|
||||
|
||||
### pprof
|
||||
|
||||
|
||||
@@ -328,6 +328,7 @@ func (p *Core) createResources(initial bool) error {
|
||||
p.conf.HLSAllowOrigin,
|
||||
p.conf.ReadBufferCount,
|
||||
p.pathManager,
|
||||
p.metrics,
|
||||
p)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -458,7 +459,8 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
|
||||
newConf.HLSSegmentDuration != p.conf.HLSSegmentDuration ||
|
||||
newConf.HLSAllowOrigin != p.conf.HLSAllowOrigin ||
|
||||
newConf.ReadBufferCount != p.conf.ReadBufferCount ||
|
||||
closePathManager {
|
||||
closePathManager ||
|
||||
closeMetrics {
|
||||
closeHLSServer = true
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ type hlsServer struct {
|
||||
hlsAllowOrigin string
|
||||
readBufferCount int
|
||||
pathManager *pathManager
|
||||
metrics *metrics
|
||||
parent hlsServerParent
|
||||
|
||||
ctx context.Context
|
||||
@@ -52,6 +53,7 @@ func newHLSServer(
|
||||
hlsAllowOrigin string,
|
||||
readBufferCount int,
|
||||
pathManager *pathManager,
|
||||
metrics *metrics,
|
||||
parent hlsServerParent,
|
||||
) (*hlsServer, error) {
|
||||
ln, err := net.Listen("tcp", address)
|
||||
@@ -69,6 +71,7 @@ func newHLSServer(
|
||||
readBufferCount: readBufferCount,
|
||||
pathManager: pathManager,
|
||||
parent: parent,
|
||||
metrics: metrics,
|
||||
ctx: ctx,
|
||||
ctxCancel: ctxCancel,
|
||||
ln: ln,
|
||||
@@ -83,6 +86,10 @@ func newHLSServer(
|
||||
|
||||
s.pathManager.onHLSServerSet(s)
|
||||
|
||||
if s.metrics != nil {
|
||||
s.metrics.onHLSServerSet(s)
|
||||
}
|
||||
|
||||
s.wg.Add(1)
|
||||
go s.run()
|
||||
|
||||
@@ -148,6 +155,10 @@ outer:
|
||||
hs.Shutdown(context.Background())
|
||||
|
||||
s.pathManager.onHLSServerSet(nil)
|
||||
|
||||
if s.metrics != nil {
|
||||
s.metrics.onHLSServerSet(nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *hlsServer) onRequest(ctx *gin.Context) {
|
||||
|
||||
+33
-12
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/aler9/rtsp-simple-server/internal/logger"
|
||||
)
|
||||
|
||||
func formatMetric(key string, value int64) string {
|
||||
func metric(key string, value int64) string {
|
||||
return key + " " + strconv.FormatInt(value, 10) + "\n"
|
||||
}
|
||||
|
||||
@@ -29,6 +29,10 @@ type metricsRTMPServer interface {
|
||||
onAPIRTMPConnsList(req apiRTMPConnsListReq) apiRTMPConnsListRes
|
||||
}
|
||||
|
||||
type metricsHLSServer interface {
|
||||
onAPIHLSMuxersList(req apiHLSMuxersListReq) apiHLSMuxersListRes
|
||||
}
|
||||
|
||||
type metricsParent interface {
|
||||
Log(logger.Level, string, ...interface{})
|
||||
}
|
||||
@@ -42,6 +46,7 @@ type metrics struct {
|
||||
rtspServer metricsRTSPServer
|
||||
rtspsServer metricsRTSPServer
|
||||
rtmpServer metricsRTMPServer
|
||||
hlsServer metricsHLSServer
|
||||
}
|
||||
|
||||
func newMetrics(
|
||||
@@ -87,9 +92,9 @@ func (m *metrics) onMetrics(ctx *gin.Context) {
|
||||
if res.Err == nil {
|
||||
for name, p := range res.Data.Items {
|
||||
if p.SourceReady {
|
||||
out += formatMetric("paths{name=\""+name+"\",state=\"ready\"}", 1)
|
||||
out += metric("paths{name=\""+name+"\",state=\"ready\"}", 1)
|
||||
} else {
|
||||
out += formatMetric("paths{name=\""+name+"\",state=\"notReady\"}", 1)
|
||||
out += metric("paths{name=\""+name+"\",state=\"notReady\"}", 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,11 +117,11 @@ func (m *metrics) onMetrics(ctx *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
out += formatMetric("rtsp_sessions{state=\"idle\"}",
|
||||
out += metric("rtsp_sessions{state=\"idle\"}",
|
||||
idleCount)
|
||||
out += formatMetric("rtsp_sessions{state=\"read\"}",
|
||||
out += metric("rtsp_sessions{state=\"read\"}",
|
||||
readCount)
|
||||
out += formatMetric("rtsp_sessions{state=\"publish\"}",
|
||||
out += metric("rtsp_sessions{state=\"publish\"}",
|
||||
publishCount)
|
||||
}
|
||||
}
|
||||
@@ -139,11 +144,11 @@ func (m *metrics) onMetrics(ctx *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
out += formatMetric("rtsps_sessions{state=\"idle\"}",
|
||||
out += metric("rtsps_sessions{state=\"idle\"}",
|
||||
idleCount)
|
||||
out += formatMetric("rtsps_sessions{state=\"read\"}",
|
||||
out += metric("rtsps_sessions{state=\"read\"}",
|
||||
readCount)
|
||||
out += formatMetric("rtsps_sessions{state=\"publish\"}",
|
||||
out += metric("rtsps_sessions{state=\"publish\"}",
|
||||
publishCount)
|
||||
}
|
||||
}
|
||||
@@ -166,15 +171,24 @@ func (m *metrics) onMetrics(ctx *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
out += formatMetric("rtmp_conns{state=\"idle\"}",
|
||||
out += metric("rtmp_conns{state=\"idle\"}",
|
||||
idleCount)
|
||||
out += formatMetric("rtmp_conns{state=\"read\"}",
|
||||
out += metric("rtmp_conns{state=\"read\"}",
|
||||
readCount)
|
||||
out += formatMetric("rtmp_conns{state=\"publish\"}",
|
||||
out += metric("rtmp_conns{state=\"publish\"}",
|
||||
publishCount)
|
||||
}
|
||||
}
|
||||
|
||||
if !interfaceIsEmpty(m.hlsServer) {
|
||||
res := m.hlsServer.onAPIHLSMuxersList(apiHLSMuxersListReq{})
|
||||
if res.Err == nil {
|
||||
for name := range res.Data.Items {
|
||||
out += metric("hls_muxers{name=\""+name+"\"}", 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
io.WriteString(ctx.Writer, out)
|
||||
}
|
||||
@@ -206,3 +220,10 @@ func (m *metrics) onRTMPServerSet(s metricsRTMPServer) {
|
||||
defer m.mutex.Unlock()
|
||||
m.rtmpServer = s
|
||||
}
|
||||
|
||||
// onHLSServerSet is called by hlsServer.
|
||||
func (m *metrics) onHLSServerSet(s metricsHLSServer) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
m.hlsServer = s
|
||||
}
|
||||
|
||||
@@ -47,6 +47,13 @@ func TestMetrics(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer cnt1.close()
|
||||
|
||||
func() {
|
||||
res, err := http.Get("http://localhost:8888/rtsp_path/index.m3u8")
|
||||
require.NoError(t, err)
|
||||
defer res.Body.Close()
|
||||
require.Equal(t, 200, res.StatusCode)
|
||||
}()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://localhost:9998/metrics", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -66,6 +73,7 @@ func TestMetrics(t *testing.T) {
|
||||
}
|
||||
|
||||
require.Equal(t, map[string]string{
|
||||
"hls_muxers{name=\"rtsp_path\"}": "1",
|
||||
"paths{name=\"rtsp_path\",state=\"ready\"}": "1",
|
||||
"paths{name=\"rtmp_path\",state=\"ready\"}": "1",
|
||||
"rtmp_conns{state=\"idle\"}": "0",
|
||||
|
||||
Reference in New Issue
Block a user