From 24a6ff54c2ea3ac9cd4a23593eef71507764a3b8 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 27 Feb 2015 16:51:17 +0000 Subject: [PATCH] Add --log-file flag to log everything (including panics) to file --- README.md | 6 ++++-- docs/content/docs.md | 8 +++++--- rclone.go | 12 ++++++++++++ redirect_stderr.go | 15 +++++++++++++++ redirect_stderr_unix.go | 19 +++++++++++++++++++ redirect_stderr_windows.go | 39 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 redirect_stderr.go create mode 100644 redirect_stderr_unix.go create mode 100644 redirect_stderr_windows.go diff --git a/README.md b/README.md index 0e20c2867..dc8c3756d 100644 --- a/README.md +++ b/README.md @@ -125,15 +125,17 @@ the same format as the standard md5sum tool produces. General options: ``` - --bwlimit=0: Bandwidth limit in kBytes/s, or use suffix k|M|G + --bwlimit=0: Bandwidth limit in kBytes/s, or use suffix K|M|G --checkers=8: Number of checkers to run in parallel. --config="~/.rclone.conf": Config file. -n, --dry-run=false: Do a trial run with no permanent changes + --log-file="": Log everything to this file --modify-window=1ns: Max time diff to be considered the same -q, --quiet=false: Print as little stuff as possible - --stats=1m0s: Interval to print stats + --stats=1m0s: Interval to print stats (0 to disable) --transfers=4: Number of file transfers to run in parallel. -v, --verbose=false: Print lots more stuff + -V, --version=false: Print the version number ``` Developer options: diff --git a/docs/content/docs.md b/docs/content/docs.md index 0e0600935..a47e6dd97 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -107,15 +107,17 @@ the same format as the standard md5sum tool produces. General options: ``` - --bwlimit=0: Bandwidth limit in kBytes/s, or use suffix k|M|G + --bwlimit=0: Bandwidth limit in kBytes/s, or use suffix K|M|G --checkers=8: Number of checkers to run in parallel. - --transfers=4: Number of file transfers to run in parallel. --config="~/.rclone.conf": Config file. -n, --dry-run=false: Do a trial run with no permanent changes + --log-file="": Log everything to this file --modify-window=1ns: Max time diff to be considered the same -q, --quiet=false: Print as little stuff as possible - --stats=1m0s: Interval to print stats + --stats=1m0s: Interval to print stats (0 to disable) + --transfers=4: Number of file transfers to run in parallel. -v, --verbose=false: Print lots more stuff + -V, --version=false: Print the version number ``` Developer options: diff --git a/rclone.go b/rclone.go index 1ae464e43..4945fb393 100644 --- a/rclone.go +++ b/rclone.go @@ -30,6 +30,7 @@ var ( cpuprofile = pflag.StringP("cpuprofile", "", "", "Write cpu profile to file") statsInterval = pflag.DurationP("stats", "", time.Minute*1, "Interval to print stats (0 to disable)") version = pflag.BoolP("version", "V", false, "Print the version number") + logFile = pflag.StringP("log-file", "", "", "Log everything to this file") ) type Command struct { @@ -343,6 +344,17 @@ func main() { } command, args := ParseCommand() + // Log file output + if *logFile != "" { + f, err := os.OpenFile(*logFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0640) + if err != nil { + log.Fatalf("Failed to open log file: %v", err) + } + f.Seek(0, os.SEEK_END) + log.SetOutput(f) + redirectStderr(f) + } + // Make source and destination fs var fdst, fsrc fs.Fs if len(args) >= 1 { diff --git a/redirect_stderr.go b/redirect_stderr.go new file mode 100644 index 000000000..eab4b39ca --- /dev/null +++ b/redirect_stderr.go @@ -0,0 +1,15 @@ +// Log the panic to the log file - for oses which can't do this + +//+build !windows,!unix + +package main + +import ( + "log" + "os" +) + +// redirectStderr to the file passed in +func redirectStderr(f *os.File) { + log.Printf("Can't redirect stderr to file") +} diff --git a/redirect_stderr_unix.go b/redirect_stderr_unix.go new file mode 100644 index 000000000..5827f2b5f --- /dev/null +++ b/redirect_stderr_unix.go @@ -0,0 +1,19 @@ +// Log the panic under unix to the log file + +//+build unix + +package main + +import ( + "log" + "os" + "syscall" +) + +// redirectStderr to the file passed in +func redirectStderr(f *os.File) { + err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd())) + if err != nil { + log.Fatalf("Failed to redirect stderr to file: %v", err) + } +} diff --git a/redirect_stderr_windows.go b/redirect_stderr_windows.go new file mode 100644 index 000000000..6b03ba00d --- /dev/null +++ b/redirect_stderr_windows.go @@ -0,0 +1,39 @@ +// Log the panic under windows to the log file +// +// Code from minix, via +// +// http://play.golang.org/p/kLtct7lSUg + +//+build windows + +package main + +import ( + "log" + "os" + "syscall" +) + +var ( + kernel32 = syscall.MustLoadDLL("kernel32.dll") + procSetStdHandle = kernel32.MustFindProc("SetStdHandle") +) + +func setStdHandle(stdhandle int32, handle syscall.Handle) error { + r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0) + if r0 == 0 { + if e1 != 0 { + return error(e1) + } + return syscall.EINVAL + } + return nil +} + +// redirectStderr to the file passed in +func redirectStderr(f *os.File) { + err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd())) + if err != nil { + log.Fatalf("Failed to redirect stderr to file: %v", err) + } +}