package common import ( "fmt" "os" "sync" "time" "github.com/gin-gonic/gin" ) // LogWriterMu protects concurrent access to gin.DefaultWriter/gin.DefaultErrorWriter // during log file rotation. Acquire RLock when reading/writing through the writers, // acquire Lock when swapping writers and closing old files. var LogWriterMu sync.RWMutex func SysLog(s string) { t := time.Now() LogWriterMu.RLock() _, _ = fmt.Fprintf(gin.DefaultWriter, "[SYS] %v | %s \n", t.Format("2006/01/02 - 15:04:05"), s) LogWriterMu.RUnlock() } func SysError(s string) { t := time.Now() LogWriterMu.RLock() _, _ = fmt.Fprintf(gin.DefaultErrorWriter, "[SYS] %v | %s \n", t.Format("2006/01/02 - 15:04:05"), s) LogWriterMu.RUnlock() } func FatalLog(v ...any) { t := time.Now() LogWriterMu.RLock() _, _ = fmt.Fprintf(gin.DefaultErrorWriter, "[FATAL] %v | %v \n", t.Format("2006/01/02 - 15:04:05"), v) LogWriterMu.RUnlock() os.Exit(1) } func LogStartupSuccess(startTime time.Time, port string) { duration := time.Since(startTime) durationMs := duration.Milliseconds() // Get network IPs networkIps := GetNetworkIps() LogWriterMu.RLock() defer LogWriterMu.RUnlock() fmt.Fprintf(gin.DefaultWriter, "\n") fmt.Fprintf(gin.DefaultWriter, " \033[32m%s %s\033[0m ready in %d ms\n", SystemName, Version, durationMs) fmt.Fprintf(gin.DefaultWriter, "\n") if !IsRunningInContainer() { fmt.Fprintf(gin.DefaultWriter, " ➜ \033[1mLocal:\033[0m http://localhost:%s/\n", port) } for _, ip := range networkIps { fmt.Fprintf(gin.DefaultWriter, " ➜ \033[1mNetwork:\033[0m http://%s:%s/\n", ip, port) } fmt.Fprintf(gin.DefaultWriter, "\n") }