package log import ( "fmt" "io" ) // DefaultLogger is the default logger for this package. type DefaultLogger struct { writer io.Writer name string level int formatter Formatter } // NewLogger creates a new default logger. If writer is not concurrent // safe, wrap it with NewConcurrentWriter. func NewLogger(writer io.Writer, name string) Logger { formatter, err := createFormatter(name, logxiFormat) if err != nil { panic("Could not create formatter") } return NewLogger3(writer, name, formatter) } // NewLogger3 creates a new logger with a writer, name and formatter. If writer is not concurrent // safe, wrap it with NewConcurrentWriter. func NewLogger3(writer io.Writer, name string, formatter Formatter) Logger { var level int if name != "__logxi" { // if err is returned, then it means the log is disabled level = getLogLevel(name) if level == LevelOff { return NullLog } } log := &DefaultLogger{ formatter: formatter, writer: writer, name: name, level: level, } // TODO loggers will be used when watching changes to configuration such // as in consul, etcd loggers.Lock() loggers.loggers[name] = log loggers.Unlock() return log } // New creates a colorable default logger. func New(name string) Logger { return NewLogger(colorableStdout, name) } // Trace logs a debug entry. func (l *DefaultLogger) Trace(msg string, args ...interface{}) { l.Log(LevelTrace, msg, args) } // Debug logs a debug entry. func (l *DefaultLogger) Debug(msg string, args ...interface{}) { l.Log(LevelDebug, msg, args) } // Info logs an info entry. func (l *DefaultLogger) Info(msg string, args ...interface{}) { l.Log(LevelInfo, msg, args) } // Warn logs a warn entry. func (l *DefaultLogger) Warn(msg string, args ...interface{}) error { if l.IsWarn() { defer l.Log(LevelWarn, msg, args) for _, arg := range args { if err, ok := arg.(error); ok { return err } } return nil } return nil } func (l *DefaultLogger) extractLogError(level int, msg string, args []interface{}) error { defer l.Log(level, msg, args) for _, arg := range args { if err, ok := arg.(error); ok { return err } } return fmt.Errorf(msg) } // Error logs an error entry. func (l *DefaultLogger) Error(msg string, args ...interface{}) error { return l.extractLogError(LevelError, msg, args) } // Fatal logs a fatal entry then panics. func (l *DefaultLogger) Fatal(msg string, args ...interface{}) { l.extractLogError(LevelFatal, msg, args) defer panic("Exit due to fatal error: ") } // Log logs a leveled entry. func (l *DefaultLogger) Log(level int, msg string, args []interface{}) { // log if the log level (warn=4) >= level of message (err=3) if l.level < level || silent { return } l.formatter.Format(l.writer, level, msg, args) } // IsTrace determines if this logger logs a debug statement. func (l *DefaultLogger) IsTrace() bool { // DEBUG(7) >= TRACE(10) return l.level >= LevelTrace } // IsDebug determines if this logger logs a debug statement. func (l *DefaultLogger) IsDebug() bool { return l.level >= LevelDebug } // IsInfo determines if this logger logs an info statement. func (l *DefaultLogger) IsInfo() bool { return l.level >= LevelInfo } // IsWarn determines if this logger logs a warning statement. func (l *DefaultLogger) IsWarn() bool { return l.level >= LevelWarn } // SetLevel sets the level of this logger. func (l *DefaultLogger) SetLevel(level int) { l.level = level } // SetFormatter set the formatter for this logger. func (l *DefaultLogger) SetFormatter(formatter Formatter) { l.formatter = formatter }