logger/multi.go

329 lines
8.4 KiB
Go

package logger
import (
"fmt"
"os"
)
var _ Logger = (*MultiLogger)(nil)
// MultiLogger implements the Logger interface by
// writing to multiple underlying loggers sequentially.
type MultiLogger struct {
Loggers []Logger
noPanic bool
noExit bool
}
// NewMulti creates and returns a new MultiLogger
func NewMulti(l ...Logger) *MultiLogger {
for _, logger := range l {
logger.NoPanic()
logger.NoExit()
}
return &MultiLogger{Loggers: l}
}
// NoExit prevents the logger from exiting on fatal events
func (ml *MultiLogger) NoExit() {
ml.noExit = true
}
// NoPanic prevents the logger from panicking on panic events
func (ml *MultiLogger) NoPanic() {
ml.noPanic = true
}
// SetLevel sets the log level of the logger
func (ml *MultiLogger) SetLevel(l LogLevel) {
for _, logger := range ml.Loggers {
logger.SetLevel(l)
}
}
// Debug creates a new debug event with the given message
func (ml *MultiLogger) Debug(msg string) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Debug(msg)
}
return &MultiLogBuilder{ml, lbs, LogLevelDebug}
}
// Debugf creates a new debug event with the formatted message
func (ml *MultiLogger) Debugf(format string, v ...any) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Debugf(format, v...)
}
return &MultiLogBuilder{ml, lbs, LogLevelDebug}
}
// Info creates a new info event with the given message
func (ml *MultiLogger) Info(msg string) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Info(msg)
}
return &MultiLogBuilder{ml, lbs, LogLevelInfo}
}
// Infof creates a new info event with the formatted message
func (ml *MultiLogger) Infof(format string, v ...any) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Infof(format, v...)
}
return &MultiLogBuilder{ml, lbs, LogLevelInfo}
}
// Warn creates a new warn event with the given message
func (ml *MultiLogger) Warn(msg string) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Warn(msg)
}
return &MultiLogBuilder{ml, lbs, LogLevelWarn}
}
// Warnf creates a new warn event with the formatted message
func (ml *MultiLogger) Warnf(format string, v ...any) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Warnf(format, v...)
}
return &MultiLogBuilder{ml, lbs, LogLevelWarn}
}
// Error creates a new error event with the given message
func (ml *MultiLogger) Error(msg string) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Error(msg)
}
return &MultiLogBuilder{ml, lbs, LogLevelError}
}
// Errorf creates a new error event with the formatted message
func (ml *MultiLogger) Errorf(format string, v ...any) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Errorf(format, v...)
}
return &MultiLogBuilder{ml, lbs, LogLevelError}
}
// Error creates a new error event with the given message
func (ml *MultiLogger) Fatal(msg string) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Fatal(msg)
}
return &MultiLogBuilder{ml, lbs, LogLevelFatal}
}
// Errorf creates a new error event with the formatted message
func (ml *MultiLogger) Fatalf(format string, v ...any) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Fatalf(format, v...)
}
return &MultiLogBuilder{ml, lbs, LogLevelFatal}
}
// Error creates a new error event with the given message
func (ml *MultiLogger) Panic(msg string) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Panic(msg)
}
return &MultiLogBuilder{ml, lbs, LogLevelPanic}
}
// Errorf creates a new error event with the formatted message
func (ml *MultiLogger) Panicf(format string, v ...any) LogBuilder {
lbs := make([]LogBuilder, len(ml.Loggers))
for index, logger := range ml.Loggers {
lbs[index] = logger.Panicf(format, v...)
}
return &MultiLogBuilder{ml, lbs, LogLevelPanic}
}
// MultiLogBuilder implements the LogBuilder interface
// by writing to multiple underlying LogBuilders sequentially.
type MultiLogBuilder struct {
l *MultiLogger
lbs []LogBuilder
lvl LogLevel
}
// Int adds an int field to the output
func (mlb *MultiLogBuilder) Int(key string, val int) LogBuilder {
for _, lb := range mlb.lbs {
lb.Int(key, val)
}
return mlb
}
// Int64 adds an int64 field to the output
func (mlb *MultiLogBuilder) Int64(key string, val int64) LogBuilder {
for _, lb := range mlb.lbs {
lb.Int64(key, val)
}
return mlb
}
// Int32 adds an int32 field to the output
func (mlb *MultiLogBuilder) Int32(key string, val int32) LogBuilder {
for _, lb := range mlb.lbs {
lb.Int32(key, val)
}
return mlb
}
// Int16 adds an int16 field to the output
func (mlb *MultiLogBuilder) Int16(key string, val int16) LogBuilder {
for _, lb := range mlb.lbs {
lb.Int16(key, val)
}
return mlb
}
// Int8 adds an int8 field to the output
func (mlb *MultiLogBuilder) Int8(key string, val int8) LogBuilder {
for _, lb := range mlb.lbs {
lb.Int8(key, val)
}
return mlb
}
// Uint adds a uint field to the output
func (mlb *MultiLogBuilder) Uint(key string, val uint) LogBuilder {
for _, lb := range mlb.lbs {
lb.Uint(key, val)
}
return mlb
}
// Uint64 adds a uint64 field to the output
func (mlb *MultiLogBuilder) Uint64(key string, val uint64) LogBuilder {
for _, lb := range mlb.lbs {
lb.Uint64(key, val)
}
return mlb
}
// Uint32 adds a uint32 field to the output
func (mlb *MultiLogBuilder) Uint32(key string, val uint32) LogBuilder {
for _, lb := range mlb.lbs {
lb.Uint32(key, val)
}
return mlb
}
// Uint16 adds a uint16 field to the output
func (mlb *MultiLogBuilder) Uint16(key string, val uint16) LogBuilder {
for _, lb := range mlb.lbs {
lb.Uint16(key, val)
}
return mlb
}
// Uint8 adds a uint8 field to the output
func (mlb *MultiLogBuilder) Uint8(key string, val uint8) LogBuilder {
for _, lb := range mlb.lbs {
lb.Uint8(key, val)
}
return mlb
}
// Float64 adds a float64 field to the output
func (mlb *MultiLogBuilder) Float64(key string, val float64) LogBuilder {
for _, lb := range mlb.lbs {
lb.Float64(key, val)
}
return mlb
}
// Float32 adds a float32 field to the output
func (mlb *MultiLogBuilder) Float32(key string, val float32) LogBuilder {
for _, lb := range mlb.lbs {
lb.Float32(key, val)
}
return mlb
}
// Stringer calls the String method of an fmt.Stringer
// and adds the resulting string as a field to the output
func (mlb *MultiLogBuilder) Stringer(key string, s fmt.Stringer) LogBuilder {
for _, lb := range mlb.lbs {
lb.Stringer(key, s)
}
return mlb
}
// Bytes writes base64-encoded bytes as a field to the output
func (mlb *MultiLogBuilder) Bytes(key string, b []byte) LogBuilder {
for _, lb := range mlb.lbs {
lb.Bytes(key, b)
}
return mlb
}
// Timestamp adds the time formatted as RFC3339Nano
// as a field to the output using the key "timestamp"
func (mlb *MultiLogBuilder) Timestamp() LogBuilder {
for _, lb := range mlb.lbs {
lb.Timestamp()
}
return mlb
}
// Bool adds a bool as a field to the output
func (mlb *MultiLogBuilder) Bool(key string, val bool) LogBuilder {
for _, lb := range mlb.lbs {
lb.Bool(key, val)
}
return mlb
}
// Str adds a string as a field to the output
func (mlb *MultiLogBuilder) Str(key, val string) LogBuilder {
for _, lb := range mlb.lbs {
lb.Str(key, val)
}
return mlb
}
// Any uses reflection to marshal any type and writes
// the result as a field to the output. This is much slower
// than the type-specific functions.
func (mlb *MultiLogBuilder) Any(key string, val any) LogBuilder {
for _, lb := range mlb.lbs {
lb.Any(key, val)
}
return mlb
}
// Err adds an error as a field to the output
func (mlb *MultiLogBuilder) Err(err error) LogBuilder {
for _, lb := range mlb.lbs {
lb.Err(err)
}
return mlb
}
// Send sends the event to the output.
//
// After calling send, do not use the event again.
func (mlb *MultiLogBuilder) Send() {
for _, lb := range mlb.lbs {
lb.Send()
}
if mlb.lvl == LogLevelFatal && !mlb.l.noExit {
os.Exit(1)
} else if mlb.lvl == LogLevelPanic && !mlb.l.noPanic {
panic("")
}
}