Browse Source

move externalcmd, syslog, loghandler into dedicated folders

pull/169/head
aler9 6 years ago
parent
commit
52019ac75e
  1. 20
      client.go
  2. 11
      conf.go
  3. 10
      externalcmd/externalcmd.go
  4. 74
      log.go
  5. 77
      loghandler/loghandler.go
  6. 30
      logsyslog_unix.go
  7. 21
      logsyslog_win.go
  8. 8
      main.go
  9. 16
      path.go
  10. 31
      syslog/syslog_unix.go
  11. 22
      syslog/syslog_win.go

20
client.go

@ -15,6 +15,8 @@ import (
"github.com/aler9/gortsplib/base" "github.com/aler9/gortsplib/base"
"github.com/aler9/gortsplib/headers" "github.com/aler9/gortsplib/headers"
"github.com/aler9/gortsplib/rtcpreceiver" "github.com/aler9/gortsplib/rtcpreceiver"
"github.com/aler9/rtsp-simple-server/externalcmd"
) )
const ( const (
@ -191,10 +193,10 @@ var errRunPlay = errors.New("play")
var errRunRecord = errors.New("record") var errRunRecord = errors.New("record")
func (c *client) run() { func (c *client) run() {
var onConnectCmd *externalCmd var onConnectCmd *externalcmd.ExternalCmd
if c.p.conf.RunOnConnect != "" { if c.p.conf.RunOnConnect != "" {
var err error var err error
onConnectCmd, err = startExternalCommand(c.p.conf.RunOnConnect, "") onConnectCmd, err = externalcmd.New(c.p.conf.RunOnConnect, "")
if err != nil { if err != nil {
c.log("ERR: %s", err) c.log("ERR: %s", err)
} }
@ -207,7 +209,7 @@ func (c *client) run() {
} }
if onConnectCmd != nil { if onConnectCmd != nil {
onConnectCmd.close() onConnectCmd.Close()
} }
close(c.describe) close(c.describe)
@ -889,10 +891,10 @@ func (c *client) runPlay() bool {
return "tracks" return "tracks"
}(), c.streamProtocol) }(), c.streamProtocol)
var onReadCmd *externalCmd var onReadCmd *externalcmd.ExternalCmd
if c.path.conf.RunOnRead != "" { if c.path.conf.RunOnRead != "" {
var err error 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 { if err != nil {
c.log("ERR: %s", err) c.log("ERR: %s", err)
} }
@ -905,7 +907,7 @@ func (c *client) runPlay() bool {
} }
if onReadCmd != nil { if onReadCmd != nil {
onReadCmd.close() onReadCmd.Close()
} }
return false return false
@ -1033,10 +1035,10 @@ func (c *client) runRecord() bool {
return "tracks" return "tracks"
}(), c.streamProtocol) }(), c.streamProtocol)
var onPublishCmd *externalCmd var onPublishCmd *externalcmd.ExternalCmd
if c.path.conf.RunOnPublish != "" { if c.path.conf.RunOnPublish != "" {
var err error 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 { if err != nil {
c.log("ERR: %s", err) c.log("ERR: %s", err)
} }
@ -1049,7 +1051,7 @@ func (c *client) runRecord() bool {
} }
if onPublishCmd != nil { if onPublishCmd != nil {
onPublishCmd.close() onPublishCmd.Close()
} }
return false return false

11
conf.go

@ -14,6 +14,7 @@ import (
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"github.com/aler9/rtsp-simple-server/confenv" "github.com/aler9/rtsp-simple-server/confenv"
"github.com/aler9/rtsp-simple-server/loghandler"
) )
type pathConf struct { type pathConf struct {
@ -51,7 +52,7 @@ type conf struct {
Metrics bool `yaml:"metrics"` Metrics bool `yaml:"metrics"`
Pprof bool `yaml:"pprof"` Pprof bool `yaml:"pprof"`
LogDestinations []string `yaml:"logDestinations"` LogDestinations []string `yaml:"logDestinations"`
logDestinationsParsed map[logDestination]struct{} `` logDestinationsParsed map[loghandler.Destination]struct{} ``
LogFile string `yaml:"logFile"` LogFile string `yaml:"logFile"`
Paths map[string]*pathConf `yaml:"paths"` Paths map[string]*pathConf `yaml:"paths"`
} }
@ -161,17 +162,17 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) {
if len(conf.LogDestinations) == 0 { if len(conf.LogDestinations) == 0 {
conf.LogDestinations = []string{"stdout"} conf.LogDestinations = []string{"stdout"}
} }
conf.logDestinationsParsed = make(map[logDestination]struct{}) conf.logDestinationsParsed = make(map[loghandler.Destination]struct{})
for _, dest := range conf.LogDestinations { for _, dest := range conf.LogDestinations {
switch dest { switch dest {
case "stdout": case "stdout":
conf.logDestinationsParsed[logDestinationStdout] = struct{}{} conf.logDestinationsParsed[loghandler.DestinationStdout] = struct{}{}
case "file": case "file":
conf.logDestinationsParsed[logDestinationFile] = struct{}{} conf.logDestinationsParsed[loghandler.DestinationFile] = struct{}{}
case "syslog": case "syslog":
conf.logDestinationsParsed[logDestinationSyslog] = struct{}{} conf.logDestinationsParsed[loghandler.DestinationSyslog] = struct{}{}
default: default:
return nil, fmt.Errorf("unsupported log destination: %s", dest) return nil, fmt.Errorf("unsupported log destination: %s", dest)

10
externalcmd.go → externalcmd/externalcmd.go

@ -1,4 +1,4 @@
package main package externalcmd
import ( import (
"os" "os"
@ -7,11 +7,11 @@ import (
"strings" "strings"
) )
type externalCmd struct { type ExternalCmd struct {
cmd *exec.Cmd cmd *exec.Cmd
} }
func startExternalCommand(cmdstr string, pathName string) (*externalCmd, error) { func New(cmdstr string, pathName string) (*ExternalCmd, error) {
var cmd *exec.Cmd var cmd *exec.Cmd
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
// on Windows the shell is not used and command is started directly // 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 nil, err
} }
return &externalCmd{ return &ExternalCmd{
cmd: cmd, cmd: cmd,
}, nil }, nil
} }
func (e *externalCmd) close() { func (e *ExternalCmd) Close() {
// on Windows it's not possible to send os.Interrupt to a process // on Windows it's not possible to send os.Interrupt to a process
// Kill() is the only supported way // Kill() is the only supported way
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {

74
log.go

@ -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
}

77
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
}

30
logsyslog_unix.go

@ -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)
}

21
logsyslog_win.go

@ -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
}

8
main.go

@ -11,6 +11,8 @@ import (
"github.com/aler9/gortsplib" "github.com/aler9/gortsplib"
"gopkg.in/alecthomas/kingpin.v2" "gopkg.in/alecthomas/kingpin.v2"
"github.com/aler9/rtsp-simple-server/loghandler"
) )
var Version = "v0.0.0" var Version = "v0.0.0"
@ -21,7 +23,7 @@ const (
type program struct { type program struct {
conf *conf conf *conf
logHandler *logHandler logHandler *loghandler.LogHandler
metrics *metrics metrics *metrics
pprof *pprof pprof *pprof
paths map[string]*path paths map[string]*path
@ -75,7 +77,7 @@ func newProgram(args []string, stdin io.Reader) (*program, error) {
return nil, err return nil, err
} }
logHandler, err := newLogHandler(conf.logDestinationsParsed, conf.LogFile) logHandler, err := loghandler.New(conf.logDestinationsParsed, conf.LogFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -376,7 +378,7 @@ outer:
p.pprof.close() p.pprof.close()
} }
p.logHandler.close() p.logHandler.Close()
close(p.clientNew) close(p.clientNew)
close(p.clientClose) close(p.clientClose)

16
path.go

@ -5,6 +5,8 @@ import (
"strings" "strings"
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/aler9/rtsp-simple-server/externalcmd"
) )
const ( const (
@ -28,8 +30,8 @@ type path struct {
sourceSdp []byte sourceSdp []byte
lastDescribeReq time.Time lastDescribeReq time.Time
lastDescribeActivation time.Time lastDescribeActivation time.Time
onInitCmd *externalCmd onInitCmd *externalcmd.ExternalCmd
onDemandCmd *externalCmd onDemandCmd *externalcmd.ExternalCmd
} }
func newPath(p *program, name string, conf *pathConf) *path { func newPath(p *program, name string, conf *pathConf) *path {
@ -67,7 +69,7 @@ func (pa *path) onInit() {
pa.log("starting on init command") pa.log("starting on init command")
var err error 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 { if err != nil {
pa.log("ERR: %s", err) pa.log("ERR: %s", err)
} }
@ -86,12 +88,12 @@ func (pa *path) onClose(wait bool) {
if pa.onInitCmd != nil { if pa.onInitCmd != nil {
pa.log("stopping on init command (closing)") pa.log("stopping on init command (closing)")
pa.onInitCmd.close() pa.onInitCmd.Close()
} }
if pa.onDemandCmd != nil { if pa.onDemandCmd != nil {
pa.log("stopping on demand command (closing)") pa.log("stopping on demand command (closing)")
pa.onDemandCmd.close() pa.onDemandCmd.Close()
} }
for c := range pa.p.clients { for c := range pa.p.clients {
@ -182,7 +184,7 @@ func (pa *path) onCheck() {
!pa.hasClientReaders() && !pa.hasClientReaders() &&
time.Since(pa.lastDescribeReq) >= onDemandCmdStopAfterDescribePeriod { time.Since(pa.lastDescribeReq) >= onDemandCmdStopAfterDescribePeriod {
pa.log("stopping on demand command (not requested anymore)") pa.log("stopping on demand command (not requested anymore)")
pa.onDemandCmd.close() pa.onDemandCmd.Close()
pa.onDemandCmd = nil pa.onDemandCmd = nil
} }
@ -247,7 +249,7 @@ func (pa *path) onDescribe(client *client) {
pa.lastDescribeActivation = time.Now() pa.lastDescribeActivation = time.Now()
var err error 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 { if err != nil {
pa.log("ERR: %s", err) pa.log("ERR: %s", err)
} }

31
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)
}

22
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
}
Loading…
Cancel
Save