diff --git a/conf.go b/conf.go index 79bf1751..16c11591 100644 --- a/conf.go +++ b/conf.go @@ -160,6 +160,9 @@ func loadConf(fpath string, stdin io.Reader) (*conf, error) { case "file": conf.logDestinationsParsed[logDestinationFile] = struct{}{} + case "syslog": + conf.logDestinationsParsed[logDestinationSyslog] = struct{}{} + default: return nil, fmt.Errorf("unsupported log destination: %s", dest) } diff --git a/log-syslog_unix.go b/log-syslog_unix.go new file mode 100644 index 00000000..8e2c7729 --- /dev/null +++ b/log-syslog_unix.go @@ -0,0 +1,30 @@ +// +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/log-syslog_win.go b/log-syslog_win.go new file mode 100644 index 00000000..ac19aa0c --- /dev/null +++ b/log-syslog_win.go @@ -0,0 +1,21 @@ +// +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/log.go b/log.go index 34eae71d..5ae5ec15 100644 --- a/log.go +++ b/log.go @@ -10,22 +10,34 @@ type logDestination int const ( logDestinationStdout logDestination = iota logDestinationFile + logDestinationSyslog ) type logHandler struct { - logDestinationsParsed map[logDestination]struct{} - logFile *os.File + logDestinations map[logDestination]struct{} + logFile *os.File + logSyslog *logSyslog } -func newLogHandler(logDestinationsParsed map[logDestination]struct{}, logFilePath string) (*logHandler, error) { +func newLogHandler(logDestinations map[logDestination]struct{}, logFilePath string) (*logHandler, error) { lh := &logHandler{ - logDestinationsParsed: logDestinationsParsed, + logDestinations: logDestinations, } - if _, ok := logDestinationsParsed[logDestinationFile]; ok { + 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 } } @@ -35,22 +47,28 @@ func newLogHandler(logDestinationsParsed map[logDestination]struct{}, logFilePat return lh, nil } -func (lh *logHandler) close() error { +func (lh *logHandler) close() { if lh.logFile != nil { lh.logFile.Close() } - return nil + if lh.logSyslog != nil { + lh.logSyslog.close() + } } func (lh *logHandler) Write(p []byte) (int, error) { - if _, ok := lh.logDestinationsParsed[logDestinationStdout]; ok { + if _, ok := lh.logDestinations[logDestinationStdout]; ok { print(string(p)) } - if _, ok := lh.logDestinationsParsed[logDestinationFile]; ok { + 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/rtsp-simple-server.yml b/rtsp-simple-server.yml index 366637aa..1b8703f4 100644 --- a/rtsp-simple-server.yml +++ b/rtsp-simple-server.yml @@ -24,7 +24,7 @@ runOnConnect: metrics: no # enable pprof on port 9999 to monitor performances pprof: no -# destinations of log messages; available options are 'stdout' and 'file' +# destinations of log messages; available options are 'stdout', 'file' and 'syslog' logDestinations: [stdout] # if 'file' is in logDestinations, this is the file that will receive the logs logFile: rtsp-simple-server.log