package logger import ( "fmt" "io" "log" "os" "time" ) // LogLevel represents the severity of a log message type LogLevel int const ( // DEBUG level for detailed information DEBUG LogLevel = iota // INFO level for general operational information INFO // WARN level for warnings WARN // ERROR level for errors ERROR // FATAL level for fatal errors that cause the application to exit FATAL ) var ( // defaultLogger is the default logger used by the package defaultLogger *Logger // level names for pretty printing levelNames = []string{ "DEBUG", "INFO", "WARN", "ERROR", "FATAL", } ) // Logger is a custom logger that wraps the standard log package type Logger struct { debugLog *log.Logger infoLog *log.Logger warnLog *log.Logger errorLog *log.Logger fatalLog *log.Logger } // Init initializes the default logger with the specified output and minimum log level func Init(out io.Writer, level LogLevel) { defaultLogger = NewLogger(out, level) } // NewLogger creates a new logger with the specified output and minimum log level func NewLogger(out io.Writer, level LogLevel) *Logger { if out == nil { out = os.Stdout } flags := log.Ldate | log.Ltime l := &Logger{ debugLog: log.New(out, "[DEBUG] ", flags), infoLog: log.New(out, "[INFO] ", flags), warnLog: log.New(out, "[WARN] ", flags), errorLog: log.New(out, "[ERROR] ", flags), fatalLog: log.New(out, "[FATAL] ", flags), } return l } // Debug logs a debug message func (l *Logger) Debug(v ...interface{}) { l.debugLog.Println(v...) } // Info logs an info message func (l *Logger) Info(v ...interface{}) { l.infoLog.Println(v...) } // Warn logs a warning message func (l *Logger) Warn(v ...interface{}) { l.warnLog.Println(v...) } // Error logs an error message func (l *Logger) Error(v ...interface{}) { l.errorLog.Println(v...) } // Fatal logs a fatal message and exits the program func (l *Logger) Fatal(v ...interface{}) { l.fatalLog.Println(v...) os.Exit(1) } // Debugf logs a formatted debug message func (l *Logger) Debugf(format string, v ...interface{}) { l.debugLog.Printf(format, v...) } // Infof logs a formatted info message func (l *Logger) Infof(format string, v ...interface{}) { l.infoLog.Printf(format, v...) } // Warnf logs a formatted warning message func (l *Logger) Warnf(format string, v ...interface{}) { l.warnLog.Printf(format, v...) } // Errorf logs a formatted error message func (l *Logger) Errorf(format string, v ...interface{}) { l.errorLog.Printf(format, v...) } // Fatalf logs a formatted fatal message and exits the program func (l *Logger) Fatalf(format string, v ...interface{}) { l.fatalLog.Printf(format, v...) os.Exit(1) } // LogRequest logs an HTTP request func (l *Logger) LogRequest(method, path, ip, userAgent string, status int, latency time.Duration) { l.Infof( "Request: %s %s | Status: %d | IP: %s | User-Agent: %s | Latency: %v", method, path, status, ip, userAgent, latency, ) } // GetTimestamp returns the current timestamp as a formatted string func GetTimestamp() string { return time.Now().Format("2006-01-02 15:04:05") } // FormatRequestLog formats a request log entry with useful information func FormatRequestLog(method, path, ip, userAgent string, statusCode int, latency time.Duration) string { return fmt.Sprintf( "Request: %s %s | Status: %d | IP: %s | Latency: %s | User-Agent: %s", method, path, statusCode, ip, latency, userAgent, ) }