2017-02-09 19:01:20 +08:00
|
|
|
// Logging for rclone
|
|
|
|
|
|
|
|
package fs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
// LogLevel describes rclone's logs. These are a subset of the syslog log levels.
|
|
|
|
type LogLevel byte
|
|
|
|
|
2017-02-10 21:28:06 +08:00
|
|
|
// Log levels. These are the syslog levels of which we only use a
|
|
|
|
// subset.
|
|
|
|
//
|
|
|
|
// LOG_EMERG system is unusable
|
|
|
|
// LOG_ALERT action must be taken immediately
|
|
|
|
// LOG_CRIT critical conditions
|
|
|
|
// LOG_ERR error conditions
|
|
|
|
// LOG_WARNING warning conditions
|
|
|
|
// LOG_NOTICE normal, but significant, condition
|
|
|
|
// LOG_INFO informational message
|
|
|
|
// LOG_DEBUG debug-level message
|
2017-02-09 19:01:20 +08:00
|
|
|
const (
|
2017-02-10 05:22:46 +08:00
|
|
|
LogLevelEmergency LogLevel = iota
|
2017-02-09 19:01:20 +08:00
|
|
|
LogLevelAlert
|
|
|
|
LogLevelCritical
|
|
|
|
LogLevelError // Error - can't be suppressed
|
|
|
|
LogLevelWarning
|
|
|
|
LogLevelNotice // Normal logging, -q suppresses
|
|
|
|
LogLevelInfo // Transfers, needs -v
|
|
|
|
LogLevelDebug // Debug level, needs -vv
|
|
|
|
)
|
|
|
|
|
2017-02-10 21:28:06 +08:00
|
|
|
var logLevelToString = []string{
|
|
|
|
LogLevelEmergency: "EMERGENCY",
|
|
|
|
LogLevelAlert: "ALERT",
|
|
|
|
LogLevelCritical: "CRITICAL",
|
|
|
|
LogLevelError: "ERROR",
|
|
|
|
LogLevelWarning: "WARNING",
|
|
|
|
LogLevelNotice: "NOTICE",
|
|
|
|
LogLevelInfo: "INFO",
|
|
|
|
LogLevelDebug: "DEBUG",
|
|
|
|
}
|
2017-02-09 19:01:20 +08:00
|
|
|
|
2017-02-10 21:28:06 +08:00
|
|
|
// String turns a LogLevel into a string
|
|
|
|
func (l LogLevel) String() string {
|
|
|
|
if l >= LogLevel(len(logLevelToString)) {
|
|
|
|
return fmt.Sprintf("LogLevel(%d)", l)
|
|
|
|
}
|
|
|
|
return logLevelToString[l]
|
|
|
|
}
|
2017-02-09 19:01:20 +08:00
|
|
|
|
2017-02-10 21:28:06 +08:00
|
|
|
// Flags
|
|
|
|
var (
|
|
|
|
logFile = StringP("log-file", "", "", "Log everything to this file")
|
|
|
|
useSyslog = BoolP("syslog", "", false, "Use Syslog for logging")
|
|
|
|
syslogFacility = StringP("syslog-facility", "", "DAEMON", "Facility for syslog, eg KERN,USER,...")
|
|
|
|
)
|
|
|
|
|
|
|
|
// logPrint sends the text to the logger of level
|
|
|
|
var logPrint = func(level LogLevel, text string) {
|
|
|
|
text = fmt.Sprintf("%-6s: %s", level, text)
|
|
|
|
log.Print(text)
|
|
|
|
}
|
|
|
|
|
|
|
|
// logPrintf produces a log string from the arguments passed in
|
|
|
|
func logPrintf(level LogLevel, o interface{}, text string, args ...interface{}) {
|
2017-02-09 19:01:20 +08:00
|
|
|
out := fmt.Sprintf(text, args...)
|
2017-02-10 21:28:06 +08:00
|
|
|
if o != nil {
|
|
|
|
out = fmt.Sprintf("%v: %s", o, out)
|
2017-02-09 19:01:20 +08:00
|
|
|
}
|
2017-02-10 21:28:06 +08:00
|
|
|
logPrint(level, out)
|
2017-02-09 19:01:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Errorf writes error log output for this Object or Fs. It
|
2017-02-10 21:28:06 +08:00
|
|
|
// should always be seen by the user.
|
2017-02-09 19:01:20 +08:00
|
|
|
func Errorf(o interface{}, text string, args ...interface{}) {
|
2017-02-10 05:22:46 +08:00
|
|
|
if Config.LogLevel >= LogLevelError {
|
2017-02-10 21:28:06 +08:00
|
|
|
logPrintf(LogLevelError, o, text, args...)
|
2017-02-10 05:22:46 +08:00
|
|
|
}
|
2017-02-09 19:01:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Logf writes log output for this Object or Fs. This should be
|
2017-02-10 05:22:46 +08:00
|
|
|
// 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.
|
2017-02-09 19:01:20 +08:00
|
|
|
func Logf(o interface{}, text string, args ...interface{}) {
|
2017-02-10 05:22:46 +08:00
|
|
|
if Config.LogLevel >= LogLevelNotice {
|
2017-02-10 21:28:06 +08:00
|
|
|
logPrintf(LogLevelNotice, o, text, args...)
|
2017-02-09 19:01:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-10 05:22:46 +08:00
|
|
|
// 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.
|
2017-02-09 19:01:20 +08:00
|
|
|
func Infof(o interface{}, text string, args ...interface{}) {
|
2017-02-10 05:22:46 +08:00
|
|
|
if Config.LogLevel >= LogLevelInfo {
|
2017-02-10 21:28:06 +08:00
|
|
|
logPrintf(LogLevelInfo, o, text, args...)
|
2017-02-09 19:01:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-10 05:22:46 +08:00
|
|
|
// Debugf writes debugging output for this Object or Fs. Use this for
|
|
|
|
// debug only. The user must have to specify -vv to see this.
|
2017-02-09 19:01:20 +08:00
|
|
|
func Debugf(o interface{}, text string, args ...interface{}) {
|
2017-02-10 05:22:46 +08:00
|
|
|
if Config.LogLevel >= LogLevelDebug {
|
2017-02-10 21:28:06 +08:00
|
|
|
logPrintf(LogLevelDebug, o, text, args...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// InitLogging start the logging as per the command line flags
|
|
|
|
func InitLogging() {
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
_, err = f.Seek(0, os.SEEK_END)
|
|
|
|
if err != nil {
|
|
|
|
Errorf(nil, "Failed to seek log file to end: %v", err)
|
|
|
|
}
|
|
|
|
log.SetOutput(f)
|
|
|
|
redirectStderr(f)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Syslog output
|
|
|
|
if *useSyslog {
|
|
|
|
if *logFile != "" {
|
|
|
|
log.Fatalf("Can't use --syslog and --log-file together")
|
|
|
|
}
|
|
|
|
startSysLog()
|
2017-02-09 19:01:20 +08:00
|
|
|
}
|
|
|
|
}
|