package logging import ( "github.com/gin-gonic/gin" "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" "system_pay/setting" ) var ( // DBCNormalLogger log DBCNormalLogger *zap.Logger ) // Init 初始化log func Init(cfg *setting.Log) (err error) { fileName := getLogFileName() filePath := getLogFilePath() writeSyncer := getLogWriter(filePath+fileName, cfg.MaxSize, cfg.MaxBackups, cfg.MaxAge) encoder := getEncoder() var l = new(zapcore.Level) err = l.UnmarshalText([]byte(cfg.Level)) if err != nil { return } var core zapcore.Core if gin.Mode() == gin.DebugMode { // 进入开发模式,日志输出到终端 consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()) core = zapcore.NewTee( zapcore.NewCore(encoder, writeSyncer, l), zapcore.NewCore(consoleEncoder, zapcore.Lock(os.Stdout), zapcore.DebugLevel), ) } else { core = zapcore.NewCore(encoder, writeSyncer, l) } DBCNormalLogger = zap.New(core, zap.AddCaller()) zap.ReplaceGlobals(DBCNormalLogger) zap.L().Info("init logger success") return } func getEncoder() zapcore.Encoder { encoderConfig := zap.NewProductionEncoderConfig() encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder encoderConfig.TimeKey = "time" encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder encoderConfig.EncodeDuration = zapcore.SecondsDurationEncoder encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder return zapcore.NewJSONEncoder(encoderConfig) } func getLogWriter(filename string, maxSize, maxBackup, maxAge int) zapcore.WriteSyncer { lumberJackLogger := &lumberjack.Logger{ Filename: filename, MaxSize: maxSize, MaxBackups: maxBackup, MaxAge: maxAge, } return zapcore.AddSync(lumberJackLogger) } //// GinLogger 接收gin框架默认的日志 //func GinLogger() gin.HandlerFunc { // return func(c *gin.Context) { // start := time.Now() // path := c.Request.URL.Path // query := c.Request.URL.RawQuery // c.Next() // // cost := time.Since(start) // DBCNormalLogger.Info(path, // zap.Int("status", c.Writer.Status()), // zap.String("method", c.Request.Method), // zap.String("path", path), // zap.String("query", query), // zap.String("ip", c.ClientIP()), // zap.String("user-agent", c.Request.UserAgent()), // zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()), // zap.Duration("cost", cost), // ) // } //} // //// GinRecovery recover掉项目可能出现的panic,并使用zap记录相关日志 //func GinRecovery(stack bool) gin.HandlerFunc { // return func(c *gin.Context) { // defer func() { // if err := recover(); err != nil { // // Check for a broken connection, as it is not really a // // condition that warrants a panic stack trace. // var brokenPipe bool // if ne, ok := err.(*net.OpError); ok { // if se, ok := ne.Err.(*os.SyscallError); ok { // if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") { // brokenPipe = true // } // } // } // // httpRequest, _ := httputil.DumpRequest(c.Request, false) // if brokenPipe { // DBCNormalLogger.Error(c.Request.URL.Path, // zap.Any("error", err), // zap.String("request", string(httpRequest)), // ) // // If the connection is dead, we can't write a status to it. // c.Error(err.(error)) // nolint: errcheck // c.Abort() // return // } // // if stack { // DBCNormalLogger.Error("[Recovery from panic]", // zap.Any("error", err), // zap.String("request", string(httpRequest)), // zap.String("stack", string(debug.Stack())), // ) // } else { // DBCNormalLogger.Error("[Recovery from panic]", // zap.Any("error", err), // zap.String("request", string(httpRequest)), // ) // } // c.AbortWithStatus(http.StatusInternalServerError) // } // }() // c.Next() // } //}