common/sys_log.go
Rama main · réplica de lectura del repositorio original.
package common
import (
"fmt"
"io"
"net"
"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
// LogWriter and ErrorLogWriter write to gin.DefaultWriter and
// gin.DefaultErrorWriter as they are at write time. Middleware that keeps its
// writer from startup, such as the gin access logger and panic recovery, must
// use them: log rotation swaps the gin writers and closes the old log file.
var (
LogWriter io.Writer = currentLogWriter{}
ErrorLogWriter io.Writer = currentLogWriter{errorStream: true}
)
type currentLogWriter struct {
errorStream bool
}
func (w currentLogWriter) Write(p []byte) (int, error) {
LogWriterMu.RLock()
defer LogWriterMu.RUnlock()
if w.errorStream {
return gin.DefaultErrorWriter.Write(p)
}
return gin.DefaultWriter.Write(p)
}
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, host, port string) {
duration := time.Since(startTime)
durationMs := duration.Milliseconds()
// Get network IPs
networkIps := GetNetworkIps()
LogWriterMu.RLock()
defer LogWriterMu.RUnlock()
if SessionCookieSecure == false {
// Warn when the local HTTP compatibility mode disables cookie transport
// security and refresh/logout Origin validation.
fmt.Fprintf(gin.DefaultWriter, "\n")
fmt.Fprintf(gin.DefaultWriter, " \033[33m%s\033[0m\n", LogText("Warning: Refresh cookie is not secure and refresh/logout Origin validation is disabled. Please set SESSION_COOKIE_SECURE=true in production."))
fmt.Fprintf(gin.DefaultWriter, "\n")
}
fmt.Fprintf(gin.DefaultWriter, "\n")
fmt.Fprintf(gin.DefaultWriter, " \033[32m%s %s\033[0m %s\n", SystemName, Version, LogText("ready in %d ms", durationMs))
fmt.Fprintf(gin.DefaultWriter, "\n")
if ip := net.ParseIP(host); host != "" && !ip.IsUnspecified() {
label := LogText("Network:")
if ip.IsLoopback() {
label = LogText("Local:")
}
fmt.Fprintf(gin.DefaultWriter, " ➜ \033[1m%-8s\033[0m http://%s/\n", label, net.JoinHostPort(host, port))
fmt.Fprintf(gin.DefaultWriter, "\n")
return
}
if !IsRunningInContainer() {
fmt.Fprintf(gin.DefaultWriter, " ➜ \033[1m%-8s\033[0m http://localhost:%s/\n", LogText("Local:"), port)
}
for _, ip := range networkIps {
fmt.Fprintf(gin.DefaultWriter, " ➜ \033[1m%-8s\033[0m http://%s:%s/\n", LogText("Network:"), ip, port)
}
fmt.Fprintf(gin.DefaultWriter, "\n")
}