Add --stats-log-level so can see --stats without -v - fixes #1180

The most common use for this flag is likely to be showing the stats
without using -v by using `--stats-log-level NOTICE`.
This commit is contained in:
Nick Craig-Wood 2017-06-26 22:46:45 +01:00
parent 33f302a06b
commit aa20486485
5 changed files with 54 additions and 18 deletions

View File

@ -253,7 +253,7 @@ func Run(Retry bool, showStats bool, cmd *cobra.Command, f func() error) {
log.Fatalf("Failed to %s: %v", cmd.Name(), err) log.Fatalf("Failed to %s: %v", cmd.Name(), err)
} }
if showStats && (fs.Stats.Errored() || *statsInterval > 0) { if showStats && (fs.Stats.Errored() || *statsInterval > 0) {
fs.Infof(nil, "%s", fs.Stats) fs.Stats.Log()
} }
fs.Debugf(nil, "Go routines at exit %d\n", runtime.NumGoroutine()) fs.Debugf(nil, "Go routines at exit %d\n", runtime.NumGoroutine())
if fs.Stats.Errored() { if fs.Stats.Errored() {

View File

@ -396,8 +396,8 @@ using `--checksum`).
Log all of rclone's output to FILE. This is not active by default. Log all of rclone's output to FILE. This is not active by default.
This can be useful for tracking down problems with syncs in This can be useful for tracking down problems with syncs in
combination with the `-v` flag. See the Logging section for more combination with the `-v` flag. See the [Logging section](#logging)
info. for more info.
### --log-level LEVEL ### ### --log-level LEVEL ###
@ -514,10 +514,23 @@ This sets the interval.
The default is `1m`. Use 0 to disable. The default is `1m`. Use 0 to disable.
If you set the stats interval then all command can show stats. This If you set the stats interval then all commands can show stats. This
can be useful when running other commands, `check` or `mount` for can be useful when running other commands, `check` or `mount` for
example. example.
Stats are logged at `INFO` level by default which means they won't
show at default log level `NOTICE`. Use `--stats-log-level NOTICE` or
`-v` to make them show. See the [Logging section](#logging) for more
info on log levels.
### --stats-log-level string ###
Log level to show `--stats` output at. This can be `DEBUG`, `INFO`,
`NOTICE`, or `ERROR`. The default is `INFO`. This means at the
default level of logging which is `NOTICE` the stats won't show - if
you want them to then use `-stats-log-level NOTICE`. See the [Logging
section](#logging) for more info on log levels.
### --stats-unit=bits|bytes ### ### --stats-unit=bits|bytes ###
By default, data transfer rates will be printed in bytes/second. By default, data transfer rates will be printed in bytes/second.

View File

@ -203,7 +203,7 @@ Elapsed time: %10v
// Log outputs the StatsInfo to the log // Log outputs the StatsInfo to the log
func (s *StatsInfo) Log() { func (s *StatsInfo) Log() {
Infof(nil, "%v\n", s) LogLevelPrintf(Config.StatsLogLevel, nil, "%v\n", s)
} }
// Bytes updates the stats for bytes bytes // Bytes updates the stats for bytes bytes

View File

@ -65,7 +65,6 @@ var (
// Flags // Flags
verbose = CountP("verbose", "v", "Print lots more stuff (repeat for more)") verbose = CountP("verbose", "v", "Print lots more stuff (repeat for more)")
quiet = BoolP("quiet", "q", false, "Print as little stuff as possible") quiet = BoolP("quiet", "q", false, "Print as little stuff as possible")
logLevel = StringP("log-level", "", "INFO", "Log level DEBUG|INFO|NOTICE|ERROR")
modifyWindow = DurationP("modify-window", "", time.Nanosecond, "Max time diff to be considered the same") modifyWindow = DurationP("modify-window", "", time.Nanosecond, "Max time diff to be considered the same")
checkers = IntP("checkers", "", 8, "Number of checkers to run in parallel.") checkers = IntP("checkers", "", 8, "Number of checkers to run in parallel.")
transfers = IntP("transfers", "", 4, "Number of file transfers to run in parallel.") transfers = IntP("transfers", "", 4, "Number of file transfers to run in parallel.")
@ -97,6 +96,8 @@ var (
backupDir = StringP("backup-dir", "", "", "Make backups into hierarchy based in DIR.") backupDir = StringP("backup-dir", "", "", "Make backups into hierarchy based in DIR.")
suffix = StringP("suffix", "", "", "Suffix for use with --backup-dir.") suffix = StringP("suffix", "", "", "Suffix for use with --backup-dir.")
useListR = BoolP("fast-list", "", false, "Use recursive list if available. Uses more memory but fewer transactions.") useListR = BoolP("fast-list", "", false, "Use recursive list if available. Uses more memory but fewer transactions.")
logLevel = LogLevelNotice
statsLogLevel = LogLevelInfo
bwLimit BwTimetable bwLimit BwTimetable
bufferSize SizeSuffix = 16 << 20 bufferSize SizeSuffix = 16 << 20
@ -106,6 +107,8 @@ var (
) )
func init() { func init() {
VarP(&logLevel, "log-level", "", "Log level DEBUG|INFO|NOTICE|ERROR")
VarP(&statsLogLevel, "stats-log-level", "", "Log level to show --stats output DEBUG|INFO|NOTICE|ERROR")
VarP(&bwLimit, "bwlimit", "", "Bandwidth limit in kBytes/s, or use suffix b|k|M|G or a full timetable.") VarP(&bwLimit, "bwlimit", "", "Bandwidth limit in kBytes/s, or use suffix b|k|M|G or a full timetable.")
VarP(&bufferSize, "buffer-size", "", "Buffer size when copying files.") VarP(&bufferSize, "buffer-size", "", "Buffer size when copying files.")
} }
@ -194,6 +197,7 @@ func MustReveal(x string) string {
// ConfigInfo is filesystem config options // ConfigInfo is filesystem config options
type ConfigInfo struct { type ConfigInfo struct {
LogLevel LogLevel LogLevel LogLevel
StatsLogLevel LogLevel
DryRun bool DryRun bool
CheckSum bool CheckSum bool
SizeOnly bool SizeOnly bool
@ -332,19 +336,9 @@ func LoadConfig() {
if *quiet { if *quiet {
log.Fatalf("Can't set -q and --log-level") log.Fatalf("Can't set -q and --log-level")
} }
switch strings.ToUpper(*logLevel) { Config.LogLevel = logLevel
case "ERROR":
Config.LogLevel = LogLevelError
case "NOTICE":
Config.LogLevel = LogLevelNotice
case "INFO":
Config.LogLevel = LogLevelInfo
case "DEBUG":
Config.LogLevel = LogLevelDebug
default:
log.Fatalf("Unknown --log-level %q", *logLevel)
}
} }
Config.StatsLogLevel = statsLogLevel
Config.ModifyWindow = *modifyWindow Config.ModifyWindow = *modifyWindow
Config.Checkers = *checkers Config.Checkers = *checkers
Config.Transfers = *transfers Config.Transfers = *transfers

View File

@ -9,6 +9,9 @@ import (
"reflect" "reflect"
"runtime" "runtime"
"strings" "strings"
"github.com/pkg/errors"
"github.com/spf13/pflag"
) )
// LogLevel describes rclone's logs. These are a subset of the syslog log levels. // LogLevel describes rclone's logs. These are a subset of the syslog log levels.
@ -55,6 +58,25 @@ func (l LogLevel) String() string {
return logLevelToString[l] return logLevelToString[l]
} }
// Set a LogLevel
func (l *LogLevel) Set(s string) error {
for n, name := range logLevelToString {
if s != "" && name == s {
*l = LogLevel(n)
return nil
}
}
return errors.Errorf("Unknown log level %q", s)
}
// Type of the value
func (l *LogLevel) Type() string {
return "string"
}
// Check it satisfies the interface
var _ pflag.Value = (*LogLevel)(nil)
// Flags // Flags
var ( var (
logFile = StringP("log-file", "", "", "Log everything to this file") logFile = StringP("log-file", "", "", "Log everything to this file")
@ -77,6 +99,13 @@ func logPrintf(level LogLevel, o interface{}, text string, args ...interface{})
logPrint(level, out) logPrint(level, out)
} }
// LogLevelPrintf writes logs at the given level
func LogLevelPrintf(level LogLevel, o interface{}, text string, args ...interface{}) {
if Config.LogLevel >= level {
logPrintf(level, o, text, args...)
}
}
// Errorf writes error log output for this Object or Fs. It // Errorf writes error log output for this Object or Fs. It
// should always be seen by the user. // should always be seen by the user.
func Errorf(o interface{}, text string, args ...interface{}) { func Errorf(o interface{}, text string, args ...interface{}) {