package logger import ( "fmt" "log" "os" ) // Level represents the logging level type Level int const ( DebugLevel Level = iota InfoLevel WarnLevel ErrorLevel ) // Logger is a simple structured logger type Logger struct { level Level } // New creates a new logger with the specified level func New(level Level) *Logger { return &Logger{level: level} } // NewFromString creates a logger from a string level func NewFromString(levelStr string) *Logger { level := InfoLevel switch levelStr { case "debug": level = DebugLevel case "info": level = InfoLevel case "warn": level = WarnLevel case "error": level = ErrorLevel } return New(level) } func (l *Logger) log(level Level, msg string, args ...interface{}) { if level < l.level { return } levelName := "" switch level { case DebugLevel: levelName = "DEBUG" case InfoLevel: levelName = "INFO" case WarnLevel: levelName = "WARN" case ErrorLevel: levelName = "ERROR" } // Simple formatting for key-value pairs output := fmt.Sprintf("[%s] %s", levelName, msg) if len(args) > 0 { output += fmt.Sprintf(" %v", args) } log.Println(output) } // Debug logs a debug message func (l *Logger) Debug(msg string, args ...interface{}) { l.log(DebugLevel, msg, args...) } // Info logs an info message func (l *Logger) Info(msg string, args ...interface{}) { l.log(InfoLevel, msg, args...) } // Warn logs a warning message func (l *Logger) Warn(msg string, args ...interface{}) { l.log(WarnLevel, msg, args...) } // Error logs an error message func (l *Logger) Error(msg string, args ...interface{}) { l.log(ErrorLevel, msg, args...) } // Fatal logs a fatal message and exits func (l *Logger) Fatal(msg string, args ...interface{}) { l.log(ErrorLevel, msg, args...) os.Exit(1) }