From a5bd05dcfcfe924a669b77fe54dde7e64e107809 Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Thu, 30 Jul 2020 19:21:36 +0200 Subject: [PATCH] add options logDestinations, logFile (#37) --- Makefile | 3 ++- conf.go | 49 +++++++++++++++++++++++++++++++----------- main.go | 32 ++++++++++++++++++++++++--- rtsp-simple-server.yml | 4 ++++ 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index bfc4e98f..98b37b79 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,8 @@ define CONFIG_RUN #rtspPort: 8555 #rtpPort: 8002 #rtcpPort: 8003 -metrics: yes +#metrics: yes +logDestinations: [stdout, file] paths: all: diff --git a/conf.go b/conf.go index c13c7ed2..870f7d8e 100644 --- a/conf.go +++ b/conf.go @@ -32,19 +32,22 @@ type confPath struct { } type conf struct { - Protocols []string `yaml:"protocols"` - protocolsParsed map[gortsplib.StreamProtocol]struct{} `` - RtspPort int `yaml:"rtspPort"` - RtpPort int `yaml:"rtpPort"` - RtcpPort int `yaml:"rtcpPort"` - RunOnConnect string `yaml:"runOnConnect"` - ReadTimeout time.Duration `yaml:"readTimeout"` - WriteTimeout time.Duration `yaml:"writeTimeout"` - AuthMethods []string `yaml:"authMethods"` - authMethodsParsed []gortsplib.AuthMethod `` - Metrics bool `yaml:"metrics"` - Pprof bool `yaml:"pprof"` - Paths map[string]*confPath `yaml:"paths"` + Protocols []string `yaml:"protocols"` + protocolsParsed map[gortsplib.StreamProtocol]struct{} `` + RtspPort int `yaml:"rtspPort"` + RtpPort int `yaml:"rtpPort"` + RtcpPort int `yaml:"rtcpPort"` + RunOnConnect string `yaml:"runOnConnect"` + ReadTimeout time.Duration `yaml:"readTimeout"` + WriteTimeout time.Duration `yaml:"writeTimeout"` + AuthMethods []string `yaml:"authMethods"` + authMethodsParsed []gortsplib.AuthMethod `` + Metrics bool `yaml:"metrics"` + Pprof bool `yaml:"pprof"` + LogDestinations []string `yaml:"logDestinations"` + logDestinationsParsed map[logDestination]struct{} `` + LogFile string `yaml:"logFile"` + Paths map[string]*confPath `yaml:"paths"` } func loadConf(fpath string, stdin io.Reader) (*conf, error) { @@ -144,6 +147,26 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) { } } + if len(conf.LogDestinations) == 0 { + conf.LogDestinations = []string{"stdout"} + } + conf.logDestinationsParsed = make(map[logDestination]struct{}) + for _, dest := range conf.LogDestinations { + switch dest { + case "stdout": + conf.logDestinationsParsed[logDestinationStdout] = struct{}{} + + case "file": + conf.logDestinationsParsed[logDestinationFile] = struct{}{} + + default: + return nil, fmt.Errorf("unsupported log destination: %s", dest) + } + } + if conf.LogFile == "" { + conf.LogFile = "rtsp-simple-server.log" + } + if len(conf.Paths) == 0 { conf.Paths = map[string]*confPath{ "all": {}, diff --git a/main.go b/main.go index 9de9bde2..b59fff2e 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,13 @@ const ( pprofAddress = ":9999" ) +type logDestination int + +const ( + logDestinationStdout logDestination = iota + logDestinationFile +) + type programEvent interface { isProgramEvent() } @@ -161,6 +168,7 @@ func (programEventTerminate) isProgramEvent() {} type program struct { conf *conf + logFile *os.File metrics *metrics serverRtsp *serverTcp serverRtp *serverUdp @@ -202,6 +210,15 @@ func newProgram(args []string, stdin io.Reader) (*program, error) { done: make(chan struct{}), } + if _, ok := p.conf.logDestinationsParsed[logDestinationFile]; ok { + p.logFile, err = os.OpenFile(p.conf.LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Fatal("ERR:", err) + } + } + + p.log("rtsp-simple-server %s", Version) + for path, confp := range conf.Paths { if path == "all" { continue @@ -216,8 +233,6 @@ func newProgram(args []string, stdin io.Reader) (*program, error) { } } - p.log("rtsp-simple-server %s", Version) - if conf.Metrics { p.metrics = newMetrics(p) } @@ -263,8 +278,15 @@ func newProgram(args []string, stdin io.Reader) (*program, error) { } func (p *program) log(format string, args ...interface{}) { - log.Printf("[%d/%d/%d] "+format, append([]interface{}{len(p.clients), + line := fmt.Sprintf("[%d/%d/%d] "+format, append([]interface{}{len(p.clients), p.publisherCount, p.readerCount}, args...)...) + + if _, ok := p.conf.logDestinationsParsed[logDestinationStdout]; ok { + log.Println(line) + } + if _, ok := p.conf.logDestinationsParsed[logDestinationFile]; ok { + p.logFile.WriteString(line + "\n") + } } func (p *program) run() { @@ -491,6 +513,10 @@ outer: p.metrics.close() } + if p.logFile != nil { + p.logFile.Close() + } + close(p.events) close(p.done) } diff --git a/rtsp-simple-server.yml b/rtsp-simple-server.yml index fd587330..74a3c971 100644 --- a/rtsp-simple-server.yml +++ b/rtsp-simple-server.yml @@ -21,6 +21,10 @@ authMethods: [basic, digest] metrics: false # enable pprof on port 9999 to monitor performances pprof: false +# destinations of log messages; available options are 'stdout' and 'file' +logDestinations: [stdout] +# if 'file' is in logDestinations, this is the file that will receive the logs +logFile: rtsp-simple-server.log # these settings are path-dependent. The settings under the path 'all' are # applied to all paths that do not match a specific entry.