package applog import ( "io" "log" "os" "path/filepath" "time" "github.com/gin-gonic/gin" "gorm.io/gorm/logger" ) // Setup 将标准库 log、Gin 请求日志同时写到控制台与文件。 // logFile 为空则仅控制台。返回文件句柄供进程结束时 Close(可为 nil)。 func Setup(logFile string) (*os.File, error) { writers := []io.Writer{os.Stdout} var f *os.File if logFile != "" { dir := filepath.Dir(logFile) if err := os.MkdirAll(dir, 0o755); err != nil { return nil, err } var err error f, err = os.OpenFile(logFile, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644) if err != nil { return nil, err } writers = append(writers, f) } mw := io.MultiWriter(writers...) log.SetOutput(mw) log.SetFlags(log.LstdFlags | log.Lmicroseconds) // Gin access / recovery 日志 gin.DefaultWriter = mw gin.DefaultErrorWriter = mw if logFile != "" { abs, _ := filepath.Abs(logFile) log.Printf("[applog] 日志同时输出到控制台与文件: %s", abs) } return f, nil } // NewGormLogger 返回写到当前 log 输出(已含 MultiWriter)的 GORM 日志 func NewGormLogger(mode string) logger.Interface { level := logger.Info if mode == "release" { level = logger.Warn } return logger.New( log.New(log.Writer(), "\r\n", log.LstdFlags), logger.Config{ SlowThreshold: 200 * time.Millisecond, LogLevel: level, IgnoreRecordNotFoundError: true, Colorful: false, }, ) }