Files
logger/golang-logger.go
Ron Rise 7950e042ee
All checks were successful
🚀 Publish Release Package / publish (push) Successful in 26s
add initial implementation of golang_logger with CloudWatch and StdErr handlers
2025-06-18 17:36:01 -04:00

160 lines
2.9 KiB
Go

package golang_logger
import (
"fmt"
"strings"
"time"
)
type Handler interface {
Log(msg logFormat)
}
type Logger struct {
handlers []Handler
level Level
channel string
extraFunc func() interface{}
}
type logFormat struct {
Message string `json:"message"`
Context interface{} `json:"context"`
Level int `json:"level"`
LevelName string `json:"level_name"`
Channel string `json:"channel"`
DateTime string `json:"date_time"`
Extra interface{} `json:"extra"`
}
type Level int
const (
Debug Level = 100
Info Level = 200
Notice Level = 250
Warn Level = 300
Error Level = 400
Fatal Level = 500
Emerg Level = 600
)
func NewLogger(channel string, level Level, handlers ...Handler) *Logger {
return &Logger{
level: level,
handlers: handlers,
channel: channel,
}
}
func (l *Logger) PushHandler(handler Handler) *Logger {
l.handlers = append(l.handlers, handler)
return l
}
func (l *Logger) ExtraFunc(f func() interface{}) *Logger {
l.extraFunc = f
return l
}
func LevelFromString(l string) Level {
switch strings.ToLower(l) {
case "debug":
return Debug
case "info":
return Info
case "notice":
return Notice
case "warn":
return Warn
case "error":
return Error
case "fatal":
return Fatal
case "emerg":
return Emerg
default:
return Debug
}
}
func (l *Level) String() string {
switch *l {
case Debug:
return "DEBUG"
case Info:
return "INFO"
case Notice:
return "NOTICE"
case Warn:
return "WARN"
case Error:
return "ERROR"
case Fatal:
return "FATAL"
case Emerg:
return "EMERG"
default:
return "UNKNOWN"
}
}
// Fatal logs a fatal message and exits
func (l *Logger) Fatal(msg string, context ...interface{}) {
l.log(Fatal, msg, context...)
}
// Error logs an error message
func (l *Logger) Error(msg string, context ...interface{}) {
l.log(Error, msg, context...)
}
// Warn logs a warning message
func (l *Logger) Warn(msg string, context ...interface{}) {
l.log(Warn, msg, context...)
}
// Info logs an info message
func (l *Logger) Info(msg string, context ...interface{}) {
l.log(Info, msg, context...)
}
// Infof logs an info message with formatting
func (l *Logger) Infof(msg string, context ...interface{}) {
l.log(Info, fmt.Sprintf(msg, context...))
}
// Debug logs a debug message
func (l *Logger) Debug(msg string, context ...interface{}) {
l.log(Debug, msg, context...)
}
func (l *Logger) log(level Level, msg string, context ...interface{}) {
// check if the level is allowed
if int32(l.level) > int32(level) {
return
}
var extra interface{}
if l.extraFunc != nil {
extra = l.extraFunc()
}
logFormated := logFormat{
Message: msg,
Context: context,
Level: int(level),
LevelName: level.String(),
Channel: l.channel,
DateTime: time.Now().Format(time.RFC3339Nano),
Extra: extra,
}
for _, handler := range l.handlers {
(handler).Log(logFormated)
}
}