Skip to content

Instantly share code, notes, and snippets.

@bylatt
Created August 2, 2023 04:21
Show Gist options
  • Save bylatt/ca5901adf064d24aa0a0c3234d518dff to your computer and use it in GitHub Desktop.
Save bylatt/ca5901adf064d24aa0a0c3234d518dff to your computer and use it in GitHub Desktop.
package logger
import (
"errors"
"fmt"
"io"
"github.com/rs/zerolog"
)
type Logger struct {
impl *zerolog.Logger
}
func removeExcessArgs(keysAndValues []any) []any {
if len(keysAndValues) == 0 {
return keysAndValues
}
if len(keysAndValues)%2 == 1 {
return keysAndValues[:len(keysAndValues)-1]
}
return keysAndValues
}
func keyValueListToMap(keysAndValues []any) map[string]any {
result := make(map[string]any)
for len(keysAndValues) > 0 {
result[fmt.Sprint(keysAndValues[0])] = keysAndValues[1]
keysAndValues = keysAndValues[2:]
}
return result
}
func (l *Logger) Trace(msg string, keysAndValues ...any) {
keyValueSlice := removeExcessArgs(keysAndValues)
keyValueMap := keyValueListToMap(keyValueSlice)
log := l.impl.Trace()
for key, val := range keyValueMap {
log = log.Interface(key, val)
}
log.Msg(msg)
}
func (l *Logger) Debug(msg string, keysAndValues ...any) {
keyValueSlice := removeExcessArgs(keysAndValues)
keyValueMap := keyValueListToMap(keyValueSlice)
log := l.impl.Debug()
for key, val := range keyValueMap {
log = log.Interface(key, val)
}
log.Msg(msg)
}
func (l *Logger) Info(msg string, keysAndValues ...any) {
keyValueSlice := removeExcessArgs(keysAndValues)
keyValueMap := keyValueListToMap(keyValueSlice)
log := l.impl.Info()
for key, val := range keyValueMap {
log = log.Interface(key, val)
}
log.Msg(msg)
}
func (l *Logger) Warn(msg string, keysAndValues ...any) {
keyValueSlice := removeExcessArgs(keysAndValues)
keyValueMap := keyValueListToMap(keyValueSlice)
log := l.impl.Warn()
for key, val := range keyValueMap {
log = log.Interface(key, val)
}
log.Msg(msg)
}
func (l *Logger) Error(msg string, keysAndValues ...any) {
keyValueSlice := removeExcessArgs(keysAndValues)
keyValueMap := keyValueListToMap(keyValueSlice)
log := l.impl.Error()
for key, val := range keyValueMap {
log = log.Interface(key, val)
}
log.Msg(msg)
}
func (l *Logger) Fatal(msg string, keysAndValues ...any) {
keyValueSlice := removeExcessArgs(keysAndValues)
keyValueMap := keyValueListToMap(keyValueSlice)
log := l.impl.Fatal()
for key, val := range keyValueMap {
log = log.Interface(key, val)
}
log.Msg(msg)
}
func (l *Logger) Panic(msg string, keysAndValues ...any) {
keyValueSlice := removeExcessArgs(keysAndValues)
keyValueMap := keyValueListToMap(keyValueSlice)
log := l.impl.Panic()
for key, val := range keyValueMap {
log = log.Interface(key, val)
}
log.Msg(msg)
}
var logger *Logger
type Level int8
const (
DebugLevel Level = iota
InfoLevel
WarnLevel
ErrorLevel
FatalLevel
PanicLevel
TraceLevel Level = -1
)
func InitLogger(w io.Writer) {
logger = NewLoggerWithLevelAndName(w, zerolog.InfoLevel, nil)
}
func InitLoggerWithLevelAndName(w io.Writer, lv Level, name *string) {
var zerologLevel zerolog.Level
switch lv {
case DebugLevel:
zerologLevel = zerolog.DebugLevel
case InfoLevel:
zerologLevel = zerolog.InfoLevel
case WarnLevel:
zerologLevel = zerolog.WarnLevel
case ErrorLevel:
zerologLevel = zerolog.ErrorLevel
case FatalLevel:
zerologLevel = zerolog.FatalLevel
case PanicLevel:
zerologLevel = zerolog.PanicLevel
case TraceLevel:
zerologLevel = zerolog.TraceLevel
default:
err := errors.New("unsupported log level")
panic(err)
}
logger = NewLoggerWithLevelAndName(w, zerologLevel, name)
}
func NewDefaultLogger(w io.Writer) *Logger {
l := zerolog.New(w).With().Timestamp().Logger()
return &Logger{impl: &l}
}
func NewLoggerWithLevelAndName(w io.Writer, lv zerolog.Level, name *string) *Logger {
var l zerolog.Logger
if name != nil && *name != "" {
l = zerolog.New(w).Level(lv).With().Timestamp().Str("name", *name).Logger()
} else {
l = zerolog.New(w).Level(lv).With().Timestamp().Logger()
}
return &Logger{impl: &l}
}
func SetOutput(w io.Writer) {
l2 := logger.impl.Output(w)
logger.impl = &l2
}
func GetCurrentLogger() *Logger {
return logger
}
func Trace(msg string, keysAndValues ...any) {
logger.Trace(msg, keysAndValues...)
}
func Debug(msg string, keysAndValues ...any) {
logger.Debug(msg, keysAndValues...)
}
func Info(msg string, keysAndValues ...any) {
logger.Info(msg, keysAndValues...)
}
func Warn(msg string, keysAndValues ...any) {
logger.Warn(msg, keysAndValues...)
}
func Error(msg string, keysAndValues ...any) {
logger.Error(msg, keysAndValues...)
}
func Fatal(msg string, keysAndValues ...any) {
logger.Fatal(msg, keysAndValues...)
}
func Panic(msg string, keysAndValues ...any) {
logger.Panic(msg, keysAndValues...)
}
// Usage
// logger.Info("message", "key1", "value1", "key2", "value2", ...)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment