move api, metrics and pprof into dedicated packages (#2843)

This commit is contained in:
Alessandro Ros 2023-12-26 13:41:15 +01:00 committed by GitHub
parent 3ecd79f076
commit 1341421412
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 299 additions and 293 deletions

View File

@ -1,4 +1,5 @@
package core
// Package api contains the API server.
package api
import (
"encoding/json"
@ -97,17 +98,20 @@ func paramName(ctx *gin.Context) (string, bool) {
return name[1:], true
}
type apiPathManager interface {
apiPathsList() (*defs.APIPathList, error)
apiPathsGet(string) (*defs.APIPath, error)
// PathManager contains methods used by the API and Metrics server.
type PathManager interface {
APIPathsList() (*defs.APIPathList, error)
APIPathsGet(string) (*defs.APIPath, error)
}
type apiHLSServer interface {
// HLSServer contains methods used by the API and Metrics server.
type HLSServer interface {
APIMuxersList() (*defs.APIHLSMuxerList, error)
APIMuxersGet(string) (*defs.APIHLSMuxer, error)
}
type apiRTSPServer interface {
// RTSPServer contains methods used by the API and Metrics server.
type RTSPServer interface {
APIConnsList() (*defs.APIRTSPConnsList, error)
APIConnsGet(uuid.UUID) (*defs.APIRTSPConn, error)
APISessionsList() (*defs.APIRTSPSessionList, error)
@ -115,19 +119,22 @@ type apiRTSPServer interface {
APISessionsKick(uuid.UUID) error
}
type apiRTMPServer interface {
// RTMPServer contains methods used by the API and Metrics server.
type RTMPServer interface {
APIConnsList() (*defs.APIRTMPConnList, error)
APIConnsGet(uuid.UUID) (*defs.APIRTMPConn, error)
APIConnsKick(uuid.UUID) error
}
type apiSRTServer interface {
// SRTServer contains methods used by the API and Metrics server.
type SRTServer interface {
APIConnsList() (*defs.APISRTConnList, error)
APIConnsGet(uuid.UUID) (*defs.APISRTConn, error)
APIConnsKick(uuid.UUID) error
}
type apiWebRTCServer interface {
// WebRTCServer contains methods used by the API and Metrics server.
type WebRTCServer interface {
APISessionsList() (*defs.APIWebRTCSessionList, error)
APISessionsGet(uuid.UUID) (*defs.APIWebRTCSession, error)
APISessionsKick(uuid.UUID) error
@ -135,52 +142,30 @@ type apiWebRTCServer interface {
type apiParent interface {
logger.Writer
apiConfigSet(conf *conf.Conf)
APIConfigSet(conf *conf.Conf)
}
type api struct {
conf *conf.Conf
pathManager apiPathManager
rtspServer apiRTSPServer
rtspsServer apiRTSPServer
rtmpServer apiRTMPServer
rtmpsServer apiRTMPServer
hlsManager apiHLSServer
webRTCServer apiWebRTCServer
srtServer apiSRTServer
parent apiParent
// API is an API server.
type API struct {
Address string
ReadTimeout conf.StringDuration
Conf *conf.Conf
PathManager PathManager
RTSPServer RTSPServer
RTSPSServer RTSPServer
RTMPServer RTMPServer
RTMPSServer RTMPServer
HLSServer HLSServer
WebRTCServer WebRTCServer
SRTServer SRTServer
Parent apiParent
httpServer *httpserv.WrappedServer
mutex sync.Mutex
}
func newAPI(
address string,
readTimeout conf.StringDuration,
conf *conf.Conf,
pathManager apiPathManager,
rtspServer apiRTSPServer,
rtspsServer apiRTSPServer,
rtmpServer apiRTMPServer,
rtmpsServer apiRTMPServer,
hlsManager apiHLSServer,
webRTCServer apiWebRTCServer,
srtServer apiSRTServer,
parent apiParent,
) (*api, error) {
a := &api{
conf: conf,
pathManager: pathManager,
rtspServer: rtspServer,
rtspsServer: rtspsServer,
rtmpServer: rtmpServer,
rtmpsServer: rtmpsServer,
hlsManager: hlsManager,
webRTCServer: webRTCServer,
srtServer: srtServer,
parent: parent,
}
// Initialize initializes API.
func (a *API) Initialize() error {
router := gin.New()
router.SetTrustedProxies(nil) //nolint:errcheck
@ -202,12 +187,12 @@ func newAPI(
group.GET("/v3/paths/list", a.onPathsList)
group.GET("/v3/paths/get/*name", a.onPathsGet)
if !interfaceIsEmpty(a.hlsManager) {
if !interfaceIsEmpty(a.HLSServer) {
group.GET("/v3/hlsmuxers/list", a.onHLSMuxersList)
group.GET("/v3/hlsmuxers/get/*name", a.onHLSMuxersGet)
}
if !interfaceIsEmpty(a.rtspServer) {
if !interfaceIsEmpty(a.RTSPServer) {
group.GET("/v3/rtspconns/list", a.onRTSPConnsList)
group.GET("/v3/rtspconns/get/:id", a.onRTSPConnsGet)
group.GET("/v3/rtspsessions/list", a.onRTSPSessionsList)
@ -215,7 +200,7 @@ func newAPI(
group.POST("/v3/rtspsessions/kick/:id", a.onRTSPSessionsKick)
}
if !interfaceIsEmpty(a.rtspsServer) {
if !interfaceIsEmpty(a.RTSPSServer) {
group.GET("/v3/rtspsconns/list", a.onRTSPSConnsList)
group.GET("/v3/rtspsconns/get/:id", a.onRTSPSConnsGet)
group.GET("/v3/rtspssessions/list", a.onRTSPSSessionsList)
@ -223,63 +208,64 @@ func newAPI(
group.POST("/v3/rtspssessions/kick/:id", a.onRTSPSSessionsKick)
}
if !interfaceIsEmpty(a.rtmpServer) {
if !interfaceIsEmpty(a.RTMPServer) {
group.GET("/v3/rtmpconns/list", a.onRTMPConnsList)
group.GET("/v3/rtmpconns/get/:id", a.onRTMPConnsGet)
group.POST("/v3/rtmpconns/kick/:id", a.onRTMPConnsKick)
}
if !interfaceIsEmpty(a.rtmpsServer) {
if !interfaceIsEmpty(a.RTMPSServer) {
group.GET("/v3/rtmpsconns/list", a.onRTMPSConnsList)
group.GET("/v3/rtmpsconns/get/:id", a.onRTMPSConnsGet)
group.POST("/v3/rtmpsconns/kick/:id", a.onRTMPSConnsKick)
}
if !interfaceIsEmpty(a.webRTCServer) {
if !interfaceIsEmpty(a.WebRTCServer) {
group.GET("/v3/webrtcsessions/list", a.onWebRTCSessionsList)
group.GET("/v3/webrtcsessions/get/:id", a.onWebRTCSessionsGet)
group.POST("/v3/webrtcsessions/kick/:id", a.onWebRTCSessionsKick)
}
if !interfaceIsEmpty(a.srtServer) {
if !interfaceIsEmpty(a.SRTServer) {
group.GET("/v3/srtconns/list", a.onSRTConnsList)
group.GET("/v3/srtconns/get/:id", a.onSRTConnsGet)
group.POST("/v3/srtconns/kick/:id", a.onSRTConnsKick)
}
network, address := restrictnetwork.Restrict("tcp", address)
network, address := restrictnetwork.Restrict("tcp", a.Address)
var err error
a.httpServer, err = httpserv.NewWrappedServer(
network,
address,
time.Duration(readTimeout),
time.Duration(a.ReadTimeout),
"",
"",
router,
a,
)
if err != nil {
return nil, err
return err
}
a.Log(logger.Info, "listener opened on "+address)
return a, nil
return nil
}
func (a *api) close() {
// Close closes the API.
func (a *API) Close() {
a.Log(logger.Info, "listener is closing")
a.httpServer.Close()
}
// Log implements logger.Writer.
func (a *api) Log(level logger.Level, format string, args ...interface{}) {
a.parent.Log(level, "[API] "+format, args...)
func (a *API) Log(level logger.Level, format string, args ...interface{}) {
a.Parent.Log(level, "[API] "+format, args...)
}
// error coming from something the user inserted into the request.
func (a *api) writeError(ctx *gin.Context, status int, err error) {
func (a *API) writeError(ctx *gin.Context, status int, err error) {
// show error in logs
a.Log(logger.Error, err.Error())
@ -289,15 +275,15 @@ func (a *api) writeError(ctx *gin.Context, status int, err error) {
})
}
func (a *api) onConfigGlobalGet(ctx *gin.Context) {
func (a *API) onConfigGlobalGet(ctx *gin.Context) {
a.mutex.Lock()
c := a.conf
c := a.Conf
a.mutex.Unlock()
ctx.JSON(http.StatusOK, c.Global())
}
func (a *api) onConfigGlobalPatch(ctx *gin.Context) {
func (a *API) onConfigGlobalPatch(ctx *gin.Context) {
var c conf.OptionalGlobal
err := json.NewDecoder(ctx.Request.Body).Decode(&c)
if err != nil {
@ -308,7 +294,7 @@ func (a *api) onConfigGlobalPatch(ctx *gin.Context) {
a.mutex.Lock()
defer a.mutex.Unlock()
newConf := a.conf.Clone()
newConf := a.Conf.Clone()
newConf.PatchGlobal(&c)
@ -318,24 +304,24 @@ func (a *api) onConfigGlobalPatch(ctx *gin.Context) {
return
}
a.conf = newConf
a.Conf = newConf
// since reloading the configuration can cause the shutdown of the API,
// call it in a goroutine
go a.parent.apiConfigSet(newConf)
go a.Parent.APIConfigSet(newConf)
ctx.Status(http.StatusOK)
}
func (a *api) onConfigPathDefaultsGet(ctx *gin.Context) {
func (a *API) onConfigPathDefaultsGet(ctx *gin.Context) {
a.mutex.Lock()
c := a.conf
c := a.Conf
a.mutex.Unlock()
ctx.JSON(http.StatusOK, c.PathDefaults)
}
func (a *api) onConfigPathDefaultsPatch(ctx *gin.Context) {
func (a *API) onConfigPathDefaultsPatch(ctx *gin.Context) {
var p conf.OptionalPath
err := json.NewDecoder(ctx.Request.Body).Decode(&p)
if err != nil {
@ -346,7 +332,7 @@ func (a *api) onConfigPathDefaultsPatch(ctx *gin.Context) {
a.mutex.Lock()
defer a.mutex.Unlock()
newConf := a.conf.Clone()
newConf := a.Conf.Clone()
newConf.PatchPathDefaults(&p)
@ -356,15 +342,15 @@ func (a *api) onConfigPathDefaultsPatch(ctx *gin.Context) {
return
}
a.conf = newConf
a.parent.apiConfigSet(newConf)
a.Conf = newConf
a.Parent.APIConfigSet(newConf)
ctx.Status(http.StatusOK)
}
func (a *api) onConfigPathsList(ctx *gin.Context) {
func (a *API) onConfigPathsList(ctx *gin.Context) {
a.mutex.Lock()
c := a.conf
c := a.Conf
a.mutex.Unlock()
data := &defs.APIPathConfList{
@ -386,7 +372,7 @@ func (a *api) onConfigPathsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onConfigPathsGet(ctx *gin.Context) {
func (a *API) onConfigPathsGet(ctx *gin.Context) {
name, ok := paramName(ctx)
if !ok {
a.writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid name"))
@ -394,7 +380,7 @@ func (a *api) onConfigPathsGet(ctx *gin.Context) {
}
a.mutex.Lock()
c := a.conf
c := a.Conf
a.mutex.Unlock()
p, ok := c.Paths[name]
@ -406,7 +392,7 @@ func (a *api) onConfigPathsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, p)
}
func (a *api) onConfigPathsAdd(ctx *gin.Context) { //nolint:dupl
func (a *API) onConfigPathsAdd(ctx *gin.Context) { //nolint:dupl
name, ok := paramName(ctx)
if !ok {
a.writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid name"))
@ -423,7 +409,7 @@ func (a *api) onConfigPathsAdd(ctx *gin.Context) { //nolint:dupl
a.mutex.Lock()
defer a.mutex.Unlock()
newConf := a.conf.Clone()
newConf := a.Conf.Clone()
err = newConf.AddPath(name, &p)
if err != nil {
@ -437,13 +423,13 @@ func (a *api) onConfigPathsAdd(ctx *gin.Context) { //nolint:dupl
return
}
a.conf = newConf
a.parent.apiConfigSet(newConf)
a.Conf = newConf
a.Parent.APIConfigSet(newConf)
ctx.Status(http.StatusOK)
}
func (a *api) onConfigPathsPatch(ctx *gin.Context) { //nolint:dupl
func (a *API) onConfigPathsPatch(ctx *gin.Context) { //nolint:dupl
name, ok := paramName(ctx)
if !ok {
a.writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid name"))
@ -460,7 +446,7 @@ func (a *api) onConfigPathsPatch(ctx *gin.Context) { //nolint:dupl
a.mutex.Lock()
defer a.mutex.Unlock()
newConf := a.conf.Clone()
newConf := a.Conf.Clone()
err = newConf.PatchPath(name, &p)
if err != nil {
@ -474,13 +460,13 @@ func (a *api) onConfigPathsPatch(ctx *gin.Context) { //nolint:dupl
return
}
a.conf = newConf
a.parent.apiConfigSet(newConf)
a.Conf = newConf
a.Parent.APIConfigSet(newConf)
ctx.Status(http.StatusOK)
}
func (a *api) onConfigPathsReplace(ctx *gin.Context) { //nolint:dupl
func (a *API) onConfigPathsReplace(ctx *gin.Context) { //nolint:dupl
name, ok := paramName(ctx)
if !ok {
a.writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid name"))
@ -497,7 +483,7 @@ func (a *api) onConfigPathsReplace(ctx *gin.Context) { //nolint:dupl
a.mutex.Lock()
defer a.mutex.Unlock()
newConf := a.conf.Clone()
newConf := a.Conf.Clone()
err = newConf.ReplacePath(name, &p)
if err != nil {
@ -511,13 +497,13 @@ func (a *api) onConfigPathsReplace(ctx *gin.Context) { //nolint:dupl
return
}
a.conf = newConf
a.parent.apiConfigSet(newConf)
a.Conf = newConf
a.Parent.APIConfigSet(newConf)
ctx.Status(http.StatusOK)
}
func (a *api) onConfigPathsDelete(ctx *gin.Context) {
func (a *API) onConfigPathsDelete(ctx *gin.Context) {
name, ok := paramName(ctx)
if !ok {
a.writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid name"))
@ -527,7 +513,7 @@ func (a *api) onConfigPathsDelete(ctx *gin.Context) {
a.mutex.Lock()
defer a.mutex.Unlock()
newConf := a.conf.Clone()
newConf := a.Conf.Clone()
err := newConf.RemovePath(name)
if err != nil {
@ -541,14 +527,14 @@ func (a *api) onConfigPathsDelete(ctx *gin.Context) {
return
}
a.conf = newConf
a.parent.apiConfigSet(newConf)
a.Conf = newConf
a.Parent.APIConfigSet(newConf)
ctx.Status(http.StatusOK)
}
func (a *api) onPathsList(ctx *gin.Context) {
data, err := a.pathManager.apiPathsList()
func (a *API) onPathsList(ctx *gin.Context) {
data, err := a.PathManager.APIPathsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -565,14 +551,14 @@ func (a *api) onPathsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onPathsGet(ctx *gin.Context) {
func (a *API) onPathsGet(ctx *gin.Context) {
name, ok := paramName(ctx)
if !ok {
a.writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid name"))
return
}
data, err := a.pathManager.apiPathsGet(name)
data, err := a.PathManager.APIPathsGet(name)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -581,8 +567,8 @@ func (a *api) onPathsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPConnsList(ctx *gin.Context) {
data, err := a.rtspServer.APIConnsList()
func (a *API) onRTSPConnsList(ctx *gin.Context) {
data, err := a.RTSPServer.APIConnsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -599,14 +585,14 @@ func (a *api) onRTSPConnsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPConnsGet(ctx *gin.Context) {
func (a *API) onRTSPConnsGet(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
data, err := a.rtspServer.APIConnsGet(uuid)
data, err := a.RTSPServer.APIConnsGet(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -615,8 +601,8 @@ func (a *api) onRTSPConnsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPSessionsList(ctx *gin.Context) {
data, err := a.rtspServer.APISessionsList()
func (a *API) onRTSPSessionsList(ctx *gin.Context) {
data, err := a.RTSPServer.APISessionsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -633,14 +619,14 @@ func (a *api) onRTSPSessionsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPSessionsGet(ctx *gin.Context) {
func (a *API) onRTSPSessionsGet(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
data, err := a.rtspServer.APISessionsGet(uuid)
data, err := a.RTSPServer.APISessionsGet(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -649,14 +635,14 @@ func (a *api) onRTSPSessionsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPSessionsKick(ctx *gin.Context) {
func (a *API) onRTSPSessionsKick(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
err = a.rtspServer.APISessionsKick(uuid)
err = a.RTSPServer.APISessionsKick(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -665,8 +651,8 @@ func (a *api) onRTSPSessionsKick(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
func (a *api) onRTSPSConnsList(ctx *gin.Context) {
data, err := a.rtspsServer.APIConnsList()
func (a *API) onRTSPSConnsList(ctx *gin.Context) {
data, err := a.RTSPSServer.APIConnsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -683,14 +669,14 @@ func (a *api) onRTSPSConnsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPSConnsGet(ctx *gin.Context) {
func (a *API) onRTSPSConnsGet(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
data, err := a.rtspsServer.APIConnsGet(uuid)
data, err := a.RTSPSServer.APIConnsGet(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -699,8 +685,8 @@ func (a *api) onRTSPSConnsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPSSessionsList(ctx *gin.Context) {
data, err := a.rtspsServer.APISessionsList()
func (a *API) onRTSPSSessionsList(ctx *gin.Context) {
data, err := a.RTSPSServer.APISessionsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -717,14 +703,14 @@ func (a *api) onRTSPSSessionsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPSSessionsGet(ctx *gin.Context) {
func (a *API) onRTSPSSessionsGet(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
data, err := a.rtspsServer.APISessionsGet(uuid)
data, err := a.RTSPSServer.APISessionsGet(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -733,14 +719,14 @@ func (a *api) onRTSPSSessionsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTSPSSessionsKick(ctx *gin.Context) {
func (a *API) onRTSPSSessionsKick(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
err = a.rtspsServer.APISessionsKick(uuid)
err = a.RTSPSServer.APISessionsKick(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -749,8 +735,8 @@ func (a *api) onRTSPSSessionsKick(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
func (a *api) onRTMPConnsList(ctx *gin.Context) {
data, err := a.rtmpServer.APIConnsList()
func (a *API) onRTMPConnsList(ctx *gin.Context) {
data, err := a.RTMPServer.APIConnsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -767,14 +753,14 @@ func (a *api) onRTMPConnsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTMPConnsGet(ctx *gin.Context) {
func (a *API) onRTMPConnsGet(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
data, err := a.rtmpServer.APIConnsGet(uuid)
data, err := a.RTMPServer.APIConnsGet(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -783,14 +769,14 @@ func (a *api) onRTMPConnsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTMPConnsKick(ctx *gin.Context) {
func (a *API) onRTMPConnsKick(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
err = a.rtmpServer.APIConnsKick(uuid)
err = a.RTMPServer.APIConnsKick(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -799,8 +785,8 @@ func (a *api) onRTMPConnsKick(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
func (a *api) onRTMPSConnsList(ctx *gin.Context) {
data, err := a.rtmpsServer.APIConnsList()
func (a *API) onRTMPSConnsList(ctx *gin.Context) {
data, err := a.RTMPSServer.APIConnsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -817,14 +803,14 @@ func (a *api) onRTMPSConnsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTMPSConnsGet(ctx *gin.Context) {
func (a *API) onRTMPSConnsGet(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
data, err := a.rtmpsServer.APIConnsGet(uuid)
data, err := a.RTMPSServer.APIConnsGet(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -833,14 +819,14 @@ func (a *api) onRTMPSConnsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onRTMPSConnsKick(ctx *gin.Context) {
func (a *API) onRTMPSConnsKick(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
err = a.rtmpsServer.APIConnsKick(uuid)
err = a.RTMPSServer.APIConnsKick(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -849,8 +835,8 @@ func (a *api) onRTMPSConnsKick(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
func (a *api) onHLSMuxersList(ctx *gin.Context) {
data, err := a.hlsManager.APIMuxersList()
func (a *API) onHLSMuxersList(ctx *gin.Context) {
data, err := a.HLSServer.APIMuxersList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -867,14 +853,14 @@ func (a *api) onHLSMuxersList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onHLSMuxersGet(ctx *gin.Context) {
func (a *API) onHLSMuxersGet(ctx *gin.Context) {
name, ok := paramName(ctx)
if !ok {
a.writeError(ctx, http.StatusBadRequest, fmt.Errorf("invalid name"))
return
}
data, err := a.hlsManager.APIMuxersGet(name)
data, err := a.HLSServer.APIMuxersGet(name)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -883,8 +869,8 @@ func (a *api) onHLSMuxersGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onWebRTCSessionsList(ctx *gin.Context) {
data, err := a.webRTCServer.APISessionsList()
func (a *API) onWebRTCSessionsList(ctx *gin.Context) {
data, err := a.WebRTCServer.APISessionsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -901,14 +887,14 @@ func (a *api) onWebRTCSessionsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onWebRTCSessionsGet(ctx *gin.Context) {
func (a *API) onWebRTCSessionsGet(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
data, err := a.webRTCServer.APISessionsGet(uuid)
data, err := a.WebRTCServer.APISessionsGet(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -917,14 +903,14 @@ func (a *api) onWebRTCSessionsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onWebRTCSessionsKick(ctx *gin.Context) {
func (a *API) onWebRTCSessionsKick(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
err = a.webRTCServer.APISessionsKick(uuid)
err = a.WebRTCServer.APISessionsKick(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -933,8 +919,8 @@ func (a *api) onWebRTCSessionsKick(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
func (a *api) onSRTConnsList(ctx *gin.Context) {
data, err := a.srtServer.APIConnsList()
func (a *API) onSRTConnsList(ctx *gin.Context) {
data, err := a.SRTServer.APIConnsList()
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -951,14 +937,14 @@ func (a *api) onSRTConnsList(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onSRTConnsGet(ctx *gin.Context) {
func (a *API) onSRTConnsGet(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
data, err := a.srtServer.APIConnsGet(uuid)
data, err := a.SRTServer.APIConnsGet(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -967,14 +953,14 @@ func (a *api) onSRTConnsGet(ctx *gin.Context) {
ctx.JSON(http.StatusOK, data)
}
func (a *api) onSRTConnsKick(ctx *gin.Context) {
func (a *API) onSRTConnsKick(ctx *gin.Context) {
uuid, err := uuid.Parse(ctx.Param("id"))
if err != nil {
a.writeError(ctx, http.StatusBadRequest, err)
return
}
err = a.srtServer.APIConnsKick(uuid)
err = a.SRTServer.APIConnsKick(uuid)
if err != nil {
a.writeError(ctx, http.StatusInternalServerError, err)
return
@ -983,9 +969,9 @@ func (a *api) onSRTConnsKick(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
// confReload is called by core.
func (a *api) confReload(conf *conf.Conf) {
// ReloadConf is called by core.
func (a *API) ReloadConf(conf *conf.Conf) {
a.mutex.Lock()
defer a.mutex.Unlock()
a.conf = conf
a.Conf = conf
}

39
internal/api/api_test.go Normal file
View File

@ -0,0 +1,39 @@
package api
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPaginate(t *testing.T) {
items := make([]int, 5)
for i := 0; i < 5; i++ {
items[i] = i
}
pageCount, err := paginate(&items, "1", "1")
require.NoError(t, err)
require.Equal(t, 5, pageCount)
require.Equal(t, []int{1}, items)
items = make([]int, 5)
for i := 0; i < 5; i++ {
items[i] = i
}
pageCount, err = paginate(&items, "3", "2")
require.NoError(t, err)
require.Equal(t, 2, pageCount)
require.Equal(t, []int{}, items)
items = make([]int, 6)
for i := 0; i < 6; i++ {
items[i] = i
}
pageCount, err = paginate(&items, "4", "1")
require.NoError(t, err)
require.Equal(t, 2, pageCount)
require.Equal(t, []int{4, 5}, items)
}

View File

@ -20,7 +20,7 @@ import (
"github.com/bluenviron/gortsplib/v4/pkg/format"
"github.com/bluenviron/mediacommon/pkg/codecs/mpeg4audio"
"github.com/bluenviron/mediacommon/pkg/formats/mpegts"
"github.com/datarhei/gosrt"
srt "github.com/datarhei/gosrt"
"github.com/google/uuid"
"github.com/pion/rtp"
"github.com/stretchr/testify/require"
@ -102,38 +102,6 @@ func httpRequest(t *testing.T, hc *http.Client, method string, ur string, in int
require.NoError(t, err)
}
func TestPagination(t *testing.T) {
items := make([]int, 5)
for i := 0; i < 5; i++ {
items[i] = i
}
pageCount, err := paginate(&items, "1", "1")
require.NoError(t, err)
require.Equal(t, 5, pageCount)
require.Equal(t, []int{1}, items)
items = make([]int, 5)
for i := 0; i < 5; i++ {
items[i] = i
}
pageCount, err = paginate(&items, "3", "2")
require.NoError(t, err)
require.Equal(t, 2, pageCount)
require.Equal(t, []int{}, items)
items = make([]int, 6)
for i := 0; i < 6; i++ {
items[i] = i
}
pageCount, err = paginate(&items, "4", "1")
require.NoError(t, err)
require.Equal(t, 2, pageCount)
require.Equal(t, []int{4, 5}, items)
}
func TestAPIConfigGlobalGet(t *testing.T) {
p, ok := newInstance("api: yes\n")
require.Equal(t, true, ok)

View File

@ -16,10 +16,13 @@ import (
"github.com/bluenviron/gortsplib/v4"
"github.com/gin-gonic/gin"
"github.com/bluenviron/mediamtx/internal/api"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/confwatcher"
"github.com/bluenviron/mediamtx/internal/externalcmd"
"github.com/bluenviron/mediamtx/internal/logger"
"github.com/bluenviron/mediamtx/internal/metrics"
"github.com/bluenviron/mediamtx/internal/pprof"
"github.com/bluenviron/mediamtx/internal/record"
"github.com/bluenviron/mediamtx/internal/rlimit"
"github.com/bluenviron/mediamtx/internal/servers/hls"
@ -84,8 +87,8 @@ type Core struct {
conf *conf.Conf
logger *logger.Logger
externalCmdPool *externalcmd.Pool
metrics *metrics
pprof *pprof
metrics *metrics.Metrics
pprof *pprof.PPROF
recordCleaner *record.Cleaner
pathManager *pathManager
rtspServer *rtsp.Server
@ -95,7 +98,7 @@ type Core struct {
hlsServer *hls.Server
webRTCServer *webrtc.Server
srtServer *srt.Server
api *api
api *api.API
confWatcher *confwatcher.ConfWatcher
// in
@ -275,12 +278,12 @@ func (p *Core) createResources(initial bool) error {
if p.conf.Metrics &&
p.metrics == nil {
p.metrics = &metrics{
p.metrics = &metrics.Metrics{
Address: p.conf.MetricsAddress,
ReadTimeout: p.conf.ReadTimeout,
Parent: p,
}
err = p.metrics.initialize()
err := p.metrics.Initialize()
if err != nil {
return err
}
@ -288,11 +291,12 @@ func (p *Core) createResources(initial bool) error {
if p.conf.PPROF &&
p.pprof == nil {
p.pprof, err = newPPROF(
p.conf.PPROFAddress,
p.conf.ReadTimeout,
p,
)
p.pprof = &pprof.PPROF{
Address: p.conf.PPROFAddress,
ReadTimeout: p.conf.ReadTimeout,
Parent: p,
}
err := p.pprof.Initialize()
if err != nil {
return err
}
@ -324,7 +328,7 @@ func (p *Core) createResources(initial bool) error {
)
if p.metrics != nil {
p.metrics.setPathManager(p.pathManager)
p.metrics.SetPathManager(p.pathManager)
}
}
@ -366,7 +370,7 @@ func (p *Core) createResources(initial bool) error {
}
if p.metrics != nil {
p.metrics.setRTSPServer(p.rtspServer)
p.metrics.SetRTSPServer(p.rtspServer)
}
}
@ -405,7 +409,7 @@ func (p *Core) createResources(initial bool) error {
}
if p.metrics != nil {
p.metrics.setRTSPSServer(p.rtspsServer)
p.metrics.SetRTSPSServer(p.rtspsServer)
}
}
@ -435,7 +439,7 @@ func (p *Core) createResources(initial bool) error {
}
if p.metrics != nil {
p.metrics.setRTMPServer(p.rtmpServer)
p.metrics.SetRTMPServer(p.rtmpServer)
}
}
@ -465,7 +469,7 @@ func (p *Core) createResources(initial bool) error {
}
if p.metrics != nil {
p.metrics.setRTMPSServer(p.rtmpsServer)
p.metrics.SetRTMPSServer(p.rtmpsServer)
}
}
@ -499,7 +503,7 @@ func (p *Core) createResources(initial bool) error {
p.pathManager.setHLSServer(p.hlsServer)
if p.metrics != nil {
p.metrics.setHLSServer(p.hlsServer)
p.metrics.SetHLSServer(p.hlsServer)
}
}
@ -524,14 +528,14 @@ func (p *Core) createResources(initial bool) error {
PathManager: p.pathManager,
Parent: p,
}
err = p.webRTCServer.Initialize()
err := p.webRTCServer.Initialize()
if err != nil {
p.webRTCServer = nil
return err
}
if p.metrics != nil {
p.metrics.setWebRTCServer(p.webRTCServer)
p.metrics.SetWebRTCServer(p.webRTCServer)
}
}
@ -551,32 +555,33 @@ func (p *Core) createResources(initial bool) error {
PathManager: p.pathManager,
Parent: p,
}
err = p.srtServer.Initialize()
err := p.srtServer.Initialize()
if err != nil {
return err
}
if p.metrics != nil {
p.metrics.setSRTServer(p.srtServer)
p.metrics.SetSRTServer(p.srtServer)
}
}
if p.conf.API &&
p.api == nil {
p.api, err = newAPI(
p.conf.APIAddress,
p.conf.ReadTimeout,
p.conf,
p.pathManager,
p.rtspServer,
p.rtspsServer,
p.rtmpServer,
p.rtmpsServer,
p.hlsServer,
p.webRTCServer,
p.srtServer,
p,
)
p.api = &api.API{
Address: p.conf.APIAddress,
ReadTimeout: p.conf.ReadTimeout,
Conf: p.conf,
PathManager: p.pathManager,
RTSPServer: p.rtspServer,
RTSPSServer: p.rtspsServer,
RTMPServer: p.rtmpServer,
RTMPSServer: p.rtmpsServer,
HLSServer: p.hlsServer,
WebRTCServer: p.webRTCServer,
SRTServer: p.srtServer,
Parent: p,
}
err := p.api.Initialize()
if err != nil {
return err
}
@ -626,7 +631,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
closeMetrics ||
closeLogger
if !closePathManager && !reflect.DeepEqual(newConf.Paths, p.conf.Paths) {
p.pathManager.confReload(newConf.Paths)
p.pathManager.ReloadConf(newConf.Paths)
}
closeRTSPServer := newConf == nil ||
@ -779,16 +784,16 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
if p.api != nil {
if closeAPI {
p.api.close()
p.api.Close()
p.api = nil
} else if !calledByAPI { // avoid a loop
p.api.confReload(newConf)
p.api.ReloadConf(newConf)
}
}
if closeSRTServer && p.srtServer != nil {
if p.metrics != nil {
p.metrics.setSRTServer(nil)
p.metrics.SetSRTServer(nil)
}
p.srtServer.Close()
@ -797,7 +802,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
if closeWebRTCServer && p.webRTCServer != nil {
if p.metrics != nil {
p.metrics.setWebRTCServer(nil)
p.metrics.SetWebRTCServer(nil)
}
p.webRTCServer.Close()
@ -806,7 +811,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
if closeHLSServer && p.hlsServer != nil {
if p.metrics != nil {
p.metrics.setHLSServer(nil)
p.metrics.SetHLSServer(nil)
}
p.pathManager.setHLSServer(nil)
@ -817,7 +822,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
if closeRTMPSServer && p.rtmpsServer != nil {
if p.metrics != nil {
p.metrics.setRTMPSServer(nil)
p.metrics.SetRTMPSServer(nil)
}
p.rtmpsServer.Close()
@ -826,7 +831,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
if closeRTMPServer && p.rtmpServer != nil {
if p.metrics != nil {
p.metrics.setRTMPServer(nil)
p.metrics.SetRTMPServer(nil)
}
p.rtmpServer.Close()
@ -835,7 +840,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
if closeRTSPSServer && p.rtspsServer != nil {
if p.metrics != nil {
p.metrics.setRTSPSServer(nil)
p.metrics.SetRTSPSServer(nil)
}
p.rtspsServer.Close()
@ -844,7 +849,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
if closeRTSPServer && p.rtspServer != nil {
if p.metrics != nil {
p.metrics.setRTSPServer(nil)
p.metrics.SetRTSPServer(nil)
}
p.rtspServer.Close()
@ -853,7 +858,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
if closePathManager && p.pathManager != nil {
if p.metrics != nil {
p.metrics.setPathManager(nil)
p.metrics.SetPathManager(nil)
}
p.pathManager.close()
@ -866,12 +871,12 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
}
if closePPROF && p.pprof != nil {
p.pprof.close()
p.pprof.Close()
p.pprof = nil
}
if closeMetrics && p.metrics != nil {
p.metrics.close()
p.metrics.Close()
p.metrics = nil
}
@ -892,8 +897,8 @@ func (p *Core) reloadConf(newConf *conf.Conf, calledByAPI bool) error {
return p.createResources(false)
}
// apiConfigSet is called by api.
func (p *Core) apiConfigSet(conf *conf.Conf) {
// APIConfigSet is called by api.
func (p *Core) APIConfigSet(conf *conf.Conf) {
select {
case p.chAPIConfigSet <- conf:
case <-p.ctx.Done():

View File

@ -1019,8 +1019,8 @@ func (pa *path) RemoveReader(req defs.PathRemoveReaderReq) {
}
}
// apiPathsGet is called by api.
func (pa *path) apiPathsGet(req pathAPIPathsGetReq) (*defs.APIPath, error) {
// APIPathsGet is called by api.
func (pa *path) APIPathsGet(req pathAPIPathsGetReq) (*defs.APIPath, error) {
req.res = make(chan pathAPIPathsGetRes)
select {
case pa.chAPIPathsGet <- req:

View File

@ -433,8 +433,8 @@ func (pm *pathManager) removePath(pa *path) {
delete(pm.paths, pa.name)
}
// confReload is called by core.
func (pm *pathManager) confReload(pathConfs map[string]*conf.Path) {
// ReloadConf is called by core.
func (pm *pathManager) ReloadConf(pathConfs map[string]*conf.Path) {
select {
case pm.chReloadConf <- pathConfs:
case <-pm.ctx.Done():
@ -545,8 +545,8 @@ func (pm *pathManager) setHLSServer(s pathManagerHLSServer) {
}
}
// apiPathsList is called by api.
func (pm *pathManager) apiPathsList() (*defs.APIPathList, error) {
// APIPathsList is called by api.
func (pm *pathManager) APIPathsList() (*defs.APIPathList, error) {
req := pathAPIPathsListReq{
res: make(chan pathAPIPathsListRes),
}
@ -560,7 +560,7 @@ func (pm *pathManager) apiPathsList() (*defs.APIPathList, error) {
}
for _, pa := range res.paths {
item, err := pa.apiPathsGet(pathAPIPathsGetReq{})
item, err := pa.APIPathsGet(pathAPIPathsGetReq{})
if err == nil {
res.data.Items = append(res.data.Items, item)
}
@ -577,8 +577,8 @@ func (pm *pathManager) apiPathsList() (*defs.APIPathList, error) {
}
}
// apiPathsGet is called by api.
func (pm *pathManager) apiPathsGet(name string) (*defs.APIPath, error) {
// APIPathsGet is called by api.
func (pm *pathManager) APIPathsGet(name string) (*defs.APIPath, error) {
req := pathAPIPathsGetReq{
name: name,
res: make(chan pathAPIPathsGetRes),
@ -591,7 +591,7 @@ func (pm *pathManager) apiPathsGet(name string) (*defs.APIPath, error) {
return nil, res.err
}
data, err := res.path.apiPathsGet(req)
data, err := res.path.APIPathsGet(req)
return data, err
case <-pm.ctx.Done():

View File

@ -78,7 +78,7 @@ func TestPathAutoDeletion(t *testing.T) {
}
}()
data, err := p.pathManager.apiPathsList()
data, err := p.pathManager.APIPathsList()
require.NoError(t, err)
require.Equal(t, 0, len(data.Items))

View File

@ -1,20 +1,27 @@
package core
// Package metrics contains the metrics provider.
package metrics
import (
"io"
"net/http"
"reflect"
"strconv"
"sync"
"time"
"github.com/gin-gonic/gin"
"github.com/bluenviron/mediamtx/internal/api"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger"
"github.com/bluenviron/mediamtx/internal/protocols/httpserv"
"github.com/bluenviron/mediamtx/internal/restrictnetwork"
)
func interfaceIsEmpty(i interface{}) bool {
return reflect.ValueOf(i).Kind() != reflect.Ptr || reflect.ValueOf(i).IsNil()
}
func metric(key string, tags string, value int64) string {
return key + tags + " " + strconv.FormatInt(value, 10) + "\n"
}
@ -23,24 +30,26 @@ type metricsParent interface {
logger.Writer
}
type metrics struct {
// Metrics is a metrics provider.
type Metrics struct {
Address string
ReadTimeout conf.StringDuration
Parent metricsParent
httpServer *httpserv.WrappedServer
mutex sync.Mutex
pathManager apiPathManager
rtspServer apiRTSPServer
rtspsServer apiRTSPServer
rtmpServer apiRTMPServer
rtmpsServer apiRTMPServer
srtServer apiSRTServer
hlsManager apiHLSServer
webRTCServer apiWebRTCServer
pathManager api.PathManager
rtspServer api.RTSPServer
rtspsServer api.RTSPServer
rtmpServer api.RTMPServer
rtmpsServer api.RTMPServer
srtServer api.SRTServer
hlsManager api.HLSServer
webRTCServer api.WebRTCServer
}
func (m *metrics) initialize() error {
// Initialize initializes metrics.
func (m *Metrics) Initialize() error {
router := gin.New()
router.SetTrustedProxies(nil) //nolint:errcheck
@ -67,20 +76,21 @@ func (m *metrics) initialize() error {
return nil
}
func (m *metrics) close() {
// Close closes Metrics.
func (m *Metrics) Close() {
m.Log(logger.Info, "listener is closing")
m.httpServer.Close()
}
// Log implements logger.Writer.
func (m *metrics) Log(level logger.Level, format string, args ...interface{}) {
func (m *Metrics) Log(level logger.Level, format string, args ...interface{}) {
m.Parent.Log(level, "[metrics] "+format, args...)
}
func (m *metrics) onMetrics(ctx *gin.Context) {
func (m *Metrics) onMetrics(ctx *gin.Context) {
out := ""
data, err := m.pathManager.apiPathsList()
data, err := m.pathManager.APIPathsList()
if err == nil && len(data.Items) != 0 {
for _, i := range data.Items {
var state string
@ -249,57 +259,57 @@ func (m *metrics) onMetrics(ctx *gin.Context) {
io.WriteString(ctx.Writer, out) //nolint:errcheck
}
// setPathManager is called by core.
func (m *metrics) setPathManager(s apiPathManager) {
// SetPathManager is called by core.
func (m *Metrics) SetPathManager(s api.PathManager) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.pathManager = s
}
// setHLSServer is called by core.
func (m *metrics) setHLSServer(s apiHLSServer) {
// SetHLSServer is called by core.
func (m *Metrics) SetHLSServer(s api.HLSServer) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.hlsManager = s
}
// setRTSPServer is called by core.
func (m *metrics) setRTSPServer(s apiRTSPServer) {
// SetRTSPServer is called by core.
func (m *Metrics) SetRTSPServer(s api.RTSPServer) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.rtspServer = s
}
// setRTSPSServer is called by core.
func (m *metrics) setRTSPSServer(s apiRTSPServer) {
// SetRTSPSServer is called by core.
func (m *Metrics) SetRTSPSServer(s api.RTSPServer) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.rtspsServer = s
}
// setRTMPServer is called by core.
func (m *metrics) setRTMPServer(s apiRTMPServer) {
// SetRTMPServer is called by core.
func (m *Metrics) SetRTMPServer(s api.RTMPServer) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.rtmpServer = s
}
// setRTMPSServer is called by core.
func (m *metrics) setRTMPSServer(s apiRTMPServer) {
// SetRTMPSServer is called by core.
func (m *Metrics) SetRTMPSServer(s api.RTMPServer) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.rtmpsServer = s
}
// setSRTServer is called by core.
func (m *metrics) setSRTServer(s apiSRTServer) {
// SetSRTServer is called by core.
func (m *Metrics) SetSRTServer(s api.SRTServer) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.srtServer = s
}
// setWebRTCServer is called by core.
func (m *metrics) setWebRTCServer(s apiWebRTCServer) {
// SetWebRTCServer is called by core.
func (m *Metrics) SetWebRTCServer(s api.WebRTCServer) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.webRTCServer = s

View File

@ -1,4 +1,5 @@
package core
// Package pprof contains a pprof exporter.
package pprof
import (
"net/http"
@ -17,48 +18,45 @@ type pprofParent interface {
logger.Writer
}
type pprof struct {
parent pprofParent
// PPROF is a pprof exporter.
type PPROF struct {
Address string
ReadTimeout conf.StringDuration
Parent pprofParent
httpServer *httpserv.WrappedServer
}
func newPPROF(
address string,
readTimeout conf.StringDuration,
parent pprofParent,
) (*pprof, error) {
pp := &pprof{
parent: parent,
}
network, address := restrictnetwork.Restrict("tcp", address)
// Initialize initializes PPROF.
func (pp *PPROF) Initialize() error {
network, address := restrictnetwork.Restrict("tcp", pp.Address)
var err error
pp.httpServer, err = httpserv.NewWrappedServer(
network,
address,
time.Duration(readTimeout),
time.Duration(pp.ReadTimeout),
"",
"",
http.DefaultServeMux,
pp,
)
if err != nil {
return nil, err
return err
}
pp.Log(logger.Info, "listener opened on "+address)
return pp, nil
return nil
}
func (pp *pprof) close() {
// Close closes PPROF.
func (pp *PPROF) Close() {
pp.Log(logger.Info, "listener is closing")
pp.httpServer.Close()
}
// Log implements logger.Writer.
func (pp *pprof) Log(level logger.Level, format string, args ...interface{}) {
pp.parent.Log(level, "[pprof] "+format, args...)
func (pp *PPROF) Log(level logger.Level, format string, args ...interface{}) {
pp.Parent.Log(level, "[pprof] "+format, args...)
}