func (l *Log) Warn(msg string, fields ...zap.Field) {
	if msg != "" {
		l.Logger.Warn(msg, fields...)
	}
}
Warn logs a message at WarnLevel. The message includes any fields passed
at the log site, as well as any fields accumulated on the logger.
package logs
import (
	"database/sql/driver"
	"fmt"
	"log"
	"os"
	"reflect"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"time"
	"unicode"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	lumberjack "gopkg.in/natefinch/lumberjack.v2"
)
var (
	logger                       *Log
	gromDebugLogger              = log.New(os.Stdout, "\r\n", 0)
	gromSQLRegexp                = regexp.MustCompile(`\?`)
	gromNumericPlaceHolderRegexp = regexp.MustCompile(`\$\d+`)
)
type Conf struct {
	OutPath    string `json:"outPath"`
	Level      string `json:"level"`
	MaxSize    int    `json:"maxSize"`
	MaxBackups int    `json:"maxBackups"`
	MaxAge     int    `json:"maxAge"`
	Debug      bool   `json:"debug"`
	LogSelect  bool   `json:"logSelect"`
	Stdout     bool   `json:"-"`
}
type Log struct {
	zap.Logger
	logConf *Conf
}
type GormLog struct {
}
func Init(conf *Conf) *Log {
	if logger == nil {
		logger = newLog(conf)
	}
	return logger
}
func newLog(conf *Conf) *Log {
	if conf == nil {
		conf = &Conf{
			OutPath:    "./logs/logs.log",
			Level:      "info",
			MaxSize:    10,
			MaxBackups: 5,
			MaxAge:     28,
			Debug:      false,
		}
	} else {
		if conf.OutPath == "" {
			conf.Stdout = true
		}
	}
	if conf.MaxSize <= 0 {
		conf.MaxSize = 10
	}
	if conf.MaxBackups <= 0 {
		conf.MaxSize = 5
	}
	if conf.MaxAge <= 0 {
		conf.MaxAge = 28
	}
	l := logLevel(conf.Level)
	var w zapcore.WriteSyncer
	var core zapcore.Core
	if !conf.Stdout {
		encoderConfig := zap.NewProductionEncoderConfig()
		encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
			enc.AppendString(t.Format("2006-01-02 15:04:05"))
		}
		w = zapcore.AddSync(&lumberjack.Logger{
			Filename:   conf.OutPath,
			MaxSize:    conf.MaxSize,  
			MaxBackups: conf.MaxBackups,
			MaxAge:     conf.MaxAge,  
		})
		core = zapcore.NewCore(
			zapcore.NewJSONEncoder(encoderConfig),
			w,
			l,
		)
	} else {
		encoderConfig := zap.NewDevelopmentEncoderConfig()
		encoderConfig.LineEnding = zapcore.DefaultLineEnding
		encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
			enc.AppendString(t.Format("2006-01-02 15:04:05"))
		}
		consoleDebugging := zapcore.Lock(os.Stdout)
		consoleErrors := zapcore.Lock(os.Stderr)
		consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
		core = zapcore.NewTee(
			zapcore.NewCore(consoleEncoder, consoleErrors, zapcore.FatalLevel),
			zapcore.NewCore(consoleEncoder, consoleDebugging, zapcore.DebugLevel),
		)
	}
	return &Log{Logger: *zap.New(core), logConf: conf}
}
func (l *Log) Info(msg string, fields ...zap.Field) {
	if msg != "" {
		l.Logger.Info(msg, fields...)
	}
}
func Info(msg string, fields ...zap.Field) {
	if logger != nil && msg != "" {
		logger.Info(msg, fields...)
	}
}