package muesli import ( "fmt" "reflect" "runtime" "strings" ) /** Logger interface that Muesli uses,to allow external logging packages to be used easly.*/ type Logger interface { Log(level string, file string, line int, format string, args ...interface{}) } func WriteLog(logger Logger, depth int, level string, format string, args ...interface{}) { if logger == nil { return } _, file, line, ok := runtime.Caller(depth) if !ok { file = "unknown" line = 0 } logger.Log(level, file, line, format, args...) } type LoggerWrapper struct { Logger } func (lw LoggerWrapper) WriteLog(depth int, level string, format string, args ...interface{}) { WriteLog(lw.Logger, depth, level, format, args...) } func (lw LoggerWrapper) LogDebug(format string, args ...interface{}) { lw.WriteLog(3, "DEBUG:", format, args...) } func (lw LoggerWrapper) LogInfo(format string, args ...interface{}) { lw.WriteLog(3, "INFO:", format, args...) } func (lw LoggerWrapper) LogWarning(format string, args ...interface{}) { lw.WriteLog(3, "WARNING:", format, args...) } func (lw LoggerWrapper) LogError(format string, args ...interface{}) { lw.WriteLog(3, "ERROR:", format, args...) } /* Logger used internally in Muesli for tests. */ type testLogger struct { last string repeat int } func (tl *testLogger) Log(level string, file string, line int, format string, args ...interface{}) { text1 := fmt.Sprintf("%s:%s:%d: ", level, file, line) text2 := fmt.Sprintf(format, args...) if format[len(format)-1] != '\n' { text2 = text2 + "\n" } out := text1 + text2 if strings.Compare(out, tl.last) == 0 { tl.repeat++ } else { if tl.repeat > 0 { fmt.Printf("%s:%s:%d: Above message repeated %d times.", level, file, line, tl.repeat) } tl.last = out tl.repeat = 0 fmt.Printf("%s", out) } } /* Useful when logging. */ func GetFunctionName(i interface{}) string { return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() }