/
zap.go
131 lines (116 loc) · 4.06 KB
/
zap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* @Date: 2022-04-30 10:34:56
* @LastEditTime: 2022-04-30 16:03:18
* @FilePath: \go-frame\internal\components\logs\init.go
*/
package logs
import (
"log"
"os"
"path/filepath"
"github.com/hyetpang/go-frame/pkgs/common"
"github.com/spf13/viper"
"go.uber.org/fx"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
func New(lc fx.Lifecycle) *zap.Logger {
conf := new(config)
err := viper.UnmarshalKey("zap_log", &conf)
if err != nil {
log.Fatal("zap_log配置Unmarshal到对象出错", zap.Error(err))
}
common.MustValidate(conf)
if len(conf.Path) < 1 {
currentPath, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
log.Fatalf("获取当前文件路径出错:%s", err.Error())
}
conf.Path = filepath.Join(currentPath, "logs")
}
debugFile, errFile := getLogFilePath(conf.Path)
hook := &lumberjack.Logger{
Filename: debugFile, // 日志文件路径
MaxSize: logMaxSize, // 最大日志大小(Mb级别)
MaxBackups: logMaxBackups, // 最多保留30个备份
MaxAge: logMaxAge, // days
Compress: true, // 是否压缩 disabled by default
LocalTime: true,
}
minLevel := zapcore.Level(conf.Level)
highPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
result := lvl >= minLevel && lvl >= zapcore.ErrorLevel
return result
})
lowPriority := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
result := lvl >= minLevel && lvl < zapcore.ErrorLevel
return result
})
// 错误日志单独写一份文件
hook_err := &lumberjack.Logger{
Filename: errFile, // 日志文件路径
MaxSize: logMaxSize, // 最大日志大小(Mb级别)
MaxBackups: logMaxBackups, // 最多保留30个备份
MaxAge: logMaxAge, // days
Compress: true, // 是否压缩 disabled by default
LocalTime: true,
}
fileError := zapcore.AddSync(hook_err)
fileDebugging := zapcore.AddSync(hook)
fileErrors := zapcore.AddSync(hook)
consoleDebugging := zapcore.Lock(os.Stdout)
consoleErrors := zapcore.Lock(os.Stderr)
fileCfg := zap.NewProductionEncoderConfig()
consoleCfg := zap.NewProductionEncoderConfig()
fileCfg.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000000")
fileEncoder := zapcore.NewJSONEncoder(fileCfg)
consoleCfg.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000000")
consoleEncoder := zapcore.NewConsoleEncoder(consoleCfg)
if common.Dev {
fileCfg = zap.NewDevelopmentEncoderConfig()
consoleCfg = zap.NewDevelopmentEncoderConfig()
consoleCfg.EncodeLevel = zapcore.CapitalColorLevelEncoder
}
core := zapcore.NewTee(
zapcore.NewCore(consoleEncoder, consoleErrors, highPriority),
zapcore.NewCore(fileEncoder, fileErrors, highPriority),
zapcore.NewCore(fileEncoder, fileError, highPriority),
zapcore.NewCore(consoleEncoder, consoleDebugging, lowPriority),
zapcore.NewCore(fileEncoder, fileDebugging, lowPriority),
)
logger := zap.New(core, zap.AddStacktrace(zap.WarnLevel))
// logger和下面return的zap.Logger依赖唯一不同是zap.AddCallerSkip(1),下面return是作为依赖给各种第三方库使用的
zap.ReplaceGlobals(logger.WithOptions(zap.AddCallerSkip(1)))
lc.Append(fx.StopHook(func() {
_ = logger.Sync() // 日志同步
}))
return logger
}
// func customTimeEncoder(time time.Time, encoder zapcore.PrimitiveArrayEncoder) {
// encoder.AppendString(time.Format("2006-01-02 15:04:05.000000"))
// }
// 获取默认的日志文件位置
func getLogFilePath(currentPath string) (string, string) {
err := makeDir(currentPath)
common.Panic(err)
debugDir := filepath.Join(currentPath, "debug")
err = makeDir(debugDir)
common.Panic(err)
debugFile := filepath.Join(debugDir, filepath.Base(os.Args[0])+".log")
errDir := filepath.Join(currentPath, "error")
err = makeDir(errDir)
common.Panic(err)
errFile := filepath.Join(errDir, filepath.Base(os.Args[0])+".log")
return debugFile, errFile
}
// 创建不存在的目录
func makeDir(path string) error {
_, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return os.Mkdir(path, os.ModePerm)
}
}
return nil
}