package logger import ( "fmt" "log" "os" "runtime" "strings" "sync" ) type LogLevelType int var ( LogLevelDebug LogLevelType = 0 LogLevelInfo LogLevelType = 1 LogLevelError LogLevelType = 2 LogLevelSilent LogLevelType = 10 ) type LogWriter struct { WriterLevel LogLevelType } var logLevelMutex sync.RWMutex var logLevel = LogLevelInfo var DebugLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime) var InfoLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime) var ErrorLogger = log.New(os.Stderr, "", log.Ldate|log.Ltime) func DebugLn(v ...any) { if GetLogLevel() <= LogLevelDebug { prefix := getCallerPrefix() DebugLogger.Println(append([]interface{}{prefix}, v...)...) } } func Debug(v ...any) { if GetLogLevel() <= LogLevelDebug { prefix := getCallerPrefix() DebugLogger.Println(append([]interface{}{prefix}, v...)...) } } func Debugf(format string, v ...any) { if GetLogLevel() <= LogLevelDebug { prefix := getCallerPrefix() DebugLogger.Printf(prefix+format, v...) } } func InfoLn(v ...any) { if GetLogLevel() <= LogLevelInfo { InfoLogger.Println(v...) } } func Info(v ...any) { if GetLogLevel() <= LogLevelInfo { InfoLogger.Print(v...) } } func Infof(format string, v ...any) { if GetLogLevel() <= LogLevelInfo { InfoLogger.Printf(format, v...) } } func ErrorLn(v ...any) { if GetLogLevel() <= LogLevelError { prefix := getCallerPrefix() ErrorLogger.Println(append([]interface{}{prefix}, v...)...) } } func Error(v ...any) { if GetLogLevel() <= LogLevelError { prefix := getCallerPrefix() ErrorLogger.Print(append([]interface{}{prefix}, v...)...) } } func Errorf(format string, v ...any) { if GetLogLevel() <= LogLevelError { prefix := getCallerPrefix() ErrorLogger.Printf(prefix+format, v...) } } func (lw *LogWriter) Write(p []byte) (n int, err error) { switch lw.WriterLevel { case LogLevelDebug: Debug(string(p)) case LogLevelInfo: Info(string(p)) case LogLevelError: Error(string(p)) } return len(p), nil } func ErrorWriter() *LogWriter { return &LogWriter{WriterLevel: LogLevelError} } func InfoWriter() *LogWriter { return &LogWriter{WriterLevel: LogLevelInfo} } func DebugWriter() *LogWriter { return &LogWriter{WriterLevel: LogLevelDebug} } func SetLogLevel(level LogLevelType) { logLevelMutex.Lock() defer logLevelMutex.Unlock() logLevel = level } func GetLogLevel() LogLevelType { logLevelMutex.RLock() defer logLevelMutex.RUnlock() return logLevel } func getCallerPrefix() string { _, file, line, ok := runtime.Caller(2) if ok { parts := strings.Split(file, "/") if len(parts) > 0 { file = parts[len(parts)-1] } return fmt.Sprintf("%s:%d - ", file, line) } return "" }