Files
LaodingBot/internal/logger/logger.go
2026-02-21 23:01:39 +08:00

90 lines
1.7 KiB
Go

package logger
import (
"fmt"
"log"
"os"
"strings"
)
type Level int
const (
LevelDebug Level = iota
LevelInfo
LevelWarn
LevelError
)
type Logger struct {
base *log.Logger
level Level
component string
}
func New(level string) (*Logger, error) {
parsed, err := ParseLevel(level)
if err != nil {
return nil, err
}
return &Logger{
base: log.New(os.Stdout, "", log.LstdFlags|log.Lmicroseconds),
level: parsed,
component: "app",
}, nil
}
func ParseLevel(raw string) (Level, error) {
switch strings.ToLower(strings.TrimSpace(raw)) {
case "debug":
return LevelDebug, nil
case "info", "":
return LevelInfo, nil
case "warn", "warning":
return LevelWarn, nil
case "error":
return LevelError, nil
default:
return LevelInfo, fmt.Errorf("invalid LOG_LEVEL=%q, expected debug|info|warn|error", raw)
}
}
func (l *Logger) WithComponent(component string) *Logger {
if component == "" {
component = "app"
}
return &Logger{
base: l.base,
level: l.level,
component: component,
}
}
func (l *Logger) Level() Level {
return l.level
}
func (l *Logger) Debugf(format string, args ...any) {
l.logf(LevelDebug, "DEBUG", format, args...)
}
func (l *Logger) Infof(format string, args ...any) {
l.logf(LevelInfo, "INFO", format, args...)
}
func (l *Logger) Warnf(format string, args ...any) {
l.logf(LevelWarn, "WARN", format, args...)
}
func (l *Logger) Errorf(format string, args ...any) {
l.logf(LevelError, "ERROR", format, args...)
}
func (l *Logger) logf(level Level, label, format string, args ...any) {
if level < l.level {
return
}
msg := fmt.Sprintf(format, args...)
l.base.Printf("[%s] [%s] %s", label, l.component, msg)
}