From 52019ac75e05736386066d64bc99da644d59df62 Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Wed, 14 Oct 2020 00:02:55 +0200 Subject: [PATCH] move externalcmd, syslog, loghandler into dedicated folders --- client.go | 20 ++--- conf.go | 11 +-- externalcmd.go => externalcmd/externalcmd.go | 10 +-- log.go | 74 ------------------- loghandler/loghandler.go | 77 ++++++++++++++++++++ logsyslog_unix.go | 30 -------- logsyslog_win.go | 21 ------ main.go | 8 +- path.go | 16 ++-- syslog/syslog_unix.go | 31 ++++++++ syslog/syslog_win.go | 22 ++++++ 11 files changed, 166 insertions(+), 154 deletions(-) rename externalcmd.go => externalcmd/externalcmd.go (84%) delete mode 100644 log.go create mode 100644 loghandler/loghandler.go delete mode 100644 logsyslog_unix.go delete mode 100644 logsyslog_win.go create mode 100644 syslog/syslog_unix.go create mode 100644 syslog/syslog_win.go diff --git a/client.go b/client.go index 7f1b6564..eeff5828 100644 --- a/client.go +++ b/client.go @@ -15,6 +15,8 @@ import ( "github.com/aler9/gortsplib/base" "github.com/aler9/gortsplib/headers" "github.com/aler9/gortsplib/rtcpreceiver" + + "github.com/aler9/rtsp-simple-server/externalcmd" ) const ( @@ -191,10 +193,10 @@ var errRunPlay = errors.New("play") var errRunRecord = errors.New("record") func (c *client) run() { - var onConnectCmd *externalCmd + var onConnectCmd *externalcmd.ExternalCmd if c.p.conf.RunOnConnect != "" { var err error - onConnectCmd, err = startExternalCommand(c.p.conf.RunOnConnect, "") + onConnectCmd, err = externalcmd.New(c.p.conf.RunOnConnect, "") if err != nil { c.log("ERR: %s", err) } @@ -207,7 +209,7 @@ func (c *client) run() { } if onConnectCmd != nil { - onConnectCmd.close() + onConnectCmd.Close() } close(c.describe) @@ -889,10 +891,10 @@ func (c *client) runPlay() bool { return "tracks" }(), c.streamProtocol) - var onReadCmd *externalCmd + var onReadCmd *externalcmd.ExternalCmd if c.path.conf.RunOnRead != "" { var err error - onReadCmd, err = startExternalCommand(c.path.conf.RunOnRead, c.path.name) + onReadCmd, err = externalcmd.New(c.path.conf.RunOnRead, c.path.name) if err != nil { c.log("ERR: %s", err) } @@ -905,7 +907,7 @@ func (c *client) runPlay() bool { } if onReadCmd != nil { - onReadCmd.close() + onReadCmd.Close() } return false @@ -1033,10 +1035,10 @@ func (c *client) runRecord() bool { return "tracks" }(), c.streamProtocol) - var onPublishCmd *externalCmd + var onPublishCmd *externalcmd.ExternalCmd if c.path.conf.RunOnPublish != "" { var err error - onPublishCmd, err = startExternalCommand(c.path.conf.RunOnPublish, c.path.name) + onPublishCmd, err = externalcmd.New(c.path.conf.RunOnPublish, c.path.name) if err != nil { c.log("ERR: %s", err) } @@ -1049,7 +1051,7 @@ func (c *client) runRecord() bool { } if onPublishCmd != nil { - onPublishCmd.close() + onPublishCmd.Close() } return false diff --git a/conf.go b/conf.go index 6897857b..28b6a06e 100644 --- a/conf.go +++ b/conf.go @@ -14,6 +14,7 @@ import ( "gopkg.in/yaml.v2" "github.com/aler9/rtsp-simple-server/confenv" + "github.com/aler9/rtsp-simple-server/loghandler" ) type pathConf struct { @@ -51,7 +52,7 @@ type conf struct { Metrics bool `yaml:"metrics"` Pprof bool `yaml:"pprof"` LogDestinations []string `yaml:"logDestinations"` - logDestinationsParsed map[logDestination]struct{} `` + logDestinationsParsed map[loghandler.Destination]struct{} `` LogFile string `yaml:"logFile"` Paths map[string]*pathConf `yaml:"paths"` } @@ -161,17 +162,17 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) { if len(conf.LogDestinations) == 0 { conf.LogDestinations = []string{"stdout"} } - conf.logDestinationsParsed = make(map[logDestination]struct{}) + conf.logDestinationsParsed = make(map[loghandler.Destination]struct{}) for _, dest := range conf.LogDestinations { switch dest { case "stdout": - conf.logDestinationsParsed[logDestinationStdout] = struct{}{} + conf.logDestinationsParsed[loghandler.DestinationStdout] = struct{}{} case "file": - conf.logDestinationsParsed[logDestinationFile] = struct{}{} + conf.logDestinationsParsed[loghandler.DestinationFile] = struct{}{} case "syslog": - conf.logDestinationsParsed[logDestinationSyslog] = struct{}{} + conf.logDestinationsParsed[loghandler.DestinationSyslog] = struct{}{} default: return nil, fmt.Errorf("unsupported log destination: %s", dest) diff --git a/externalcmd.go b/externalcmd/externalcmd.go similarity index 84% rename from externalcmd.go rename to externalcmd/externalcmd.go index 1d628ced..da3fd2a6 100644 --- a/externalcmd.go +++ b/externalcmd/externalcmd.go @@ -1,4 +1,4 @@ -package main +package externalcmd import ( "os" @@ -7,11 +7,11 @@ import ( "strings" ) -type externalCmd struct { +type ExternalCmd struct { cmd *exec.Cmd } -func startExternalCommand(cmdstr string, pathName string) (*externalCmd, error) { +func New(cmdstr string, pathName string) (*ExternalCmd, error) { var cmd *exec.Cmd if runtime.GOOS == "windows" { // on Windows the shell is not used and command is started directly @@ -38,12 +38,12 @@ func startExternalCommand(cmdstr string, pathName string) (*externalCmd, error) return nil, err } - return &externalCmd{ + return &ExternalCmd{ cmd: cmd, }, nil } -func (e *externalCmd) close() { +func (e *ExternalCmd) Close() { // on Windows it's not possible to send os.Interrupt to a process // Kill() is the only supported way if runtime.GOOS == "windows" { diff --git a/log.go b/log.go deleted file mode 100644 index 5ae5ec15..00000000 --- a/log.go +++ /dev/null @@ -1,74 +0,0 @@ -package main - -import ( - "log" - "os" -) - -type logDestination int - -const ( - logDestinationStdout logDestination = iota - logDestinationFile - logDestinationSyslog -) - -type logHandler struct { - logDestinations map[logDestination]struct{} - logFile *os.File - logSyslog *logSyslog -} - -func newLogHandler(logDestinations map[logDestination]struct{}, logFilePath string) (*logHandler, error) { - lh := &logHandler{ - logDestinations: logDestinations, - } - - if _, ok := logDestinations[logDestinationFile]; ok { - var err error - lh.logFile, err = os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - lh.close() - return nil, err - } - } - - if _, ok := logDestinations[logDestinationSyslog]; ok { - var err error - lh.logSyslog, err = newLogSyslog() - if err != nil { - lh.close() - return nil, err - } - } - - log.SetOutput(lh) - - return lh, nil -} - -func (lh *logHandler) close() { - if lh.logFile != nil { - lh.logFile.Close() - } - - if lh.logSyslog != nil { - lh.logSyslog.close() - } -} - -func (lh *logHandler) Write(p []byte) (int, error) { - if _, ok := lh.logDestinations[logDestinationStdout]; ok { - print(string(p)) - } - - if _, ok := lh.logDestinations[logDestinationFile]; ok { - lh.logFile.Write(p) - } - - if _, ok := lh.logDestinations[logDestinationSyslog]; ok { - lh.logSyslog.write(p) - } - - return len(p), nil -} diff --git a/loghandler/loghandler.go b/loghandler/loghandler.go new file mode 100644 index 00000000..41a1e985 --- /dev/null +++ b/loghandler/loghandler.go @@ -0,0 +1,77 @@ +package loghandler + +import ( + "io" + "log" + "os" + + "github.com/aler9/rtsp-simple-server/syslog" +) + +type Destination int + +const ( + DestinationStdout Destination = iota + DestinationFile + DestinationSyslog +) + +type LogHandler struct { + destinations map[Destination]struct{} + file *os.File + syslog io.WriteCloser +} + +func New(destinations map[Destination]struct{}, filePath string) (*LogHandler, error) { + lh := &LogHandler{ + destinations: destinations, + } + + if _, ok := destinations[DestinationFile]; ok { + var err error + lh.file, err = os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + lh.Close() + return nil, err + } + } + + if _, ok := destinations[DestinationSyslog]; ok { + var err error + lh.syslog, err = syslog.New("rtsp-simple-server") + if err != nil { + lh.Close() + return nil, err + } + } + + log.SetOutput(lh) + + return lh, nil +} + +func (lh *LogHandler) Close() { + if lh.file != nil { + lh.file.Close() + } + + if lh.syslog != nil { + lh.syslog.Close() + } +} + +func (lh *LogHandler) Write(p []byte) (int, error) { + if _, ok := lh.destinations[DestinationStdout]; ok { + print(string(p)) + } + + if _, ok := lh.destinations[DestinationFile]; ok { + lh.file.Write(p) + } + + if _, ok := lh.destinations[DestinationSyslog]; ok { + lh.syslog.Write(p) + } + + return len(p), nil +} diff --git a/logsyslog_unix.go b/logsyslog_unix.go deleted file mode 100644 index 8e2c7729..00000000 --- a/logsyslog_unix.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build !windows - -package main - -import ( - "log/syslog" -) - -type logSyslog struct { - inner *syslog.Writer -} - -func newLogSyslog() (*logSyslog, error) { - inner, err := syslog.New(syslog.LOG_INFO|syslog.LOG_DAEMON, "rtsp-simple-server") - if err != nil { - return nil, err - } - - return &logSyslog{ - inner: inner, - }, nil -} - -func (ls *logSyslog) close() { - ls.inner.Close() -} - -func (ls *logSyslog) write(p []byte) (int, error) { - return ls.inner.Write(p) -} diff --git a/logsyslog_win.go b/logsyslog_win.go deleted file mode 100644 index ac19aa0c..00000000 --- a/logsyslog_win.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build windows - -package main - -import ( - "fmt" -) - -type logSyslog struct { -} - -func newLogSyslog() (*logSyslog, error) { - return nil, fmt.Errorf("not implemented on windows") -} - -func (ls *logSyslog) close() { -} - -func (ls *logSyslog) write(p []byte) (int, error) { - return 0, nil -} diff --git a/main.go b/main.go index 4f4c2e7b..68c9cfcf 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,8 @@ import ( "github.com/aler9/gortsplib" "gopkg.in/alecthomas/kingpin.v2" + + "github.com/aler9/rtsp-simple-server/loghandler" ) var Version = "v0.0.0" @@ -21,7 +23,7 @@ const ( type program struct { conf *conf - logHandler *logHandler + logHandler *loghandler.LogHandler metrics *metrics pprof *pprof paths map[string]*path @@ -75,7 +77,7 @@ func newProgram(args []string, stdin io.Reader) (*program, error) { return nil, err } - logHandler, err := newLogHandler(conf.logDestinationsParsed, conf.LogFile) + logHandler, err := loghandler.New(conf.logDestinationsParsed, conf.LogFile) if err != nil { return nil, err } @@ -376,7 +378,7 @@ outer: p.pprof.close() } - p.logHandler.close() + p.logHandler.Close() close(p.clientNew) close(p.clientClose) diff --git a/path.go b/path.go index 8b18cb54..e85bb3ea 100644 --- a/path.go +++ b/path.go @@ -5,6 +5,8 @@ import ( "strings" "sync/atomic" "time" + + "github.com/aler9/rtsp-simple-server/externalcmd" ) const ( @@ -28,8 +30,8 @@ type path struct { sourceSdp []byte lastDescribeReq time.Time lastDescribeActivation time.Time - onInitCmd *externalCmd - onDemandCmd *externalCmd + onInitCmd *externalcmd.ExternalCmd + onDemandCmd *externalcmd.ExternalCmd } func newPath(p *program, name string, conf *pathConf) *path { @@ -67,7 +69,7 @@ func (pa *path) onInit() { pa.log("starting on init command") var err error - pa.onInitCmd, err = startExternalCommand(pa.conf.RunOnInit, pa.name) + pa.onInitCmd, err = externalcmd.New(pa.conf.RunOnInit, pa.name) if err != nil { pa.log("ERR: %s", err) } @@ -86,12 +88,12 @@ func (pa *path) onClose(wait bool) { if pa.onInitCmd != nil { pa.log("stopping on init command (closing)") - pa.onInitCmd.close() + pa.onInitCmd.Close() } if pa.onDemandCmd != nil { pa.log("stopping on demand command (closing)") - pa.onDemandCmd.close() + pa.onDemandCmd.Close() } for c := range pa.p.clients { @@ -182,7 +184,7 @@ func (pa *path) onCheck() { !pa.hasClientReaders() && time.Since(pa.lastDescribeReq) >= onDemandCmdStopAfterDescribePeriod { pa.log("stopping on demand command (not requested anymore)") - pa.onDemandCmd.close() + pa.onDemandCmd.Close() pa.onDemandCmd = nil } @@ -247,7 +249,7 @@ func (pa *path) onDescribe(client *client) { pa.lastDescribeActivation = time.Now() var err error - pa.onDemandCmd, err = startExternalCommand(pa.conf.RunOnDemand, pa.name) + pa.onDemandCmd, err = externalcmd.New(pa.conf.RunOnDemand, pa.name) if err != nil { pa.log("ERR: %s", err) } diff --git a/syslog/syslog_unix.go b/syslog/syslog_unix.go new file mode 100644 index 00000000..87f1184c --- /dev/null +++ b/syslog/syslog_unix.go @@ -0,0 +1,31 @@ +// +build !windows + +package syslog + +import ( + "io" + native "log/syslog" +) + +type syslog struct { + inner *native.Writer +} + +func New(prefix string) (io.WriteCloser, error) { + inner, err := native.New(native.LOG_INFO|native.LOG_DAEMON, prefix) + if err != nil { + return nil, err + } + + return &syslog{ + inner: inner, + }, nil +} + +func (ls *syslog) Close() error { + return ls.inner.Close() +} + +func (ls *syslog) Write(p []byte) (int, error) { + return ls.inner.Write(p) +} diff --git a/syslog/syslog_win.go b/syslog/syslog_win.go new file mode 100644 index 00000000..7be6b4ea --- /dev/null +++ b/syslog/syslog_win.go @@ -0,0 +1,22 @@ +// +build windows + +package syslog + +import ( + "fmt" +) + +type syslog struct { +} + +func New(prefix string) (io.WriteCloser, error) { + return nil, fmt.Errorf("not implemented on windows") +} + +func (ls *syslog) Close() error { + return nil +} + +func (ls *syslog) Write(p []byte) (int, error) { + return 0, nil +}