update: 去掉 github.com/lestrrat-go/file-rotatelogs 库的依赖, 实现zap.String("business", "xx")自定义业务日志数据路径, 输出文件路径为./global.GVA_CONFIG.Zap.Director/2006-01-02/xx/level(debug, info, warn, error, dpanic, panic, fatal).log (#1551)
This commit is contained in:
97
server/core/internal/cutter.go
Normal file
97
server/core/internal/cutter.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Cutter struct {
|
||||
level string // 日志级别(debug, info, warn, error, dpanic, panic, fatal)
|
||||
format string // 时间格式(2006-01-02)
|
||||
Director string // 日志文件夹
|
||||
file *os.File // 文件句柄
|
||||
mutex *sync.RWMutex // 读写锁
|
||||
}
|
||||
|
||||
type CutterOption func(*Cutter)
|
||||
|
||||
// WithCutterFormat 设置时间格式
|
||||
func WithCutterFormat(format string) CutterOption {
|
||||
return func(c *Cutter) {
|
||||
c.format = format
|
||||
}
|
||||
}
|
||||
|
||||
func NewCutter(director string, level string, options ...CutterOption) *Cutter {
|
||||
rotate := &Cutter{
|
||||
level: level,
|
||||
Director: director,
|
||||
mutex: new(sync.RWMutex),
|
||||
}
|
||||
for i := 0; i < len(options); i++ {
|
||||
options[i](rotate)
|
||||
}
|
||||
return rotate
|
||||
}
|
||||
|
||||
// Write satisfies the io.Writer interface. It writes to the
|
||||
// appropriate file handle that is currently being used.
|
||||
// If we have reached rotation time, the target file gets
|
||||
// automatically rotated, and also purged if necessary.
|
||||
func (c *Cutter) Write(bytes []byte) (n int, err error) {
|
||||
c.mutex.Lock()
|
||||
defer func() {
|
||||
if c.file != nil {
|
||||
_ = c.file.Close()
|
||||
c.file = nil
|
||||
}
|
||||
c.mutex.Unlock()
|
||||
}()
|
||||
var business string
|
||||
if strings.Contains(string(bytes), "business") {
|
||||
var compile *regexp.Regexp
|
||||
compile, err = regexp.Compile(`{"business": "([^,]+)"}`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if compile.Match(bytes) {
|
||||
finds := compile.FindSubmatch(bytes)
|
||||
business = string(finds[len(finds)-1])
|
||||
bytes = compile.ReplaceAll(bytes, []byte(""))
|
||||
}
|
||||
compile, err = regexp.Compile(`"business": "([^,]+)"`)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if compile.Match(bytes) {
|
||||
finds := compile.FindSubmatch(bytes)
|
||||
business = string(finds[len(finds)-1])
|
||||
bytes = compile.ReplaceAll(bytes, []byte(""))
|
||||
}
|
||||
}
|
||||
format := time.Now().Format(c.format)
|
||||
formats := make([]string, 0, 4)
|
||||
formats = append(formats, c.Director)
|
||||
if format != "" {
|
||||
formats = append(formats, format)
|
||||
}
|
||||
if business != "" {
|
||||
formats = append(formats, business)
|
||||
}
|
||||
formats = append(formats, c.level+".log")
|
||||
filename := filepath.Join(formats...)
|
||||
dirname := filepath.Dir(filename)
|
||||
err = os.MkdirAll(dirname, 0755)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c.file, err = os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return c.file.Write(bytes)
|
||||
}
|
@@ -2,11 +2,8 @@ package internal
|
||||
|
||||
import (
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
var FileRotatelogs = new(fileRotatelogs)
|
||||
@@ -15,15 +12,10 @@ type fileRotatelogs struct{}
|
||||
|
||||
// GetWriteSyncer 获取 zapcore.WriteSyncer
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (r *fileRotatelogs) GetWriteSyncer(level string) (zapcore.WriteSyncer, error) {
|
||||
fileWriter, err := rotatelogs.New(
|
||||
path.Join(global.GVA_CONFIG.Zap.Director, "%Y-%m-%d", level+".log"),
|
||||
rotatelogs.WithClock(rotatelogs.Local),
|
||||
rotatelogs.WithMaxAge(time.Duration(global.GVA_CONFIG.Zap.MaxAge)*24*time.Hour), // 日志留存时间
|
||||
rotatelogs.WithRotationTime(time.Hour*24),
|
||||
)
|
||||
func (r *fileRotatelogs) GetWriteSyncer(level string) zapcore.WriteSyncer {
|
||||
fileWriter := NewCutter(global.GVA_CONFIG.Zap.Director, level, WithCutterFormat("2006-01-02"))
|
||||
if global.GVA_CONFIG.Zap.LogInConsole {
|
||||
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter)), err
|
||||
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter))
|
||||
}
|
||||
return zapcore.AddSync(fileWriter), err
|
||||
return zapcore.AddSync(fileWriter)
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
@@ -42,12 +41,7 @@ func (z *_zap) GetEncoderConfig() zapcore.EncoderConfig {
|
||||
// GetEncoderCore 获取Encoder的 zapcore.Core
|
||||
// Author [SliverHorn](https://github.com/SliverHorn)
|
||||
func (z *_zap) GetEncoderCore(l zapcore.Level, level zap.LevelEnablerFunc) zapcore.Core {
|
||||
writer, err := FileRotatelogs.GetWriteSyncer(l.String()) // 使用file-rotatelogs进行日志分割
|
||||
if err != nil {
|
||||
fmt.Printf("Get Write Syncer Failed err:%v", err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
writer := FileRotatelogs.GetWriteSyncer(l.String()) // 日志分割
|
||||
return zapcore.NewCore(z.GetEncoder(), writer, level)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user