|
|
|
package logging
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// higher log level means more logging...
|
|
|
|
const (
|
|
|
|
ERROR = iota
|
|
|
|
WARNING
|
|
|
|
INFO
|
|
|
|
DEBUG
|
|
|
|
TRACE
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
LoggerCreated int = iota // return code if the logger creates a new logger
|
|
|
|
LoggerExists // retun cde in the case that there is already a logger
|
|
|
|
ErrorCreatingLogger // in case of error creating the logger
|
|
|
|
)
|
|
|
|
|
|
|
|
var logLevelStringMap = map[string]int{
|
|
|
|
"error": ERROR,
|
|
|
|
"warning": WARNING,
|
|
|
|
"info": INFO,
|
|
|
|
"debug": DEBUG,
|
|
|
|
"trace": TRACE,
|
|
|
|
}
|
|
|
|
|
|
|
|
type logOutput interface {
|
|
|
|
Printf(format string, a ...interface{})
|
|
|
|
// Println(format string, a ...interface{})
|
|
|
|
init(m *io.Writer, s string, ll int)
|
|
|
|
}
|
|
|
|
|
|
|
|
type logStream struct {
|
|
|
|
s *log.Logger
|
|
|
|
logLevel int
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
Trace logStream
|
|
|
|
Debug logStream
|
|
|
|
Info logStream
|
|
|
|
Warning logStream
|
|
|
|
Error logStream
|
|
|
|
DefaultLogger logStream
|
|
|
|
LogLevel int
|
|
|
|
)
|
|
|
|
|
|
|
|
func (l *logStream) Printf(format string, a ...interface{}) {
|
|
|
|
// describe(a)
|
|
|
|
if LogLevel < l.logLevel {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// if no specific logger is configured for this logstrea, write to stdout...
|
|
|
|
if l.s == nil {
|
|
|
|
fmt.Printf(format, a...)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
l.s.Printf(format, a...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *logStream) init(m io.Writer, s string, ll int) {
|
|
|
|
l.s = log.New(m, s, log.Ldate|log.Ltime|log.Lshortfile)
|
|
|
|
l.logLevel = ll
|
|
|
|
}
|
|
|
|
|
|
|
|
// function to parse string representation of log level into integer - if there
|
|
|
|
// is no match of the string, it will return 0 which maps to error only
|
|
|
|
// logging...perhaps this could be made more explicit
|
|
|
|
func determineLogLevel(lstr string) int {
|
|
|
|
lstrLowerCase := strings.ToLower(lstr)
|
|
|
|
return logLevelStringMap[lstrLowerCase]
|
|
|
|
}
|
|
|
|
|
|
|
|
func InitLogger(logFile string, logLevelStr string, logToConsole bool) {
|
|
|
|
|
|
|
|
LogLevel = determineLogLevel(logLevelStr)
|
|
|
|
|
|
|
|
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
|
|
|
|
|
|
|
var multi io.Writer
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Failed to open log file:", logFile, ":", err)
|
|
|
|
multi = io.MultiWriter(os.Stdout)
|
|
|
|
} else {
|
|
|
|
if logToConsole {
|
|
|
|
multi = io.MultiWriter(file, os.Stdout)
|
|
|
|
} else {
|
|
|
|
multi = io.MultiWriter(file)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Trace.init(multi, " TRACE: ", TRACE)
|
|
|
|
Debug.init(multi, " DEBUG: ", DEBUG)
|
|
|
|
Info.init(multi, " INFO: ", INFO)
|
|
|
|
Warning.init(multi, "WARNING: ", WARNING)
|
|
|
|
Error.init(multi, " ERROR: ", ERROR)
|
|
|
|
}
|