180 lines
4.3 KiB
Go
180 lines
4.3 KiB
Go
// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code
|
|
// is governed by an MIT-style license that can be found in the LICENSE file.
|
|
|
|
// Package logger implements a standardized logger with callback functionality
|
|
package logger
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type LogLevel int
|
|
|
|
const (
|
|
LevelDebug LogLevel = iota
|
|
LevelVerbose
|
|
LevelInfo
|
|
LevelOK
|
|
LevelWarn
|
|
LevelFatal
|
|
NumLevels
|
|
)
|
|
|
|
// A MessageHandler is called with the log level and message text.
|
|
type MessageHandler func(l LogLevel, msg string)
|
|
|
|
type Logger struct {
|
|
logger *log.Logger
|
|
handlers [NumLevels][]MessageHandler
|
|
mut sync.Mutex
|
|
}
|
|
|
|
// The default logger logs to standard output with a time prefix.
|
|
var DefaultLogger = New()
|
|
|
|
func New() *Logger {
|
|
return &Logger{
|
|
logger: log.New(os.Stdout, "", log.Ltime),
|
|
}
|
|
}
|
|
|
|
// AddHandler registers a new MessageHandler to receive messages with the
|
|
// specified log level or above.
|
|
func (l *Logger) AddHandler(level LogLevel, h MessageHandler) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
l.handlers[level] = append(l.handlers[level], h)
|
|
}
|
|
|
|
// See log.SetFlags
|
|
func (l *Logger) SetFlags(flag int) {
|
|
l.logger.SetFlags(flag)
|
|
}
|
|
|
|
// See log.SetPrefix
|
|
func (l *Logger) SetPrefix(prefix string) {
|
|
l.logger.SetPrefix(prefix)
|
|
}
|
|
|
|
func (l *Logger) callHandlers(level LogLevel, s string) {
|
|
for _, h := range l.handlers[level] {
|
|
h(level, strings.TrimSpace(s))
|
|
}
|
|
}
|
|
|
|
// Debugln logs a line with a DEBUG prefix.
|
|
func (l *Logger) Debugln(vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintln(vals...)
|
|
l.logger.Output(2, "DEBUG: "+s)
|
|
l.callHandlers(LevelDebug, s)
|
|
}
|
|
|
|
// Debugf logs a formatted line with a DEBUG prefix.
|
|
func (l *Logger) Debugf(format string, vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintf(format, vals...)
|
|
l.logger.Output(2, "DEBUG: "+s)
|
|
l.callHandlers(LevelDebug, s)
|
|
}
|
|
|
|
// Infoln logs a line with a VERBOSE prefix.
|
|
func (l *Logger) Verboseln(vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintln(vals...)
|
|
l.logger.Output(2, "VERBOSE: "+s)
|
|
l.callHandlers(LevelVerbose, s)
|
|
}
|
|
|
|
// Infof logs a formatted line with a VERBOSE prefix.
|
|
func (l *Logger) Verbosef(format string, vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintf(format, vals...)
|
|
l.logger.Output(2, "VERBOSE: "+s)
|
|
l.callHandlers(LevelVerbose, s)
|
|
}
|
|
|
|
// Infoln logs a line with an INFO prefix.
|
|
func (l *Logger) Infoln(vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintln(vals...)
|
|
l.logger.Output(2, "INFO: "+s)
|
|
l.callHandlers(LevelInfo, s)
|
|
}
|
|
|
|
// Infof logs a formatted line with an INFO prefix.
|
|
func (l *Logger) Infof(format string, vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintf(format, vals...)
|
|
l.logger.Output(2, "INFO: "+s)
|
|
l.callHandlers(LevelInfo, s)
|
|
}
|
|
|
|
// Okln logs a line with an OK prefix.
|
|
func (l *Logger) Okln(vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintln(vals...)
|
|
l.logger.Output(2, "OK: "+s)
|
|
l.callHandlers(LevelOK, s)
|
|
}
|
|
|
|
// Okf logs a formatted line with an OK prefix.
|
|
func (l *Logger) Okf(format string, vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintf(format, vals...)
|
|
l.logger.Output(2, "OK: "+s)
|
|
l.callHandlers(LevelOK, s)
|
|
}
|
|
|
|
// Warnln logs a formatted line with a WARNING prefix.
|
|
func (l *Logger) Warnln(vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintln(vals...)
|
|
l.logger.Output(2, "WARNING: "+s)
|
|
l.callHandlers(LevelWarn, s)
|
|
}
|
|
|
|
// Warnf logs a formatted line with a WARNING prefix.
|
|
func (l *Logger) Warnf(format string, vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintf(format, vals...)
|
|
l.logger.Output(2, "WARNING: "+s)
|
|
l.callHandlers(LevelWarn, s)
|
|
}
|
|
|
|
// Fatalln logs a line with a FATAL prefix and exits the process with exit
|
|
// code 1.
|
|
func (l *Logger) Fatalln(vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintln(vals...)
|
|
l.logger.Output(2, "FATAL: "+s)
|
|
l.callHandlers(LevelFatal, s)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Fatalf logs a formatted line with a FATAL prefix and exits the process with
|
|
// exit code 1.
|
|
func (l *Logger) Fatalf(format string, vals ...interface{}) {
|
|
l.mut.Lock()
|
|
defer l.mut.Unlock()
|
|
s := fmt.Sprintf(format, vals...)
|
|
l.logger.Output(2, "FATAL: "+s)
|
|
l.callHandlers(LevelFatal, s)
|
|
os.Exit(1)
|
|
}
|