diff options
author | n-peugnet <n.peugnet@free.fr> | 2021-09-14 12:35:03 +0200 |
---|---|---|
committer | n-peugnet <n.peugnet@free.fr> | 2021-09-14 12:35:03 +0200 |
commit | d85847ec99d44e1010a95c71579a754ac9f7c646 (patch) | |
tree | 44553dd7f7a2a25fc5eb209b9258661e24f22ae5 | |
parent | 33ce234dc7f325caa282c19c3e63a510d7778373 (diff) | |
download | dna-backup-d85847ec99d44e1010a95c71579a754ac9f7c646.tar.gz dna-backup-d85847ec99d44e1010a95c71579a754ac9f7c646.zip |
add basic logger
-rw-r--r-- | TODO.md | 1 | ||||
-rw-r--r-- | logger/logger.go | 290 | ||||
-rw-r--r-- | main.go | 30 |
3 files changed, 316 insertions, 5 deletions
@@ -32,6 +32,7 @@ priority 2 - [ ] maybe use an LRU cache instead of the current FIFO one. - [x] remove `LoadedChunk` and only use `StoredChunk` instead now that the cache is implemented +- [ ] store file list compressed reunion 7/09 ------------ diff --git a/logger/logger.go b/logger/logger.go new file mode 100644 index 0000000..c47d268 --- /dev/null +++ b/logger/logger.go @@ -0,0 +1,290 @@ +// Package logger offers simple logging +package logger + +import ( + "fmt" + "log" + "os" + "runtime/debug" + "sync" +) + +type severity int + +type logger interface { + Output(calldepth int, s string) error + SetFlags(flag int) +} + +// Severity levels. +const ( + sInfo severity = iota + sWarning + sError + sFatal +) + +// Severity tags. +const ( + tagInfo = "[INFO] " + tagWarning = "[WARN] " + tagError = "[ERROR] " + tagFatal = "[FATAL] " +) + +const ( + flags = log.Lmsgprefix | log.LstdFlags | log.Lshortfile +) + +var ( + logLock sync.Mutex + defaultLogger *Logger +) + +// initialize resets defaultLogger. Which allows tests to reset environment. +func initialize() { + defaultLogger = &Logger{ + loggers: []logger{ + log.New(os.Stderr, tagInfo, flags), + log.New(os.Stderr, tagWarning, flags), + log.New(os.Stderr, tagError, flags), + log.New(os.Stderr, tagFatal, flags), + }, + level: 3, + } +} + +func init() { + initialize() +} + +// Init sets up logging and should be called before log functions, usually in +// the caller's main(). Default log functions can be called before Init(), but +// every severity will be logged. +// The first call to Init populates the default logger and returns the +// generated logger, subsequent calls to Init will only return the generated +// logger. +func Init(level int) *Logger { + + loggers := []logger{ + log.New(os.Stderr, tagInfo, flags), + log.New(os.Stderr, tagWarning, flags), + log.New(os.Stderr, tagError, flags), + log.New(os.Stderr, tagFatal, flags), + } + l := Logger{loggers: loggers, level: level, initialized: true} + + logLock.Lock() + defer logLock.Unlock() + if !defaultLogger.initialized { + defaultLogger = &l + } + + return &l +} + +// A Logger represents an active logging object. Multiple loggers can be used +// simultaneously even if they are using the same writers. +type Logger struct { + loggers []logger + level int + initialized bool +} + +func (l *Logger) output(s severity, depth int, txt string) { + if s < sFatal-severity(l.level) { + return + } + logLock.Lock() + defer logLock.Unlock() + if int(s) >= len(l.loggers) { + panic(fmt.Sprintln("unrecognized severity:", s)) + } + l.loggers[s].Output(3+depth, txt) +} + +// SetFlags sets the output flags for the logger. +func (l *Logger) SetFlags(flag int) { + for _, logger := range l.loggers { + logger.SetFlags(flag) + } +} + +// Info logs with the Info severity. +// Arguments are handled in the manner of fmt.Print. +func (l *Logger) Info(v ...interface{}) { + l.output(sInfo, 0, fmt.Sprint(v...)) +} + +// InfoDepth acts as Info but uses depth to determine which call frame to log. +// InfoDepth(0, "msg") is the same as Info("msg"). +func (l *Logger) InfoDepth(depth int, v ...interface{}) { + l.output(sInfo, depth, fmt.Sprint(v...)) +} + +// Infoln logs with the Info severity. +// Arguments are handled in the manner of fmt.Println. +func (l *Logger) Infoln(v ...interface{}) { + l.output(sInfo, 0, fmt.Sprintln(v...)) +} + +// Infof logs with the Info severity. +// Arguments are handled in the manner of fmt.Printf. +func (l *Logger) Infof(format string, v ...interface{}) { + l.output(sInfo, 0, fmt.Sprintf(format, v...)) +} + +// Warning logs with the Warning severity. +// Arguments are handled in the manner of fmt.Print. +func (l *Logger) Warning(v ...interface{}) { + l.output(sWarning, 0, fmt.Sprint(v...)) +} + +// WarningDepth acts as Warning but uses depth to determine which call frame to log. +// WarningDepth(0, "msg") is the same as Warning("msg"). +func (l *Logger) WarningDepth(depth int, v ...interface{}) { + l.output(sWarning, depth, fmt.Sprint(v...)) +} + +// Warningln logs with the Warning severity. +// Arguments are handled in the manner of fmt.Println. +func (l *Logger) Warningln(v ...interface{}) { + l.output(sWarning, 0, fmt.Sprintln(v...)) +} + +// Warningf logs with the Warning severity. +// Arguments are handled in the manner of fmt.Printf. +func (l *Logger) Warningf(format string, v ...interface{}) { + l.output(sWarning, 0, fmt.Sprintf(format, v...)) +} + +// Error logs with the ERROR severity. +// Arguments are handled in the manner of fmt.Print. +func (l *Logger) Error(v ...interface{}) { + l.output(sError, 0, fmt.Sprint(v...)) +} + +// ErrorDepth acts as Error but uses depth to determine which call frame to log. +// ErrorDepth(0, "msg") is the same as Error("msg"). +func (l *Logger) ErrorDepth(depth int, v ...interface{}) { + l.output(sError, depth, fmt.Sprint(v...)) +} + +// Errorln logs with the ERROR severity. +// Arguments are handled in the manner of fmt.Println. +func (l *Logger) Errorln(v ...interface{}) { + l.output(sError, 0, fmt.Sprintln(v...)) +} + +// Errorf logs with the Error severity. +// Arguments are handled in the manner of fmt.Printf. +func (l *Logger) Errorf(format string, v ...interface{}) { + l.output(sError, 0, fmt.Sprintf(format, v...)) +} + +// Fatal logs with the Fatal severity, and ends with os.Exit(1). +// Arguments are handled in the manner of fmt.Print. +func (l *Logger) Fatal(v ...interface{}) { + l.output(sFatal, 0, fmt.Sprint(v...)) + os.Exit(1) +} + +// Fatalln logs with the Fatal severity, and ends with os.Exit(1). +// Arguments are handled in the manner of fmt.Println. +func (l *Logger) Fatalln(v ...interface{}) { + l.output(sFatal, 0, fmt.Sprintln(v...)) + os.Exit(1) +} + +// Fatalf logs with the Fatal severity, and ends with os.Exit(1). +// Arguments are handled in the manner of fmt.Printf. +func (l *Logger) Fatalf(format string, v ...interface{}) { + l.output(sFatal, 0, fmt.Sprintf(format, v...)) + os.Exit(1) +} + +// SetFlags sets the output flags for the logger. +func SetFlags(flag int) { + defaultLogger.SetFlags(flag) +} + +// Info uses the default logger and logs with the Info severity. +// Arguments are handled in the manner of fmt.Print. +func Info(v ...interface{}) { + defaultLogger.output(sInfo, 0, fmt.Sprint(v...)) +} + +// Infoln uses the default logger and logs with the Info severity. +// Arguments are handled in the manner of fmt.Println. +func Infoln(v ...interface{}) { + defaultLogger.output(sInfo, 0, fmt.Sprintln(v...)) +} + +// Infof uses the default logger and logs with the Info severity. +// Arguments are handled in the manner of fmt.Printf. +func Infof(format string, v ...interface{}) { + defaultLogger.output(sInfo, 0, fmt.Sprintf(format, v...)) +} + +// Warning uses the default logger and logs with the Warning severity. +// Arguments are handled in the manner of fmt.Print. +func Warning(v ...interface{}) { + defaultLogger.output(sWarning, 0, fmt.Sprint(v...)) +} + +// Warningln uses the default logger and logs with the Warning severity. +// Arguments are handled in the manner of fmt.Println. +func Warningln(v ...interface{}) { + defaultLogger.output(sWarning, 0, fmt.Sprintln(v...)) +} + +// Warningf uses the default logger and logs with the Warning severity. +// Arguments are handled in the manner of fmt.Printf. +func Warningf(format string, v ...interface{}) { + defaultLogger.output(sWarning, 0, fmt.Sprintf(format, v...)) +} + +// Error uses the default logger and logs with the Error severity. +// Arguments are handled in the manner of fmt.Print. +func Error(v ...interface{}) { + defaultLogger.output(sError, 0, fmt.Sprint(v...)) +} + +// Errorln uses the default logger and logs with the Error severity. +// Arguments are handled in the manner of fmt.Println. +func Errorln(v ...interface{}) { + defaultLogger.output(sError, 0, fmt.Sprintln(v...)) +} + +// Errorf uses the default logger and logs with the Error severity. +// Arguments are handled in the manner of fmt.Printf. +func Errorf(format string, v ...interface{}) { + defaultLogger.output(sError, 0, fmt.Sprintf(format, v...)) +} + +// Fatal uses the default logger, logs with the Fatal severity, +// and ends with os.Exit(1). +// Arguments are handled in the manner of fmt.Print. +func Fatal(v ...interface{}) { + defaultLogger.output(sFatal, 0, fmt.Sprint(v...)) + debug.PrintStack() + os.Exit(1) +} + +// Fatalln uses the default logger, logs with the Fatal severity, +// and ends with os.Exit(1). +// Arguments are handled in the manner of fmt.Println. +func Fatalln(v ...interface{}) { + defaultLogger.output(sFatal, 0, fmt.Sprintln(v...)) + debug.PrintStack() + os.Exit(1) +} + +// Fatalf uses the default logger, logs with the Fatal severity, +// and ends with os.Exit(1). +// Arguments are handled in the manner of fmt.Printf. +func Fatalf(format string, v ...interface{}) { + defaultLogger.output(sFatal, 0, fmt.Sprintf(format, v...)) + debug.PrintStack() + os.Exit(1) +} @@ -1,19 +1,39 @@ package main import ( + "flag" "fmt" "os" + + "github.com/n-peugnet/dna-backup/logger" ) -func main() { +const ( + usage = "usage: dna-backup [<options>] [--] <source> <dest>\n\noptions:\n" +) + +var ( + logLevel int +) - if len(os.Args) != 3 { - fmt.Println("usage: dna-backup <source> <dest>") +func init() { + flag.IntVar(&logLevel, "v", 1, "log verbosity level (0-3)") +} + +func main() { + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), usage) + flag.PrintDefaults() + } + flag.Parse() + logger.Init(logLevel) + if len(flag.Args()) != 2 { + flag.Usage() os.Exit(1) } - source := os.Args[1] - dest := os.Args[2] + source := os.Args[0] + dest := os.Args[1] repo := NewRepo(dest) repo.Commit(source) } |