diff --git a/lib/log/default.go b/lib/log/default.go new file mode 100644 index 0000000000000000000000000000000000000000..beddd59aeb0bcda9058e47f9afe9c9dcfb93d431 --- /dev/null +++ b/lib/log/default.go @@ -0,0 +1,25 @@ +package log + +import "os" + +var Default *Logger = WriterLogger(os.Stderr) + +func Debug(message string) { Default.Debug(message) } +func Info(message string) { Default.Info(message) } +func Notice(message string) { Default.Notice(message) } +func Warning(message string) { Default.Warning(message) } +func Error(message string) { Default.Error(message) } +func Critical(message string) { Default.Critical(message) } + +func Debugf(template string, args ...interface{}) { Default.Debugf(template, args...) } +func Infof(template string, args ...interface{}) { Default.Infof(template, args...) } +func Noticef(template string, args ...interface{}) { Default.Noticef(template, args...) } +func Warningf(template string, args ...interface{}) { Default.Warningf(template, args...) } +func Errorf(template string, args ...interface{}) { Default.Errorf(template, args...) } +func Criticalf(template string, args ...interface{}) { Default.Criticalf(template, args...) } + +var ErrorHandler func(err error) = defaultErrorHandler + +func defaultErrorHandler(err error) { + _, _ = os.Stderr.WriteString("Error while logging: " + err.Error() + "\n") +} diff --git a/lib/log/entry.go b/lib/log/entry.go new file mode 100644 index 0000000000000000000000000000000000000000..37180acf4997052fffac16b1746dc04c744f1bd2 --- /dev/null +++ b/lib/log/entry.go @@ -0,0 +1,21 @@ +package log + +import ( + "fmt" + "time" +) + +type Entry struct { + Timestamp time.Time + Level Level + Message string + Fields *Fields +} + +func NewEntry(level Level, message string, fields *Fields) *Entry { + return &Entry{time.Now(), level, message, fields} +} + +func NewEntryf(level Level, template string, args []interface{}, fields *Fields) *Entry { + return NewEntry(level, fmt.Sprintf(template, args...), fields) +} diff --git a/lib/log/fields.go b/lib/log/fields.go new file mode 100644 index 0000000000000000000000000000000000000000..ccd860f14ee06af6ba24827626b8787b03612652 --- /dev/null +++ b/lib/log/fields.go @@ -0,0 +1,16 @@ +package log + +type Fields struct { + Name string + Value interface{} + previous *Fields +} + +func (f *Fields) With(name string, value interface{}) *Fields { + return &Fields{name, value, f} +} + +func (f *Fields) ForEach(do func(string, interface{}) bool) { + for i := f; i != nil && do(i.Name, i.Value); i = i.previous { + } +} diff --git a/lib/log/level.go b/lib/log/level.go new file mode 100644 index 0000000000000000000000000000000000000000..b9c3b8c5513a93cda78e3f1757e3ab30a3d33378 --- /dev/null +++ b/lib/log/level.go @@ -0,0 +1,30 @@ +package log + +type Level byte + +const ( + DEBUG Level = iota + INFO + NOTICE + WARNING + ERROR + CRITICAL +) + +func (l Level) String() string { + switch l { + case DEBUG: + return "DEBUG" + case INFO: + return "INFO" + case NOTICE: + return "NOTICE" + case WARNING: + return "WARNING" + case ERROR: + return "ERROR" + case CRITICAL: + return "CRITICAL" + } + panic("unknown log level") +} diff --git a/lib/log/logger.go b/lib/log/logger.go new file mode 100644 index 0000000000000000000000000000000000000000..7565fb5eb076434633a2501722a4fae0e9e5ae9d --- /dev/null +++ b/lib/log/logger.go @@ -0,0 +1,45 @@ +package log + +type logger interface { + Log(*Entry) +} + +type Logger struct { + logger + Fields *Fields +} + +func (l *Logger) WithField(name string, value interface{}) *Logger { + return &Logger{l, l.Fields.With(name, value)} +} + +func (l *Logger) Debug(message string) { l.Log(NewEntry(DEBUG, message, l.Fields)) } +func (l *Logger) Info(message string) { l.Log(NewEntry(INFO, message, l.Fields)) } +func (l *Logger) Notice(message string) { l.Log(NewEntry(NOTICE, message, l.Fields)) } +func (l *Logger) Warning(message string) { l.Log(NewEntry(WARNING, message, l.Fields)) } +func (l *Logger) Error(message string) { l.Log(NewEntry(ERROR, message, l.Fields)) } +func (l *Logger) Critical(message string) { l.Log(NewEntry(CRITICAL, message, l.Fields)) } + +func (l *Logger) Debugf(template string, args ...interface{}) { + l.Log(NewEntryf(DEBUG, template, args, l.Fields)) +} + +func (l *Logger) Infof(template string, args ...interface{}) { + l.Log(NewEntryf(INFO, template, args, l.Fields)) +} + +func (l *Logger) Noticef(template string, args ...interface{}) { + l.Log(NewEntryf(NOTICE, template, args, l.Fields)) +} + +func (l *Logger) Warningf(template string, args ...interface{}) { + l.Log(NewEntryf(WARNING, template, args, l.Fields)) +} + +func (l *Logger) Errorf(template string, args ...interface{}) { + l.Log(NewEntryf(ERROR, template, args, l.Fields)) +} + +func (l *Logger) Criticalf(template string, args ...interface{}) { + l.Log(NewEntryf(CRITICAL, template, args, l.Fields)) +} diff --git a/lib/log/writer.go b/lib/log/writer.go new file mode 100644 index 0000000000000000000000000000000000000000..bd4eadc50bd20c32e2020c4f243e58c53cb7f363 --- /dev/null +++ b/lib/log/writer.go @@ -0,0 +1,16 @@ +package log + +import ( + "io" +) + +type writerLogger struct { + target io.Writer +} + +func (l writerLogger) Log(entry *Entry) { +} + +func WriterLogger(target io.WriteCloser) *Logger { + return &Logger{logger: writerLogger{target}} +}