mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 08:23:47 +01:00
Redo log level flags
* -vv or --log-level DEBUG * -v or --log-level INFO * --log-level NOTICE (default) * -q --log-level ERROR Replace Config.Verbose and Config.Quiet with Config.LogLevel Fixes #739 Fixes #1108 Fixes #1000
This commit is contained in:
parent
0366ea39c5
commit
ac1c041377
@ -274,12 +274,10 @@ func Run(Retry bool, showStats bool, cmd *cobra.Command, f func() error) {
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to %s: %v", cmd.Name(), err)
|
||||
}
|
||||
if showStats && (!fs.Config.Quiet || fs.Stats.Errored() || *statsInterval > 0) {
|
||||
if showStats && (fs.Stats.Errored() || *statsInterval > 0) {
|
||||
fs.Infof(nil, "%s", fs.Stats)
|
||||
}
|
||||
if fs.Config.Verbose {
|
||||
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() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
@ -71,8 +71,9 @@ func newRun() *Run {
|
||||
// "RCLONE_CONFIG_PASS=hunter2" (or your password)
|
||||
*fs.AskPassword = false
|
||||
fs.LoadConfig()
|
||||
fs.Config.Verbose = *Verbose
|
||||
fs.Config.Quiet = !*Verbose
|
||||
if *Verbose {
|
||||
fs.Config.LogLevel = fs.LogLevelDebug
|
||||
}
|
||||
fs.Config.DumpHeaders = *DumpHeaders
|
||||
fs.Config.DumpBodies = *DumpBodies
|
||||
fs.Config.LowLevelRetries = *LowLevelRetries
|
||||
|
@ -362,6 +362,22 @@ This can be useful for tracking down problems with syncs in
|
||||
combination with the `-v` flag. See the Logging section for more
|
||||
info.
|
||||
|
||||
### --log-level LEVEL ###
|
||||
|
||||
This sets the log level for rclone. The default log level is `INFO`.
|
||||
|
||||
`DEBUG` is equivalent to `-vv`. It outputs lots of debug info - useful
|
||||
for bug reports and really finding out what rclone is doing.
|
||||
|
||||
`INFO` is equivalent to `-v`. It outputs information about each transfer
|
||||
and prints stats once a minute by default.
|
||||
|
||||
`NOTICE` is the default log level if no logging flags are supplied. It
|
||||
outputs very little when things are working normally. It outputs
|
||||
warnings and significant events.
|
||||
|
||||
`ERROR` is equivalent to `-q`. It only output error messages.
|
||||
|
||||
### --low-level-retries NUMBER ###
|
||||
|
||||
This controls the number of low level retries rclone does.
|
||||
@ -568,12 +584,14 @@ This can be useful when transferring to a remote which doesn't support
|
||||
mod times directly as it is more accurate than a `--size-only` check
|
||||
and faster than using `--checksum`.
|
||||
|
||||
### -v, --verbose ###
|
||||
### -v, -vv, --verbose ###
|
||||
|
||||
If you set this flag, rclone will become very verbose telling you
|
||||
about every file it considers and transfers.
|
||||
With `-v` rclone will tell you about each file that is transferred and
|
||||
a small number of significant events.
|
||||
|
||||
Very useful for debugging.
|
||||
With `-vv` rclone will become very verbose telling you about every
|
||||
file it considers and transfers. Please send bug reports with a log
|
||||
with this setting.
|
||||
|
||||
### -V, --version ###
|
||||
|
||||
@ -762,22 +780,34 @@ See the [filtering section](/filtering/).
|
||||
Logging
|
||||
-------
|
||||
|
||||
rclone has 3 levels of logging, `Error`, `Info` and `Debug`.
|
||||
rclone has 4 levels of logging, `Error`, `Notice`, `Info` and `Debug`.
|
||||
|
||||
By default rclone logs `Error` and `Info` to standard error and `Debug`
|
||||
to standard output. This means you can redirect standard output and
|
||||
standard error to different places.
|
||||
By default rclone logs to standard error. This means you can redirect
|
||||
standard error and still see the normal output of rclone commands (eg
|
||||
`rclone ls`).
|
||||
|
||||
By default rclone will produce `Error` and `Info` level messages.
|
||||
By default rclone will produce `Error` and `Notice` level messages.
|
||||
|
||||
If you use the `-q` flag, rclone will only produce `Error` messages.
|
||||
|
||||
If you use the `-v` flag, rclone will produce `Error`, `Info` and
|
||||
`Debug` messages.
|
||||
If you use the `-v` flag, rclone will produce `Error`, `Notice` and
|
||||
`Info` messages.
|
||||
|
||||
If you use the `-vv` flag, rclone will produce `Error`, `Notice`,
|
||||
`Info` and `Debug` messages.
|
||||
|
||||
You can also control the log levels with the `--log-level` flag.
|
||||
|
||||
If you use the `--log-file=FILE` option, rclone will redirect `Error`,
|
||||
`Info` and `Debug` messages along with standard error to FILE.
|
||||
|
||||
If you use the `--syslog` flag then rclone will log to syslog and the
|
||||
`--syslog-facility` control which facility it uses.
|
||||
|
||||
Rclone prefixes all log messages with their level in capitals, eg INFO
|
||||
which makes it easy to grep the log file for different kinds of
|
||||
information.
|
||||
|
||||
Exit Code
|
||||
---------
|
||||
|
||||
|
42
fs/config.go
42
fs/config.go
@ -26,6 +26,7 @@ import (
|
||||
|
||||
"github.com/Unknwon/goconfig"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/pflag"
|
||||
"golang.org/x/crypto/nacl/secretbox"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
@ -56,8 +57,9 @@ var (
|
||||
// Config is the global config
|
||||
Config = &ConfigInfo{}
|
||||
// Flags
|
||||
verbose = BoolP("verbose", "v", false, "Print lots more stuff")
|
||||
verbose = CountP("verbose", "v", "Print lots more stuff (repeat for more)")
|
||||
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")
|
||||
checkers = IntP("checkers", "", 8, "Number of checkers to run in parallel.")
|
||||
transfers = IntP("transfers", "", 4, "Number of file transfers to run in parallel.")
|
||||
@ -182,8 +184,7 @@ func MustReveal(x string) string {
|
||||
|
||||
// ConfigInfo is filesystem config options
|
||||
type ConfigInfo struct {
|
||||
Verbose bool
|
||||
Quiet bool
|
||||
LogLevel LogLevel
|
||||
DryRun bool
|
||||
CheckSum bool
|
||||
SizeOnly bool
|
||||
@ -300,8 +301,39 @@ func LoadConfig() {
|
||||
// Read some flags if set
|
||||
//
|
||||
// FIXME read these from the config file too
|
||||
Config.Verbose = *verbose
|
||||
Config.Quiet = *quiet
|
||||
Config.LogLevel = LogLevelNotice
|
||||
if *verbose >= 2 {
|
||||
Config.LogLevel = LogLevelDebug
|
||||
} else if *verbose >= 1 {
|
||||
Config.LogLevel = LogLevelInfo
|
||||
}
|
||||
if *quiet {
|
||||
if *verbose > 0 {
|
||||
log.Fatalf("Can't set -v and -q")
|
||||
}
|
||||
Config.LogLevel = LogLevelError
|
||||
}
|
||||
logLevelFlag := pflag.Lookup("log-level")
|
||||
if logLevelFlag != nil && logLevelFlag.Changed {
|
||||
if *verbose > 0 {
|
||||
log.Fatalf("Can't set -v and --log-level")
|
||||
}
|
||||
if *quiet {
|
||||
log.Fatalf("Can't set -q and --log-level")
|
||||
}
|
||||
switch strings.ToUpper(*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.ModifyWindow = *modifyWindow
|
||||
Config.Checkers = *checkers
|
||||
Config.Transfers = *transfers
|
||||
|
@ -313,3 +313,12 @@ func StringArrayP(name, shorthand string, value []string, usage string) (out *[]
|
||||
setDefaultFromEnv(name)
|
||||
return out
|
||||
}
|
||||
|
||||
// CountP defines a flag which can be overridden by an environment variable
|
||||
//
|
||||
// It is a thin wrapper around pflag.CountP
|
||||
func CountP(name, shorthand string, usage string) (out *int) {
|
||||
out = pflag.CountP(name, shorthand, usage)
|
||||
setDefaultFromEnv(name)
|
||||
return out
|
||||
}
|
||||
|
37
fs/log.go
37
fs/log.go
@ -11,9 +11,11 @@ import (
|
||||
// LogLevel describes rclone's logs. These are a subset of the syslog log levels.
|
||||
type LogLevel byte
|
||||
|
||||
//go:generate stringer -type=LogLevel
|
||||
|
||||
// Log levels - a subset of the syslog logs
|
||||
const (
|
||||
LogLevelEmergency = iota
|
||||
LogLevelEmergency LogLevel = iota
|
||||
LogLevelAlert
|
||||
LogLevelCritical
|
||||
LogLevelError // Error - can't be suppressed
|
||||
@ -38,30 +40,37 @@ func makeLog(o interface{}, text string, args ...interface{}) string {
|
||||
}
|
||||
|
||||
// Errorf writes error log output for this Object or Fs. It
|
||||
// unconditionally logs a message regardless of Config.Quiet or
|
||||
// Config.Verbose.
|
||||
// unconditionally logs a message regardless of Config.LogLevel
|
||||
func Errorf(o interface{}, text string, args ...interface{}) {
|
||||
log.Print(makeLog(o, text, args...))
|
||||
}
|
||||
|
||||
// Logf writes log output for this Object or Fs. This should be
|
||||
// considered to be Info level logging.
|
||||
func Logf(o interface{}, text string, args ...interface{}) {
|
||||
if !Config.Quiet {
|
||||
if Config.LogLevel >= LogLevelError {
|
||||
log.Print(makeLog(o, text, args...))
|
||||
}
|
||||
}
|
||||
|
||||
// Infof writes info on transfers for this Object or Fs
|
||||
// Logf writes log output for this Object or Fs. This should be
|
||||
// considered to be Info level logging. It is the default level. By
|
||||
// default rclone should not log very much so only use this for
|
||||
// important things the user should see. The user can filter these
|
||||
// out with the -q flag.
|
||||
func Logf(o interface{}, text string, args ...interface{}) {
|
||||
if Config.LogLevel >= LogLevelNotice {
|
||||
log.Print(makeLog(o, text, args...))
|
||||
}
|
||||
}
|
||||
|
||||
// Infof writes info on transfers for this Object or Fs. Use this
|
||||
// level for logging transfers, deletions and things which should
|
||||
// appear with the -v flag.
|
||||
func Infof(o interface{}, text string, args ...interface{}) {
|
||||
if Config.Verbose {
|
||||
if Config.LogLevel >= LogLevelInfo {
|
||||
DebugLogger.Print(makeLog(o, text, args...))
|
||||
}
|
||||
}
|
||||
|
||||
// Debugf writes debugging output for this Object or Fs
|
||||
// Debugf writes debugging output for this Object or Fs. Use this for
|
||||
// debug only. The user must have to specify -vv to see this.
|
||||
func Debugf(o interface{}, text string, args ...interface{}) {
|
||||
if Config.Verbose {
|
||||
if Config.LogLevel >= LogLevelDebug {
|
||||
DebugLogger.Print(makeLog(o, text, args...))
|
||||
}
|
||||
}
|
||||
|
16
fs/loglevel_string.go
Normal file
16
fs/loglevel_string.go
Normal file
@ -0,0 +1,16 @@
|
||||
// Code generated by "stringer -type=LogLevel"; DO NOT EDIT
|
||||
|
||||
package fs
|
||||
|
||||
import "fmt"
|
||||
|
||||
const _LogLevel_name = "LogLevelEmergencyLogLevelAlertLogLevelCriticalLogLevelErrorLogLevelWarningLogLevelNoticeLogLevelInfoLogLevelDebug"
|
||||
|
||||
var _LogLevel_index = [...]uint8{0, 17, 30, 46, 59, 74, 88, 100, 113}
|
||||
|
||||
func (i LogLevel) String() string {
|
||||
if i >= LogLevel(len(_LogLevel_index)-1) {
|
||||
return fmt.Sprintf("LogLevel(%d)", i)
|
||||
}
|
||||
return _LogLevel_name[_LogLevel_index[i]:_LogLevel_index[i+1]]
|
||||
}
|
@ -105,8 +105,9 @@ func newRun() *Run {
|
||||
// "RCLONE_CONFIG_PASS=hunter2" (or your password)
|
||||
*fs.AskPassword = false
|
||||
fs.LoadConfig()
|
||||
fs.Config.Verbose = *Verbose
|
||||
fs.Config.Quiet = !*Verbose
|
||||
if *Verbose {
|
||||
fs.Config.LogLevel = fs.LogLevelDebug
|
||||
}
|
||||
fs.Config.DumpHeaders = *DumpHeaders
|
||||
fs.Config.DumpBodies = *DumpBodies
|
||||
fs.Config.LowLevelRetries = *LowLevelRetries
|
||||
|
@ -73,8 +73,9 @@ func TestInit(t *testing.T) {
|
||||
for _, item := range ExtraConfig {
|
||||
fs.ConfigFileSet(item.Name, item.Key, item.Value)
|
||||
}
|
||||
fs.Config.Verbose = *verbose
|
||||
fs.Config.Quiet = !*verbose
|
||||
if *verbose {
|
||||
fs.Config.LogLevel = fs.LogLevelDebug
|
||||
}
|
||||
fs.Config.DumpHeaders = *dumpHeaders
|
||||
fs.Config.DumpBodies = *dumpBodies
|
||||
t.Logf("Using remote %q", RemoteName)
|
||||
|
Loading…
Reference in New Issue
Block a user