Skip to content
Snippets Groups Projects
Commit cda2b608 authored by Manuel Kieweg's avatar Manuel Kieweg
Browse files

log levels can have different writers

parent bb159ce7
No related branches found
No related tags found
2 merge requests!41Resolve "Enhanced Logging",!18Develop
Pipeline #52253 passed with warnings
...@@ -17,18 +17,36 @@ var once sync.Once ...@@ -17,18 +17,36 @@ var once sync.Once
// Logger is a wrapper for log.Logger and provides // Logger is a wrapper for log.Logger and provides
// methods to enable and disable logging. // methods to enable and disable logging.
type Logger struct { type Logger struct {
Out io.Writer DefaultWriter io.Writer
Loglevel Level LoglevelWriter map[Level]io.Writer
lock sync.Mutex Loglevel Level
builder strings.Builder 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 { func get() *Logger {
once.Do(func() { once.Do(func() {
logger = &Logger{ logger = &Logger{
Out: os.Stderr, DefaultWriter: os.Stderr,
Loglevel: INFO, LoglevelWriter: make(map[Level]io.Writer),
lock: sync.Mutex{}, Loglevel: INFO,
lock: sync.Mutex{},
} }
}) })
return logger return logger
...@@ -49,7 +67,16 @@ func Output(out io.Writer) { ...@@ -49,7 +67,16 @@ func Output(out io.Writer) {
l := get() l := get()
l.lock.Lock() l.lock.Lock()
defer l.lock.Unlock() 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 //Debug passes the DEBUG flag and a
...@@ -101,21 +128,17 @@ func log(level Level, args ...interface{}) { ...@@ -101,21 +128,17 @@ func log(level Level, args ...interface{}) {
l := get() l := get()
l.lock.Lock() l.lock.Lock()
defer l.lock.Unlock() defer l.lock.Unlock()
defer l.builder.Reset()
if level <= l.Loglevel { if level <= l.Loglevel {
l.builder.WriteString(time.Now().Format(time.RFC3339)) l.buildMessage(level, args...)
l.builder.WriteRune('\t') msg := []byte(l.builder.String())
l.builder.WriteString(prefix(level)) writer, ok := l.LoglevelWriter[level]
l.builder.WriteRune('\t') var err error
function, line := callers() if !ok {
functionSplitted := strings.SplitAfter(function, "/") _, err = l.DefaultWriter.Write(msg)
function = functionSplitted[len(functionSplitted) - 1] } else {
l.builder.WriteString(function) _, err = writer.Write(msg)
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()))
if err != nil { if err != nil {
panic(err) panic(err)
} }
...@@ -124,7 +147,7 @@ func log(level Level, args ...interface{}) { ...@@ -124,7 +147,7 @@ func log(level Level, args ...interface{}) {
func callers() (string, int) { func callers() (string, int) {
pc := make([]uintptr, 15) pc := make([]uintptr, 15)
n := runtime.Callers(4, pc) n := runtime.Callers(5, pc)
frames := runtime.CallersFrames(pc[:n]) frames := runtime.CallersFrames(pc[:n])
frame, _ := frames.Next() frame, _ := frames.Next()
return frame.Function, frame.Line return frame.Function, frame.Line
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment