diff --git a/log/logger.go b/log/logger.go index 2e856d3b76aed7c7fb1c4e577aeccfd93654c2ab..4a75751123037fb7a163de63f4073f595f9fe1bf 100644 --- a/log/logger.go +++ b/log/logger.go @@ -17,18 +17,36 @@ var once sync.Once // Logger is a wrapper for log.Logger and provides // methods to enable and disable logging. type Logger struct { - Out io.Writer - Loglevel Level - lock sync.Mutex - builder strings.Builder + DefaultWriter io.Writer + LoglevelWriter map[Level]io.Writer + Loglevel Level + lock sync.Mutex + builder strings.Builder +} + +func (l *Logger) buildMessage(level Level, args ...interface{}) { + l.builder.WriteString(time.Now().Format(time.RFC3339)) + l.builder.WriteRune('\t') + l.builder.WriteString(prefix(level)) + l.builder.WriteRune('\t') + function, line := callers() + functionSplitted := strings.SplitAfter(function, "/") + function = functionSplitted[len(functionSplitted)-1] + l.builder.WriteString(function) + l.builder.WriteRune(':') + l.builder.WriteString(strconv.Itoa(line)) + l.builder.WriteRune('\t') + l.builder.WriteString(fmt.Sprint(args...)) + l.builder.WriteRune('\n') } func get() *Logger { once.Do(func() { logger = &Logger{ - Out: os.Stderr, - Loglevel: INFO, - lock: sync.Mutex{}, + DefaultWriter: os.Stderr, + LoglevelWriter: make(map[Level]io.Writer), + Loglevel: INFO, + lock: sync.Mutex{}, } }) return logger @@ -49,7 +67,16 @@ func Output(out io.Writer) { l := get() l.lock.Lock() defer l.lock.Unlock() - l.Out = out + l.DefaultWriter = out +} + +//LoglevelOutput defines a special output +//for a certain log level +func LoglevelOutput(level Level, out io.Writer) { + l := get() + l.lock.Lock() + defer l.lock.Unlock() + l.LoglevelWriter[level] = out } //Debug passes the DEBUG flag and a @@ -101,21 +128,17 @@ func log(level Level, args ...interface{}) { l := get() l.lock.Lock() defer l.lock.Unlock() + defer l.builder.Reset() if level <= l.Loglevel { - l.builder.WriteString(time.Now().Format(time.RFC3339)) - l.builder.WriteRune('\t') - l.builder.WriteString(prefix(level)) - l.builder.WriteRune('\t') - function, line := callers() - functionSplitted := strings.SplitAfter(function, "/") - function = functionSplitted[len(functionSplitted) - 1] - l.builder.WriteString(function) - l.builder.WriteRune(':') - l.builder.WriteString(strconv.Itoa(line)) - l.builder.WriteRune('\t') - l.builder.WriteString(fmt.Sprint(args...)) - l.builder.WriteRune('\n') - _,err := l.Out.Write([]byte(l.builder.String())) + l.buildMessage(level, args...) + msg := []byte(l.builder.String()) + writer, ok := l.LoglevelWriter[level] + var err error + if !ok { + _, err = l.DefaultWriter.Write(msg) + } else { + _, err = writer.Write(msg) + } if err != nil { panic(err) } @@ -124,7 +147,7 @@ func log(level Level, args ...interface{}) { func callers() (string, int) { pc := make([]uintptr, 15) - n := runtime.Callers(4, pc) + n := runtime.Callers(5, pc) frames := runtime.CallersFrames(pc[:n]) frame, _ := frames.Next() return frame.Function, frame.Line