提交 e6a2c8bf 编写于 作者: Sliver_Horn's avatar Sliver_Horn

go-logging(停止维护了)替换成zap, zap的配置完善优化,gva的日志更换zap后的处理

上级 9bac9fb2
......@@ -73,7 +73,10 @@ zap:
# console: 控制台, json: json格式输出
format: 'console'
prefix: '[GIN-VUE-ADMIN]'
director: 'logs'
link_name: 'ZapLatestLog'
director: 'log'
link_name: 'latest_log'
show_line: true
# LowercaseLevelEncoder:小写, LowercaseColorLevelEncoder:小写带颜色,CapitalLevelEncoder: 大写, CapitalColorLevelEncoder: 大写带颜色,
encode_level: 'LowercaseColorLevelEncoder'
stacktrace_key: 'stacktrace'
log_in_console: true
\ No newline at end of file
package config
type Server struct {
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"`
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
System System `mapstructure:"system" json:"system" yaml:"system"`
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
Log Log `mapstructure:"log" json:"log" yaml:"log"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"`
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
System System `mapstructure:"system" json:"system" yaml:"system"`
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
LocalUpload LocalUpload `mapstructure:"localUpload" json:"localUpload" yaml:"localUpload"`
}
......@@ -47,9 +46,9 @@ type Redis struct {
}
type LocalUpload struct {
Local bool `mapstructure:"local" json:"local" yaml:"local"`
Local bool `mapstructure:"local" json:"local" yaml:"local"`
AvatarPath string `mapstructure:"avatar-path" json:"avatarPath" yaml:"avatar-path"`
FilePath string `mapstructure:"file-path" json:"filePath" yaml:"file-path"`
FilePath string `mapstructure:"file-path" json:"filePath" yaml:"file-path"`
}
type Qiniu struct {
......@@ -65,13 +64,6 @@ type Captcha struct {
ImgHeight int `mapstructure:"img-height" json:"imgHeight" yaml:"img-height"`
}
type Log struct {
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`
LogFile bool `mapstructure:"log-file" json:"logFile" yaml:"log-file"`
Stdout string `mapstructure:"stdout" json:"stdout" yaml:"stdout"`
File string `mapstructure:"file" json:"file" yaml:"file"`
}
type Sqlite struct {
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
......@@ -81,11 +73,13 @@ type Sqlite struct {
}
type Zap struct {
Level string `mapstructure:"level" json:"level" yaml:"level"`
Format string `mapstructure:"format" json:"format" yaml:"format"`
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`
Director string `mapstructure:"director" json:"director" yaml:"director"`
LinkName string `mapstructure:"link_name" json:"linkName" yaml:"link_name"`
ShowLine bool `mapstructure:"show_line" json:"show_line" yaml:"show_line"`
LogInConsole bool `mapstructure:"log_in_console" json:"logInConsole" yaml:"log_in_console"`
Level string `mapstructure:"level" json:"level" yaml:"level"`
Format string `mapstructure:"format" json:"format" yaml:"format"`
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`
Director string `mapstructure:"director" json:"director" yaml:"director"`
LinkName string `mapstructure:"link_name" json:"linkName" yaml:"link_name"`
ShowLine bool `mapstructure:"show_line" json:"showLine" yaml:"showLine"`
EncodeLevel string `mapstructure:"encode_level" json:"encodeLevel" yaml:"encode_level"`
StacktraceKey string `mapstructure:"stacktrace_key" json:"stacktraceKey" yaml:"stacktrace_key"`
LogInConsole bool `mapstructure:"log_in_console" json:"logInConsole" yaml:"log_in_console"`
}
package core
import (
"fmt"
"gin-vue-admin/config"
"gin-vue-admin/global"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
rotatelogs "github.com/lestrrat/go-file-rotatelogs"
oplogging "github.com/op/go-logging"
"io"
"os"
"strings"
"time"
)
const (
logDir = "log"
logSoftLink = "latest_log"
module = "gin-vue-admin"
)
var (
defaultFormatter = `%{time:2006/01/02 - 15:04:05.000} %{longfile} %{color:bold}▶ [%{level:.6s}] %{message}%{color:reset}`
)
func init() {
c := global.GVA_CONFIG.Log
if c.Prefix == "" {
_ = fmt.Errorf("logger prefix not found")
}
logger := oplogging.MustGetLogger(module)
var backends []oplogging.Backend
registerStdout(c, &backends)
if fileWriter := registerFile(c, &backends); fileWriter != nil {
gin.DefaultWriter = io.MultiWriter(fileWriter, os.Stdout)
}
oplogging.SetBackend(backends...)
global.GVA_LOG = logger
}
func registerStdout(c config.Log, backends *[]oplogging.Backend) {
if c.Stdout != "" {
level, err := oplogging.LogLevel(c.Stdout)
if err != nil {
fmt.Println(err)
}
*backends = append(*backends, createBackend(os.Stdout, c, level))
}
}
func registerFile(c config.Log, backends *[]oplogging.Backend) io.Writer {
if c.File != "" {
if ok, _ := utils.PathExists(logDir); !ok {
// directory not exist
fmt.Println("create log directory")
_ = os.Mkdir(logDir, os.ModePerm)
}
fileWriter, err := rotatelogs.New(
logDir+string(os.PathSeparator)+"%Y-%m-%d-%H-%M.log",
// generate soft link, point to latest log file
rotatelogs.WithLinkName(logSoftLink),
// maximum time to save log files
rotatelogs.WithMaxAge(7*24*time.Hour),
// time period of log file switching
rotatelogs.WithRotationTime(24*time.Hour),
)
if err != nil {
fmt.Println(err)
}
level, err := oplogging.LogLevel(c.File)
if err != nil {
fmt.Println(err)
}
*backends = append(*backends, createBackend(fileWriter, c, level))
return fileWriter
}
return nil
}
func createBackend(w io.Writer, c config.Log, level oplogging.Level) oplogging.Backend {
backend := oplogging.NewLogBackend(w, c.Prefix, 0)
stdoutWriter := false
if w == os.Stdout {
stdoutWriter = true
}
format := getLogFormatter(c, stdoutWriter)
backendLeveled := oplogging.AddModuleLevel(oplogging.NewBackendFormatter(backend, format))
backendLeveled.SetLevel(level, module)
return backendLeveled
}
func getLogFormatter(c config.Log, stdoutWriter bool) oplogging.Formatter {
pattern := defaultFormatter
if !stdoutWriter {
// Color is only required for console output
// Other writers don't need %{color} tag
pattern = strings.Replace(pattern, "%{color:bold}", "", -1)
pattern = strings.Replace(pattern, "%{color:reset}", "", -1)
}
if !c.LogFile {
// Remove %{logfile} tag
pattern = strings.Replace(pattern, "%{longfile}", "", -1)
}
return oplogging.MustStringFormatter(pattern)
}
......@@ -4,6 +4,7 @@ import (
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/initialize"
"go.uber.org/zap"
"time"
)
......@@ -24,11 +25,11 @@ func RunWindowsServer() {
// 保证文本顺序输出
// In order to ensure that the text order output can be deleted
time.Sleep(10 * time.Microsecond)
global.GVA_LOG.Debug("server run success on ", address)
global.GVA_LOG.Debug("server run success on ", zap.String("address", address))
fmt.Printf(`欢迎使用 Gin-Vue-Admin
默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
默认前端文件运行地址:http://127.0.0.1:8080
`, address)
global.GVA_LOG.Error(s.ListenAndServe())
global.GVA_LOG.Error(s.ListenAndServe().Error())
}
......@@ -13,17 +13,17 @@ import (
var (
err error
level zapcore.Level
level zapcore.Level
writer zapcore.WriteSyncer
)
func init() {
if ok, _ := utils.PathExists(global.GVA_CONFIG.Zap.Director); !ok { // 判断是否有logs文件夹
fmt.Println("create logs directory") // directory not exist
if ok, _ := utils.PathExists(global.GVA_CONFIG.Zap.Director); !ok { // 判断是否有Director文件夹
fmt.Printf("create %v directory\n", global.GVA_CONFIG.Zap.Director)
_ = os.Mkdir(global.GVA_CONFIG.Zap.Director, os.ModePerm)
}
switch global.GVA_CONFIG.Zap.Level {// 初始化配置文件的Level
switch global.GVA_CONFIG.Zap.Level { // 初始化配置文件的Level
case "debug":
level = zap.DebugLevel
case "info":
......@@ -32,6 +32,12 @@ func init() {
level = zap.WarnLevel
case "error":
level = zap.ErrorLevel
case "dpanic":
level = zap.DPanicLevel
case "panic":
level = zap.PanicLevel
case "fatal":
level = zap.FatalLevel
default:
level = zap.InfoLevel
}
......@@ -43,23 +49,19 @@ func init() {
}
if level == zap.DebugLevel || level == zap.ErrorLevel {
global.GVA_ZAP = zap.New(getEncoderCore(), zap.AddStacktrace(level))
if global.GVA_CONFIG.Zap.ShowLine {
global.GVA_ZAP.WithOptions(zap.AddCaller())
}
return
global.GVA_LOG = zap.New(getEncoderCore(), zap.AddStacktrace(level))
} else {
global.GVA_LOG = zap.New(getEncoderCore())
}
global.GVA_ZAP = zap.New(getEncoderCore())
if global.GVA_CONFIG.Zap.ShowLine {
global.GVA_ZAP.WithOptions(zap.AddCaller())
global.GVA_LOG.WithOptions(zap.AddCaller())
}
}
// getWriteSyncer zap logger中加入file-rotatelogs
func getWriteSyncer() (zapcore.WriteSyncer, error) {
fileWriter, err := zaprotatelogs.New(
global.GVA_CONFIG.Zap.Director+string(os.PathSeparator)+"%Y-%m-%d-%H-%M.log",
global.GVA_CONFIG.Zap.Director+string(os.PathSeparator)+"%Y-%m-%d.log",
zaprotatelogs.WithLinkName(global.GVA_CONFIG.Zap.LinkName),
zaprotatelogs.WithMaxAge(7*24*time.Hour),
zaprotatelogs.WithRotationTime(24*time.Hour),
......@@ -78,18 +80,41 @@ func getEncoderConfig() (config zapcore.EncoderConfig) {
TimeKey: "time",
NameKey: "logger",
CallerKey: "caller",
StacktraceKey: "stacktrace",
StacktraceKey: global.GVA_CONFIG.Zap.StacktraceKey,
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalColorLevelEncoder,
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: CustomTimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.FullCallerEncoder,
}
switch {
case global.GVA_CONFIG.Zap.EncodeLevel == "LowercaseLevelEncoder" && global.GVA_CONFIG.Zap.Format == "console" : // console小写编码器
config.EncodeLevel = zapcore.LowercaseLevelEncoder
case global.GVA_CONFIG.Zap.EncodeLevel == "LowercaseLevelEncoder" && global.GVA_CONFIG.Zap.Format == "json" : // json小写编码器
config.EncodeLevel = zapcore.LowercaseLevelEncoder
case global.GVA_CONFIG.Zap.EncodeLevel == "LowercaseColorLevelEncoder" && global.GVA_CONFIG.Zap.Format == "console": // console小写编码器带颜色
config.EncodeLevel = zapcore.LowercaseColorLevelEncoder
case global.GVA_CONFIG.Zap.EncodeLevel == "LowercaseColorLevelEncoder" && global.GVA_CONFIG.Zap.Format == "json": // json小写编码器带颜色
config.EncodeLevel = zapcore.LowercaseColorLevelEncoder
case global.GVA_CONFIG.Zap.EncodeLevel == "CapitalLevelEncoder" && global.GVA_CONFIG.Zap.Format == "console": // console大写编码器
config.EncodeLevel = zapcore.CapitalLevelEncoder
case global.GVA_CONFIG.Zap.EncodeLevel == "CapitalLevelEncoder" && global.GVA_CONFIG.Zap.Format == "json": // json大写编码器
config.EncodeLevel = zapcore.CapitalLevelEncoder
case global.GVA_CONFIG.Zap.EncodeLevel == "CapitalColorLevelEncoder" && global.GVA_CONFIG.Zap.Format == "console": // console 大写编码器带颜色
config.EncodeLevel = zapcore.CapitalColorLevelEncoder
case global.GVA_CONFIG.Zap.EncodeLevel == "CapitalColorLevelEncoder" && global.GVA_CONFIG.Zap.Format == "json": // json 大写编码器带颜色
config.EncodeLevel = zapcore.CapitalColorLevelEncoder
default:
config.EncodeLevel = zapcore.LowercaseLevelEncoder
}
return config
}
// getEncoder 获取zapcore.Encoder
func getEncoder() zapcore.Encoder {
if global.GVA_CONFIG.Zap.Format == "json" {
return zapcore.NewJSONEncoder(getEncoderConfig())
}
return zapcore.NewConsoleEncoder(getEncoderConfig())
}
......@@ -100,5 +125,5 @@ func getEncoderCore() (core zapcore.Core) {
// 自定义日志输出时间格式
func CustomTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format(global.GVA_CONFIG.Zap.Prefix+"2006/01/02 - 15:04:05.000"))
enc.AppendString(t.Format(global.GVA_CONFIG.Zap.Prefix + "2006/01/02 - 15:04:05.000"))
}
......@@ -5,7 +5,6 @@ import (
"gin-vue-admin/config"
"github.com/go-redis/redis"
oplogging "github.com/op/go-logging"
"github.com/spf13/viper"
"gorm.io/gorm"
)
......@@ -15,6 +14,6 @@ var (
GVA_REDIS *redis.Client
GVA_CONFIG config.Server
GVA_VP *viper.Viper
GVA_LOG *oplogging.Logger
GVA_ZAP *zap.Logger
//GVA_LOG *oplogging.Logger
GVA_LOG *zap.Logger
)
......@@ -23,14 +23,12 @@ require (
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible
github.com/lestrrat-go/strftime v1.0.3 // indirect
github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
github.com/mailru/easyjson v0.7.1 // indirect
github.com/mitchellh/mapstructure v1.2.2 // indirect
github.com/mojocn/base64Captcha v1.3.1
github.com/onsi/ginkgo v1.7.0 // indirect
github.com/onsi/gomega v1.4.3 // indirect
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/qiniu/api.v7/v7 v7.4.1
......
......@@ -3,6 +3,7 @@ package initialize
import (
"gin-vue-admin/global"
"gin-vue-admin/service"
"go.uber.org/zap"
)
func Data() {
......@@ -20,7 +21,7 @@ func Data() {
err = service.InitSysDictionaryDetail()
err = service.InitExaFileUploadAndDownload()
if err != nil {
global.GVA_LOG.Error("initialize data failed", err)
global.GVA_LOG.Error("initialize data failed", zap.Any("err", err))
}
global.GVA_LOG.Debug("initialize data success")
}
......@@ -3,6 +3,7 @@ package initialize
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"go.uber.org/zap"
"os"
)
......@@ -28,7 +29,7 @@ func DBTables() {
model.SysOperationRecord{},
)
if err != nil {
global.GVA_LOG.Error("register table failed", err)
global.GVA_LOG.Error("register table failed", zap.Any("err", err))
os.Exit(0)
}
global.GVA_LOG.Debug("register table success")
......
......@@ -2,6 +2,7 @@ package initialize
import (
"gin-vue-admin/global"
"go.uber.org/zap"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
......@@ -33,7 +34,7 @@ func Mysql() {
}
if db, err := gorm.Open(mysql.New(mysqlConfig), gormConfig); err != nil {
global.GVA_LOG.Error("MySQL启动异常", err)
global.GVA_LOG.Error("MySQL启动异常", zap.Any("err", err))
os.Exit(0)
} else {
global.GVA_DB = db
......
......@@ -3,6 +3,7 @@ package initialize
import (
"gin-vue-admin/global"
"github.com/go-redis/redis"
"go.uber.org/zap"
)
func Redis() {
......@@ -14,9 +15,9 @@ func Redis() {
})
pong, err := client.Ping().Result()
if err != nil {
global.GVA_LOG.Error(err)
global.GVA_LOG.Error("redis connect ping failed, err:", zap.Any("err", err))
} else {
global.GVA_LOG.Info("redis connect ping response:", pong)
global.GVA_LOG.Info("redis connect ping response:", zap.String("pong",pong))
global.GVA_REDIS = client
}
}
......@@ -30,7 +30,7 @@ func GinRecovery(stack bool) gin.HandlerFunc {
httpRequest, _ := httputil.DumpRequest(c.Request, false)
if brokenPipe {
global.GVA_ZAP.Error(c.Request.URL.Path,
global.GVA_LOG.Error(c.Request.URL.Path,
zap.Any("error", err),
zap.String("request", string(httpRequest)),
)
......@@ -41,13 +41,13 @@ func GinRecovery(stack bool) gin.HandlerFunc {
}
if stack {
global.GVA_ZAP.Error("[Recovery from panic]",
global.GVA_LOG.Error("[Recovery from panic]",
zap.Any("error", err),
zap.String("request", string(httpRequest)),
zap.String("stack", string(debug.Stack())),
)
} else {
global.GVA_ZAP.Error("[Recovery from panic]",
global.GVA_LOG.Error("[Recovery from panic]",
zap.Any("error", err),
zap.String("request", string(httpRequest)),
)
......
......@@ -9,6 +9,7 @@ import (
"gin-vue-admin/service"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"strconv"
"time"
)
......@@ -57,7 +58,7 @@ func JWTAuth() gin.HandlerFunc {
if global.GVA_CONFIG.System.UseMultipoint {
err,RedisJwtToken := service.GetRedisJWT(newClaims.Username)
if err!=nil {
global.GVA_LOG.Error(err)
global.GVA_LOG.Error("get redis jwt failed", zap.Any("err", err))
}else{
service.JsonInBlacklist(model.JwtBlacklist{Jwt: RedisJwtToken})
//当之前的取成功时才进行拉黑操作
......
......@@ -6,6 +6,7 @@ import (
"gin-vue-admin/model"
"gin-vue-admin/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"io/ioutil"
"net/http"
"strconv"
......@@ -19,7 +20,7 @@ func OperationRecord() gin.HandlerFunc {
var err error
body, err = ioutil.ReadAll(c.Request.Body)
if err != nil {
global.GVA_LOG.Error("read body from request error:", err)
global.GVA_LOG.Error("read body from request error:", zap.Any("err", err))
} else {
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
}
......@@ -52,7 +53,7 @@ func OperationRecord() gin.HandlerFunc {
record.Resp = writer.body.String()
if err := service.CreateSysOperationRecord(record); err != nil {
global.GVA_LOG.Error("create operation record error:", err)
global.GVA_LOG.Error("create operation record error:", zap.Any("err", err))
}
}
}
......
......@@ -2,6 +2,7 @@ package utils
import (
"gin-vue-admin/global"
"go.uber.org/zap"
"os"
)
......@@ -35,10 +36,10 @@ func CreateDir(dirs ...string) (err error) {
return err
}
if !exist {
global.GVA_LOG.Debug("create directory ", v)
global.GVA_LOG.Debug("create directory" + v)
err = os.MkdirAll(v, os.ModePerm)
if err != nil {
global.GVA_LOG.Error("create directory", v, " error:", err)
global.GVA_LOG.Error("create directory"+ v, zap.Any(" error:", err))
}
}
}
......
......@@ -2,6 +2,7 @@ package utils
import (
"gin-vue-admin/global"
"go.uber.org/zap"
"io"
"mime/multipart"
"os"
......@@ -23,7 +24,7 @@ func UploadAvatarLocal(file *multipart.FileHeader) (err error, localPath string,
// 尝试创建此路径
err = os.MkdirAll(savePath, os.ModePerm)
if err != nil{
global.GVA_LOG.Error("upload local file fail:", err)
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
// 拼接路径和文件名
......@@ -32,21 +33,21 @@ func UploadAvatarLocal(file *multipart.FileHeader) (err error, localPath string,
// 打开文件 defer 关闭
src, err := file.Open()
if err != nil {
global.GVA_LOG.Error("upload local file fail:", err)
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
defer src.Close()
// 创建文件 defer 关闭
out, err := os.Create(dst)
if err != nil {
global.GVA_LOG.Error("upload local file fail:", err)
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
defer out.Close()
// 传输(拷贝)文件
_, err = io.Copy(out, src)
if err != nil {
global.GVA_LOG.Error("upload local file fail:", err)
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
return nil, dst, lastName
......
......@@ -2,6 +2,7 @@ package utils
import (
"gin-vue-admin/global"
"go.uber.org/zap"
"io"
"mime/multipart"
"os"
......@@ -22,8 +23,8 @@ func UploadFileLocal(file *multipart.FileHeader) (err error, localPath string, k
savePath := global.GVA_CONFIG.LocalUpload.FilePath
// 尝试创建此路径
err = os.MkdirAll(savePath, os.ModePerm)
if err != nil{
global.GVA_LOG.Error("upload local file fail:", err)
if err != nil {
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
// 拼接路径和文件名
......@@ -32,21 +33,21 @@ func UploadFileLocal(file *multipart.FileHeader) (err error, localPath string, k
// 打开文件 defer 关闭
src, err := file.Open()
if err != nil {
global.GVA_LOG.Error("upload local file fail:", err)
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
defer src.Close()
// 创建文件 defer 关闭
out, err := os.Create(dst)
if err != nil {
global.GVA_LOG.Error("upload local file fail:", err)
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
defer out.Close()
// 传输(拷贝)文件
_, err = io.Copy(out, src)
if err != nil {
global.GVA_LOG.Error("upload local file fail:", err)
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
return nil, dst, lastName
......
......@@ -6,6 +6,7 @@ import (
"gin-vue-admin/global"
"github.com/qiniu/api.v7/v7/auth/qbox"
"github.com/qiniu/api.v7/v7/storage"
"go.uber.org/zap"
"mime/multipart"
"time"
)
......@@ -40,7 +41,7 @@ func UploadRemote(file *multipart.FileHeader) (err error, path string, key strin
fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename) // 文件名格式 自己可以改 建议保证唯一性
err = formUploader.Put(context.Background(), &ret, upToken, fileKey, f, dataLen, &putExtra)
if err != nil {
global.GVA_LOG.Error("upload file fail:", err)
global.GVA_LOG.Error("upload file fail:", zap.Any("err", err))
return err, "", ""
}
return err, global.GVA_CONFIG.Qiniu.ImgPath + "/" + ret.Key, ret.Key
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册