diff --git a/cmd/syncthing/main.go b/cmd/syncthing/main.go index 4a98d232..fcb042a9 100644 --- a/cmd/syncthing/main.go +++ b/cmd/syncthing/main.go @@ -178,6 +178,7 @@ var ( doUpgradeCheck bool noBrowser bool generateDir string + logFile string noRestart = os.Getenv("STNORESTART") != "" guiAddress = os.Getenv("STGUIADDRESS") // legacy guiAuthentication = os.Getenv("STGUIAUTH") // legacy @@ -194,6 +195,15 @@ func main() { if err != nil { l.Fatalln("home:", err) } + + if runtime.GOOS == "windows" { + // On Windows, we use a log file by default. Setting the -logfile flag + // to the empty string disables this behavior. + + logFile = filepath.Join(defConfDir, "syncthing.log") + flag.StringVar(&logFile, "logfile", logFile, "Log file name (blank for stdout)") + } + flag.StringVar(&generateDir, "generate", "", "Generate key and config in specified dir, then exit") flag.StringVar(&guiAddress, "gui-address", guiAddress, "Override GUI address") flag.StringVar(&guiAuthentication, "gui-authentication", guiAuthentication, "Override GUI authentication; username:password") diff --git a/cmd/syncthing/monitor.go b/cmd/syncthing/monitor.go index ccc3d8eb..af64be32 100644 --- a/cmd/syncthing/monitor.go +++ b/cmd/syncthing/monitor.go @@ -44,6 +44,19 @@ func monitorMain() { os.Setenv("STMONITORED", "yes") l.SetPrefix("[monitor] ") + var err error + var dst io.Writer + + if logFile == "" { + dst = os.Stdout + } else { + dst, err = os.Create(logFile) + if err != nil { + l.Fatalln("log file:", err) + } + l.Infof(`Log output directed to file "%s"`, logFile) + } + args := os.Args var restarts [countRestarts]time.Time @@ -64,12 +77,12 @@ func monitorMain() { stderr, err := cmd.StderrPipe() if err != nil { - l.Fatalln(err) + l.Fatalln("stderr:", err) } stdout, err := cmd.StdoutPipe() if err != nil { - l.Fatalln(err) + l.Fatalln("stdout:", err) } l.Infoln("Starting syncthing") @@ -87,8 +100,8 @@ func monitorMain() { stdoutLastLines = make([]string, 0, 50) stdoutMut.Unlock() - go copyStderr(stderr) - go copyStdout(stdout) + go copyStderr(stderr, dst) + go copyStdout(stdout, dst) exit := make(chan error) @@ -130,7 +143,7 @@ func monitorMain() { } } -func copyStderr(stderr io.ReadCloser) { +func copyStderr(stderr io.ReadCloser, dst io.Writer) { br := bufio.NewReader(stderr) var panicFd *os.File @@ -141,7 +154,7 @@ func copyStderr(stderr io.ReadCloser) { } if panicFd == nil { - os.Stderr.WriteString(line) + dst.Write([]byte(line)) if strings.HasPrefix(line, "panic:") || strings.HasPrefix(line, "fatal error:") { panicFd, err = os.Create(filepath.Join(confDir, time.Now().Format("panic-20060102-150405.log"))) @@ -173,8 +186,8 @@ func copyStderr(stderr io.ReadCloser) { } } -func copyStdout(stderr io.ReadCloser) { - br := bufio.NewReader(stderr) +func copyStdout(stdout io.ReadCloser, dst io.Writer) { + br := bufio.NewReader(stdout) for { line, err := br.ReadString('\n') if err != nil { @@ -192,6 +205,6 @@ func copyStdout(stderr io.ReadCloser) { } stdoutMut.Unlock() - os.Stdout.WriteString(line) + dst.Write([]byte(line)) } }