package main import ( "fmt" "log" "os" "runtime" "time" ) var AppLogger = NewCustomLogger() // CustomLogger wraps the standard logger type CustomLogger struct { logger *log.Logger } // NewCustomLogger initializes the custom logger func NewCustomLogger() *CustomLogger { // Create a logger that writes to stdout with no flags return &CustomLogger{ logger: log.New(os.Stdout, "", 0), // we will handle formatting manually } } // logFormat retrieves the function name, file, and line number func logFormat() string { // Use the runtime.Caller to retrieve caller info pc, file, line, ok := runtime.Caller(2) if !ok { file = "unknown" line = 0 } // Get function name funcName := runtime.FuncForPC(pc).Name() // Format timestamp timestamp := time.Now().Format("2006-01-02 15:04:05") // Return formatted log prefix (timestamp, file, line, and function name) return fmt.Sprintf("%s - %s:%d - %s: ", timestamp, file, line, funcName) } // Info logs informational messages func (c *CustomLogger) Info(msg string) { c.logger.Println(logFormat() + "INFO: " + msg) } // Error logs error messages func (c *CustomLogger) Error(msg string) { c.logger.Println(logFormat() + "ERROR: " + msg) } // Example usage of the custom logger func showcase() { logger := NewCustomLogger() logger.Info("This is an info message") logger.Error("This is an error message") }